web頁面渲染(二)

客戶端渲染(CSR)

客戶端渲染意味着在瀏覽器中使用Javascript直接渲染頁面。全部的邏輯,數據獲取,模板和路由都在客戶端處理。web

對於移動設備來講,客戶端渲染很可貴到或者保持一種快速的訪問水平。若是它作最少的工做,保持嚴格的Javascript預算,並儘量減小數據請求往返的時間,那麼它能夠接近純服務器端渲染的性能。使用HTTP/2推送或者是<link rel=preload>可使得關鍵腳本和數據得以更快的傳遞,從而使得解析器更快的爲你工做。爲了確保初始化和隨後的導航感受馬上就能完成,像PRPL這樣的模式就比較值得去作。瀏覽器

640?wx_fmt=png

客戶端渲染主要的缺點就是Javascript的數量會隨着應用程序的增加而變得愈來愈多。當有額外的新Javascript類庫,polyfills和第三方代碼的時候,優化工做會尤爲困難。然而這些代碼也會競爭系統的處理能力,所以在頁面內容被渲染完成以前,必需要常常處理一些東西。緩存

對於構建單頁應用的人員來講,對於被大多數頁面共享的核心用戶接口,你能夠嘗試應用Application Shell緩存技術。並與service workers相結合,它能夠明顯提升重複訪問的時候的感知性能。服務器

經過rehydration合併服務器端渲染和客戶端渲染

這種方式一般被稱爲「Universal Rendering」或簡稱爲「SSR」,這種方式試圖經過平滑的方式來平衡客戶端渲染和服務器端渲染。諸如全頁加載或者是從新加載的請求會在服務器端被處理,在服務器端會把其轉爲HTML,而後Javascript和渲染所用到的數據會被一塊兒插入到最後的結果頁面。若是實現的好的話,這種方式會像服務器端渲染那樣產生一個很快的First Contentful Paint。服務器端返回結果之後,會在客戶端會經過一個叫(rehydration)的技術再次渲染。這是一個比較新的解決方案,可是他可能有比較大的性能缺陷。架構

rehydration的SSR的主要的缺點就是它對Time To Interactive有着明顯的缺點,即便它會提升First Paint。它常常看起來是具備欺騙性的加載和交互,由於它實際上在js以及事件處理完成以前,是沒法響應輸入的。在手機端可能會花費數秒鐘纔會讓頁面真正可使用。異步

你可能經歷過如下問題 - 頁面請求加載一段時間之後,你的網頁看起來已經加載好了,可是點擊之後什麼都不會作,你可能很快就會變得崩潰...「如今到底發生什麼事情了?爲何我不能滾動頁面」。函數

一個Rehydration的問題:一個應用程序要構建兩次

因爲JS的緣由,Rehydration的問題一般要比延遲可用的問題要更糟。爲了使客戶端的Javascript可以精確的「獲取」服務器中止渲染的位置,而沒必要從新渲染服務器已渲染過的HTML,當前的SSR解決方案一般會序列化其UI響應,並把其依賴的數據做爲標籤放進文檔中。HTML文檔的結果包含一個更高級別的重複。工具

640?wx_fmt=png

正如你所看到的,在響應中服務器不只返回一個應用程序UI的描述給瀏覽器,並且還吧相關的數據也一併返回了過來,當啓動客戶端的時候,UI會再次實現渲染一次。其只在bundle.js已經完成加載和解析之後,UI纔會變爲可交互的。性能

在真實世界中經過使用SSR來收集性能指標,其結果一般會比較使人沮喪。緣由歸結於用戶體驗:它很容易使用戶留在一個「難以想象的山谷中」。測試

640?wx_fmt=png

雖然SSR有rehydration的但願。可是是在一個很短的時期內,在更高的可緩存的內容中使用SSR能夠減小TTFB延遲。產生一個和預渲染類似的結果。遞增的,逐步的,部分的rehydration多是將來技術可用性更高的關鍵(Rehydrating incrementally, progressively, or partially may be the key to making this technique more viable in the future)。

流服務器渲染和漸進式Rehydration

服務器端渲染在過去幾年擁有大量的開發者。

流服務器渲染容許你以塊的方式發送HTML,瀏覽器能夠經過接收到的片斷進行漸進式的渲染。因爲內容能夠更快的送達給用戶,因此他能夠帶來更快的First Paint和First Contentful Paint。在React中,流經過renderToNodeStream()被異步傳輸 - 相比於同步渲染方式 - 意味着背壓處理效果會更好。

漸進式rehydration也是值得一看的,在一些React已經對此有了一些相關的探索了。經過這種方法,服務器端渲染的每個部份內容都會隨着時間的推移而啓動,而不是目前通用的方法,經過一次初始化整個應用程序。這能夠幫助咱們減小頁面交互所須要的Javascript的代碼量。由於能夠延緩低優先級客戶端的內容過早的執行,以使得防止阻塞主線程的執行。它還能夠幫助避免最多見的SSR Rehydration陷阱之一,其中服務器呈現的DOM樹被破壞而後當即重建 - 一般是由於初始同步客戶端渲染所需的數據尚未徹底準備好,可能還在等待Promise 解析的完成。

部分Rehydration

部分Rehydration已經被證實是難以實現的。這種方法是漸進式rehydration的一種擴展。其中逐步分析了漸進式的rehydration的每個部分。標記了那些交互性很小,或者沒有交互性的那些。對於每一個幾乎靜態的部分,對應的Javascript會被轉換爲惰性引用或者是裝飾函數中。將其客戶端佔用空間減小到接近爲零.部分Rehydration也會有本身的問題和妥協。它爲緩存帶來了一些有趣的挑戰,而客戶端導航意味着咱們沒法假設應用程序的惰性部分的服務器呈現的HTML將在沒有完整頁面加載的狀況下可用。

Trisomorphic渲染

若是service workers對於你來講是一個選項的話。那麼對於「trisomorphic」渲染來講,你可能也是感興趣的。這是一種能夠將初始/非JS應用在流服務器上的一種技術,而後讓您的服務工做者在安裝後渲染爲HTML以進行導航,這可使緩存的組件和模板保持最新,並啓用SPA樣式導航以在同一會話中呈現新視圖。當您能夠在服務器,客戶端頁面和服務器工做程序之間共享相同的模板和路由代碼時,此方法最有效。

640?wx_fmt=png

SEO注意事項

當在網站上選擇渲染策略時,團隊一般會考慮SEO的影響。服務器端渲染一般被選擇提供一個對於爬蟲「徹底可視」的,更容易爬取的網頁。爬蟲可能會理解Javascript,可是他們在渲染中一般有值得注意的限制。客戶端渲染能夠工做,可是一般沒有額外的測試工做。最近的動態渲染逐漸成爲一個值得考慮的選項,若是你的架構很大部分都是由客戶端Javascript驅動的話。

若是有疑問,移動友好測試工具對於測試您選擇的方法是否符合您的預期很是寶貴。 它顯示了Google抓取工具顯示任何頁面的方式預覽,找到的序列化HTML內容(執行JavaScript後)以及渲染過程當中遇到的任何錯誤。

640?wx_fmt=png

總結

當決定渲染的方法的時候,首先要測量而且理解你的瓶頸是什麼。思考靜態渲染或者是服務器端渲染是否能夠知足你90%的需求。用最少的JS發佈HTML也是極好的,其會獲得一個可交互的用戶體驗。下面是一個方便的信息圖,顯示了服務器-客戶端頻譜。

640?wx_fmt=png

本文翻譯自:

https://developers.google.com...

本文轉載自http://www.lht.ren/article/14/

相關文章
相關標籤/搜索