「服務端渲染」吊打「客戶端渲染」的那些事(The Benefits of Server Side Rendering Over Client Side Rendering)

The Benefits of Server Side Rendering Over Client Side Rendering

(先交代一下背景),咱們walmart(沃爾瑪)主站的(大)多數頁面,使用的是服務端渲染(如下用簡稱SSR代替),只有極個別頁面使用的是客戶端渲染。html

咱們之因此使用服務端渲染,正是基於如下兩個緣由:react

  • 在用戶購物的過程當中,可以讓用戶享受到頁面性能(的)提高所帶來的用戶體驗web

  • 符合(consistent)咱們對頁面SEO性能優化的要求chrome

正是由於SSR擁有這些優勢,這才讓咱們下定決心(對頁面)使用服務端渲染。(不過,說實話),當咱們(真的)把技術棧切到React和Nodejs的時候,(吃驚的發現),SSR性能的優化工做(其實)也花了咱們不少時間和精力。(爲啥呢)?這是由於SSR性能優化的一部分工做是針對首屏渲染的優化,(忘記說了),首屏渲染(above-the-fold render)也是咱們衡量性能的重要指標之一。(順道安利一下)咱們本身的開源框架Electrode framework,該框架內置了多個有助於SSR性能提高的獨立模塊,(若是沒記錯的話),我以前就寫過有關於使用這些模塊所帶來性能提高的介紹瀏覽器

Eletrode框架(旨在解決SSR性能優化問題)一經發布,不久我就收到了許多有關於使用SSR(究竟)能帶來(哪些)好處的提問以及相關的評論。大家如今看的這篇文章,主要講的是使用SSR(究竟)能帶來(哪些)好處,至於SEO優化(究竟)能帶來(哪些)好處等話題,(我以爲)Andrew FarmerPatrick Hund他倆的文章已經講得很全面啦,(我這裏將再也不贅述)。性能優化

理論上的性能優勢

接下來,我將會用最直觀(super simple)的時序圖(timeline diagram)來闡述SSR以及CSR之間的區別。服務器

SSR

CSR

從圖中能夠看出,(這兩種渲染方式的)區別主要在於出現首屏渲染的時機。對於SSR來講,服務器返回的是(結構相對完整的)HTML文件,(經過解析HTML文件),瀏覽器就能渲染出頁面。而對CSR來講,瀏覽器拿到的只是包含JavaScript代碼的HTML文件,(換句話,在瀏覽器渲開始渲染出頁面以前,須要動態建立HTML標籤)。這也就意味着,SSR可讓瀏覽器在邊下載JavaScript文件的同時邊渲染HTML頁面,換句話說,瀏覽器不再須要等到全部的JavaScript文件下載並執行完以後纔去渲染頁面啦。(譯者注:上述方式屬於增量式構建),從SSR以及CSR的時序圖裏,咱們能夠發現,這兩種渲染方式仍是有蠻多共同點的:網絡

  • 都須要下載React的
  • 都須要經歷虛擬DOM構建過程
  • 都須要(給頁面元素)綁定事件來加強頁面的可交互性

不過對於使用SSR方式渲染出的HTML頁面來講,用戶是能夠在這些操做(指的是下載React、構建虛擬DOM、綁定事件)完成以前就能看到頁面。再反觀使用CSR方式渲染出的HTML頁面,你必須等到上面的這些操做(指的是下載React、構建虛擬DOM、綁定事件)都完成,virtual-dom轉換成(瀏覽器)頁面上的真實dom以後,用戶才能看到頁面。app

使用SSR渲染的另外一大優點(Another Bonus):(熟悉瀏覽器渲染機制的人都應該知道),使用CSR渲染的話,頁面很容易白屏。相反,若是你使用SSR渲染的話,白屏就不(那麼)容易出現啦。儘管你們都知道,使用CSR(在很大程度上)就意味着頁面白屏,不過大多數人仍是會使用下面的這種方式來規避(白屏)風險(在服務器返回全部數據以前,給頁面添加loading圖,而後在全部數據到達以後,把loading圖撤掉)。(譯者注:用磚業術語是醬紫描述的,在數據到達以前,讓頁面開始轉「菊花」,數據到達以後,移除「菊花」圖)框架

前方高能預警(there are a few caveats),請全部(使用SSR方式)的小夥伴提早作好戰鬥準備:

  • 雖然說使用SSR方式渲染,不但可讓瀏覽器更早的渲染出HTML頁面,並且還能讓用戶更快的看到HTML頁面。不過美中不足的是,在React沒有執行以前,這些頁面是不存在交互這一說的,甚至是包括像用戶(快速)點擊按鈕等相似(這樣簡單)的交互都不能完成。
  • (熟悉HTTP協議的人都應該知道),在使用SSR方式渲染HTML頁面的過程當中,瀏覽器獲取第一個字節的時間(Time To First Byte)要長於用CSR渲染HTML頁面所獲取的時間,(爲啥呢)?這是由於在你使用SSR方式渲染頁面的過程當中,你服務器須要花更多的時間來渲染出(瀏覽器所須要的)HTML結構,(最後纔將渲染好的HTML結構做爲響應返回),而不像CSR那樣,服務器只須要返回字節相對較少的Json數據(relatively empty respons)。

  • (經過對比SSR、CSR這兩種渲染方式,你會發現),在使用SSR方式渲染HTML頁面的過程當中,服務器的吞吐量會明顯少於用CSR渲染HTML頁面時服務器的吞吐量。尤爲是當你在服務端使用react的時候,(你會發現,是否使用react的服務端渲染特性,服務器吞吐量每每也是咱們考慮的因素),這是由於react對服務器吞吐量的影響太大啦(the throughput impact is extremely large)。ReactDOMServer.renderToString具備如下特色:

(換句話說),在ReactDOMServer.renderToString沒有執行完以前,服務器是(絕)不可能處理其它請求的。(啥?你說我講的太抽象啦,徹底聽不懂),(那好吧,不妨)讓咱們作個假設(Let’s say ),在使用SSR渲染HTML頁面的過程當中,執行ReactDOMServer.renderToString就花了500ms,這意味你如今每秒最多隻能處理兩個請求。(若是有同窗對這方面感興趣的話,能夠重點關注一下)

真實案例(Real Use Case)

(接下來,我將會帶着你們來親身感覺一下,咱們walmart主站是如何在生產環境實踐SSR以及CSR的),如下是咱們針對SSR、CSR這兩種渲染方式所作的一些對比。

CSR vs SSR

爲了(更好的)對比SSR、CSR這兩種渲染方式,咱們分別拿出了(walmart主站的)home、category以及search三個模塊來進行對比。(忘記說了),當前的這張圖片以及接下來的圖片都是咱們在頁面進行渲染的過程當中,使用chrome(瀏覽器自帶的Screenshots工具)所抓取的快照。(譯者注:此處應該有掌聲),經過查看圖片,你會發現使用SSR的話,HTML頁面渲染更快,相反使用CSR的話,HTML頁面在加載過程當中會出現白屏。雖然說絕大多數應用仍是能夠經過(顯式地使用)loading圖的方式來解決頁面白屏,不過咱們的作法是醬紫的:在常規狀況下,咱們會使用SSR方式,(不過一旦 生產環境出現緊急狀況),須要強制切到CSR的狀況下,頁面仍是會出現白屏。請注意,雖然說上面的圖片只是(對HTML頁面渲染狀況的)一次快照,(不過你們應該不用擔憂),由於咱們天天都會按期在不一樣的時間點、不一樣的生產環境來跑咱們的機器,因此說咱們獲得的個體樣本數據很是全(vary-but),(全到啥子程度呢)?你均可以從這些數據中看出app接下來的性能走勢啦。

SSR & CSR

咱們能夠看到,(在分別使用SSR、CSR這兩種渲染方式的狀況下),服務器會針對home、category以及search頁面返回相對應的響應頭數據。不過我會綠色bar忽略掉,這是由於在網絡拓撲圖(network graph)當中,(咱們發現),相比綠色bar位置以外的數據來講,綠色bar所反映出的數據更具備相對性(more relative)。(在這些數據當中),我比較關注的是文件大小以及TTFB。既然服務器會針對不一樣的頁面返回相對應的HTML,(那麼你就有可能注意到),使用SSR方式渲染出的HTML體積老是比用CSR方式大。另一點就是關於服務器的響應速度,(通過咱們測試發現),使用CSR方式,可以讓服務器更快地響應頁面請求(因爲其它緣由,在請求home page頁面的過程當中,服務器響應的速度反而變慢啦)。

我不能徹底保證上述結論的正確性,這是由於上述結論摻雜了不少不穩定的因素好比網絡是否延遲,服務器是否正常,訪問者的地理位置以及其它因素。因此但願你們不要把上述結論理解爲真理(scientific fact),更多的是把它理解爲對SSR以及CSR這兩種渲染方式趨勢的一種解讀。

Electrode

當咱們分別對CSR、SSR這兩種渲染方式進行A/B測試時,發現(咱們看到的)結果和以前預期的同樣,另外咱們的統計數據顯示,渲染的越早,用戶的參與度就會越高。

正是基於以上緣由,咱們才決定把開源electrode平臺的關注點放在SSR上。electrode默認開啓SSR,另外咱們有一些模塊是圍繞優化SSR展開的。在另一篇文章中,我將會爲你們展現,如何使用這兩個模塊,將RenderToString()的時間縮減至30%

很是感謝MayakumarCaoyang幫我review並潤色這篇文章。

相關文章
相關標籤/搜索