天天看點

web頁面渲染(一)術語渲染性能伺服器端渲染靜态渲染伺服器端渲染 vs 靜态渲染

作為開發者,我們經常會面臨一些影響我們整個網站結構的決定,其中web開發者一定要做的核心決定之一就是在應用程式中實作邏輯和渲染的位置。這可能比較難,因為有很多不同的方式來建構一個網站。

我們在這一領域的了解主要來源于在過去的幾年在Chrome工作期間,一直與一些大的網站的交流得來的。從廣義上來講,我們鼓勵開發人員去通過完全rehydration方法進行服務端渲染或者是靜态渲染。

為了更好的了解我們所選擇的技術架構,我們需要對每種方法有一種紮實的了解,并且在談論時要使用一緻的術語。這些方式的不同點有助于我們說明通過性能和渲染之間尋求一個平衡。

術語

渲染

SSR: Server-Side Rendering - 在伺服器端渲染内容的方式。

CSR: Client-Side Rendering - 通常在浏覽器中使用DOM來渲染應用程式的過程。

Rehydration: 在用戶端“啟動”Javascript視圖,使得他們能夠重用伺服器端渲染的html的dom樹和資料。

Prerendering: 在建構時運作用戶端應用程式來使用其初始狀态作為靜态的html頁面。

性能

TTFB: Time to First Byte - 點選一個連結到傳回的第一個位元組資料所用的時間。

FP: First Paint - 首次任何像素對使用者可見的時間(也就是首先将像素繪制到螢幕的時刻)。

FCP: First Contentful Paint - 首次内容對使用者可見的時間(也就是浏覽器将第一個 DOM 渲染到螢幕的時間)。

TTI: Time To Interactive - 頁面變為可互動的時間。

伺服器端渲染

伺服器端渲染會在伺服器上生成整個的HTML頁面,然後整體傳回給浏覽器。由于它在傳回給浏覽器之前就已經處理好了,是以會避免用戶端在資料擷取和模闆化的額外開銷。

伺服器渲染很快就會産生First Paint(FP)和First Contentful Paint(FCP)。在伺服器端運作頁面邏輯和渲染,使之避免了是以而發送大量的Javascript給用戶端。也會有助于我們實作一個快速的Time To Interactive(TTI)。這是可能的,因為在伺服器端渲染的話,你僅僅需要發送文本和連結給浏覽器。這種方式在大範圍的裝置和網絡環境下都會很好的運作,與此同時也會提起你對浏覽器優化的興趣,比如說流文檔解析。

web頁面渲染(一)術語渲染性能伺服器端渲染靜态渲染伺服器端渲染 vs 靜态渲染

通過伺服器端渲染,使用者不太可能等待CPU綁定的javascript處理完畢之後才能去使用您的站點。即使是第三方js不可避免。使用伺服器端渲染也會減少你的js開銷,會給您處理其他事情留有更多的“預算”。然而,這種方式有一個主要的缺點:在伺服器端生成頁面會減慢你的Time To First Byte(TTFB)。

伺服器端渲染對于你的應用程式是否夠用,很大一部分依賴于你個人的建構經驗。在伺服器端渲染和用戶端渲染哪一個更好這個争論曾經持續了很長時間。但是要記住很重要的一點,你可以在一些頁面中使用伺服器端渲染,而不是全部都用。一些網站已經成功使用了混合渲染技術,Netflix在伺服器端渲染,呈現其相對于靜态的頁面,同時為互動繁重的頁面預取js,給這些較重的用戶端頁面提供一個更快的加載機會。

許多現代浏覽器,類庫和架構使得在用戶端和伺服器端渲染同一個應用程式成為可能。這些技術可以被用于伺服器端渲染,然而,重要的是注意在用戶端和伺服器端渲染的架構都有他們不同的解決方案,具有非常不同的性能特征和權衡。React使用者可以使用renderToString()或者是在其之上的解決方案來實作伺服器端渲染,比如說Next.js。Vue使用者可以查閱Vue的server rendering guide或者是Nuxt。Angular有Universal。最流行的解決方案會采用某些形式的hydration。在選擇一個工具之前要注意使用的方法。

靜态渲染

靜态渲染在建構時發生,會提供一個很快的First Paint,First Contentful Paint, Time To Interactive - 假設用戶端js是有限的。跟伺服器端渲染差別之一是它會設法實作一個始終如一的快速的Time To First Byte,因為HTML頁面不必動态生成。通常來說,靜态渲染意味着會提前對每一個URL生成一個單獨的HTML檔案。由于預先生成了HTML的響應,是以靜态渲染可以部署在多個CDN來用于邊緣緩存。

web頁面渲染(一)術語渲染性能伺服器端渲染靜态渲染伺服器端渲染 vs 靜态渲染

靜态渲染的解決方案多種多樣,像Gatsby這樣的工具,開發者會感覺他們的應用程式是動态渲染的,而不是作為建構時生成的。而像Jekly和Metalsmith則會擁抱他們的靜态生态系統,提供更多模闆驅動的方法。

靜态渲染的缺點之一就是要為每一個可能的URL單獨生成一個HTML檔案,當你不能提前預知這些URL都有什麼,或者網站有非常多的唯一頁面的時候,這或許是一個挑戰,又或者是不可能實作的。

React使用者可能很熟悉Gatsby,Next.js,static export或者是Navi - 他們都使得作者使用元件變得很友善。然而,重要的是了解靜态渲染和預渲染的不同點:靜态渲染頁面是可互動的,不需要執行太多的用戶端的js,而預渲染則會提升單頁應用的First Paint或者是First Contentful Paint,為了讓頁面變為真正的可互動其一定要在用戶端啟動。

如果你不确定給定的解決方案是靜态渲染,還是預渲染,嘗試下如下測試:禁用Javascript,加載已經建立好的頁面。對于靜态渲染頁面,如果不啟用Javascript,大部分功能依然存在。而對于預渲染頁面,可能依然有一些基本的功能可以使用,比如說超連結,但是大部分頁面将會是惰性的。

另一個有用的測試是使用Chrome DevTool降低你的網絡帶寬,觀察頁面變為可互動之前Javascript已經下載下傳的數量。預渲染通常需要更多的Javascript來使頁面變的可互動,并且Javascript要比靜态渲染使用的漸進增強方法要更複雜。

伺服器端渲染 vs 靜态渲染

伺服器端渲染并不是靈丹妙藥 - 它的動态特性會帶來明顯的計算性能開銷。許多伺服器端渲染解決方案都不會提早重新整理,可能會導緻延遲TTFB或者是發送的資料量加倍。在React中,renderToString()可能是很慢的,因為它是同步并且是單線程的。要使得伺服器渲染“正确”可能會涉及查找或者建構一個元件緩存的解決方案,管理記憶體消耗,等等。你通常會多次處理/重新建構相同的應用程式 - 一次在用戶端,一次在伺服器端。僅僅是因為伺服器端渲染可以使某些東西更快顯示,但并不是突然意味着會減少你的工作量。

伺服器端渲染可以按需要為每個URL生成對應的HTML,但是它卻慢于靜态渲染的内容。如果你可以進行一些額外的工作,那麼伺服器端渲染 + HTML緩存可以極大的減少伺服器渲染的時間。伺服器端渲染的優點是有能力擷取更多“實時”的資料并且傳回比靜态渲染更加完整的結果集,個性化的頁面是伺服器渲染的一個具體的事例,不過這種對于靜态渲染來說,就不太适合了。

在建構PWA的時候,伺服器端渲染也可以提出一些有有趣的決策。是以是全頁server worker更好,還是用伺服器渲染僅僅渲染單獨的内容片段更好呢?

本文翻譯自:

https://developers.google.com/web/updates/2019/02/rendering-on-the-web

本文轉載自

http://www.lht.ren/article/13

繼續閱讀