摘要:與的興起緊密相連。現(xiàn)在情況下,所有發(fā)送到端的請(qǐng)求都會(huì)被直接返回成。這樣對(duì)于做的部門來說也是十分有利的。這個(gè)函數(shù)將會(huì)接受服務(wù)端渲染的代碼并掛載事件處理函數(shù)。用于在渲染的過程中追蹤可能的重定向請(qǐng)求比如需要根據(jù)響應(yīng)重定向。
原文地址:https://medium.freecodecamp.o...
Server-Side Rendering :SSR 是一種前端框架能夠在后端渲染出HTML的能力。那些能夠在客戶端和服務(wù)端完成渲染的應(yīng)用就叫做universal app
為了理解為什么需要SSR,這里我們需要了解下web應(yīng)用在過去十年內(nèi)的發(fā)展史。SSR與SPA(Single Page Application)的興起緊密相連。與傳統(tǒng)的服務(wù)端渲染的app相比,SPA在速度和用戶體驗(yàn)發(fā)面存在很大的優(yōu)勢(shì)。
但是使用SPA有個(gè)問題,通常情況下用戶第一次請(qǐng)求會(huì)返回一個(gè)空html文件和一堆JS和CSS鏈接,渲染html之前會(huì)先把JS和CSS提前下載下來。
這就意味著首次渲染的時(shí)候,用戶必須要等更長的時(shí)間。同時(shí)對(duì)于爬蟲來說,解析到的頁面也是一個(gè)空頁面。
因此SSR的主要思想就是首次在server端渲染應(yīng)用,后續(xù)可以充分利用SPA的優(yōu)勢(shì),在客戶端完成渲染。
SSR + SPA = Universal App
有的文章中也會(huì)把Universal App講成isomorphoic app,實(shí)際上這兩個(gè)是同一個(gè)東西。采用SSR的情況下,首次渲染的時(shí)候,用戶不需要等JS加載完成后在看到渲染完成的頁面,而是在請(qǐng)求返回的時(shí)候就已經(jīng)拿到渲染完成的頁面了。
對(duì)于使用slow 3G的用戶來說,使用SSR會(huì)大大改善用戶體驗(yàn)。用戶將會(huì)直接看到網(wǎng)頁內(nèi)容而不是等待20s+才能看到網(wǎng)頁內(nèi)容。
現(xiàn)在情況下,所有發(fā)送到server端的請(qǐng)求都會(huì)被直接返回成HTML。這樣對(duì)于做SEO的部門來說也是十分有利的。
對(duì)爬蟲來說不會(huì)區(qū)別對(duì)待SPA引用和其他靜態(tài)站點(diǎn),同樣會(huì)為服務(wù)端渲染的內(nèi)容生成索引。
簡而言之,使用SSR有兩點(diǎn)好處:
首次渲染速度更快
生成的HTML內(nèi)容可以被索引到。
一步步來理解SSR下面筆者將通過一個(gè)例子,一步步來實(shí)現(xiàn)一個(gè)完整的SSR案例。首先從React的服務(wù)端渲染API開始,后續(xù)每一步我們都將加入一些新的內(nèi)容。
可以follow 這個(gè)項(xiàng)目倉庫 ,每一步的代碼都會(huì)有一個(gè)tag,讀者可以通過git checkout tags/xxx -b xxx的方式獲取每一步的代碼(xxx為對(duì)應(yīng)的tag名)。
開始介紹SSR之前,我們需要一個(gè)server。這里筆者采用express來渲染React應(yīng)用。
在代碼的第10行,我們用express啟動(dòng)了一個(gè)靜態(tài)服務(wù)器。同時(shí)我們也創(chuàng)建了一個(gè)用于處理非靜態(tài)請(qǐng)求的handle函數(shù)。非靜態(tài)的路由將會(huì)返回HTML代碼。
在代碼的第13~14行,我們用renderToString 函數(shù)把一開始的JSX代碼轉(zhuǎn)換成字符串,這段字符串后續(xù)將被插入到HTML模板中。
PS:我們并沒有直接啟動(dòng)sever.js ,而是通過index.js來啟動(dòng)server.js。在index.js中,我們用babel插件來抹平client和server端的差異,保證client和server都能夠使用es module和jsx。
在SSR中client端的代碼也需要從ReactDOM.render的改成ReactDOM.hydrate。這個(gè)函數(shù)將會(huì)接受服務(wù)端渲染的react代碼并掛載事件處理函數(shù)。
想看到完整的例子,可以check react-ssr tag為basic的代碼。到這兒為止,我們就完成了一個(gè)簡單的服務(wù)端渲染的react app。
React Router到目前為止,我們的應(yīng)用實(shí)際上啥事也沒干。現(xiàn)在我們來往之前的應(yīng)用加入一些路由。先來看看如何處理服務(wù)端部分:
現(xiàn)在Layout組件在client端上將會(huì)渲染出路由組件。對(duì)應(yīng)的我們需要在server端模擬出client的路由實(shí)現(xiàn)。下面我們列出server端代碼的修改部分:
在服務(wù)端的代碼中,我們需要把React Application包裝在StaticRouter 組件中,并提供location參數(shù)。
PS:context用于在渲染React DOM的過程中追蹤可能的重定向請(qǐng)求:比如client需要根據(jù)3XX響應(yīng)重定向。
完整的案例需要checkout tag為router的代碼。
在項(xiàng)目已經(jīng)具備路由能力的情況下,下面我們來集成redux。一些場(chǎng)景下,我們需要使用redux來管理client端的狀態(tài)。但是在服務(wù)端渲染的情況,如何根據(jù)當(dāng)前狀態(tài)來渲染部分DOM是個(gè)問題,因此我們有必要在服務(wù)端初始化redux。
如果應(yīng)用在服務(wù)端dispatch action的情況下,SSR需要記錄下這些操作,并把最終的state和HTML一起返回給client。在client端,會(huì)把服務(wù)端返回的state設(shè)為redux的初始狀態(tài)。
我們先來看看server端的實(shí)現(xiàn):
這段代碼看起來實(shí)現(xiàn)的十分丑陋,但是我們確實(shí)需要把服務(wù)端渲染出來的redux狀態(tài)和HTML代碼一起返回給client。
接著來看看client部分的實(shí)現(xiàn):
這里我們調(diào)用了兩次createStore,一次在server端,一次在client端。但是在client端上需要把server端保存下來的狀態(tài)設(shè)為redux的初始狀態(tài)。
完整的例子可以看當(dāng)前項(xiàng)目的redux tag。
Fetch Data最后一步就是加載數(shù)據(jù)。這是個(gè)比較棘手的問題。我們從一個(gè)返回JSON數(shù)據(jù)的接口開始講起。
在代碼倉庫中,筆者通過開放API獲取了2018第一賽季的Formula的數(shù)據(jù)。我們希望在Home頁面顯示所有的Formula數(shù)據(jù)。
我們可以在所有React app掛載完成、所有元素都已經(jīng)渲染完畢的的情況下調(diào)用API接口來完成需求。如果這樣的話,可能會(huì)存在一些loading畫面,對(duì)于用戶體驗(yàn)并不友好。
考慮到項(xiàng)目中已經(jīng)整合了Redux,我們可以通過Redux來保存數(shù)據(jù)并返回給前端的方式來加載數(shù)據(jù)。
如何在server端調(diào)用API接口、將接口返回?cái)?shù)據(jù)保存在Redux中并讓客戶端根據(jù)相關(guān)數(shù)據(jù)來渲染HTML呢?
那么需要調(diào)用哪些接口呢?
首先我們需要通過一種不同的方式來申明路由。所以我們把路由改成如下所示:
同時(shí)我們也需要在組件上聲明所有的數(shù)據(jù):
PS: fetchData 是一個(gè) Redux thunk action,dispatch fetchData的時(shí)候會(huì)返回一個(gè)promise。
同時(shí)在服務(wù)端,我們也用了一個(gè)react-router中的特殊的函數(shù):matchRoute :
通過這個(gè)方法,當(dāng)服務(wù)端根據(jù)當(dāng)前URL渲染頁面的時(shí)候會(huì)得到需要被mounted 的組件。我們會(huì)收集所有組件需要的數(shù)據(jù),等待所有接口都已經(jīng)返回?cái)?shù)據(jù),并把獲取的數(shù)據(jù)塞到redux中才會(huì)繼續(xù)執(zhí)行服務(wù)渲染。
切換到tag為fetch-data的分支可以看到整個(gè)案例。
從這兒開始,我們就會(huì)開始從各個(gè)維度進(jìn)行比較,并比較出哪些場(chǎng)景適合使用SSR哪些場(chǎng)景不適合使用SSR。比如說對(duì)一個(gè)電商app來說,獲取所有的產(chǎn)品是重中之重,但是價(jià)格以及一些其他的邊欄filter相比之下就顯得不那么重要。
Helmet最后我們來看看SEO。當(dāng)和React打交道的時(shí)候,我們經(jīng)常需要在標(biāo)簽中設(shè)置不同的值。比如:title、meta tags 、keywords 等等。
記住 標(biāo)簽中的內(nèi)容一般不是React App的一部分。
react-helmet就是為了解決修改標(biāo)簽中的內(nèi)容而生的,并對(duì)SSR提供了良好的支持。
你可以在組件樹中的任何地方加入head標(biāo)簽內(nèi)的數(shù)據(jù)。在client端上,react-helmet提供了一種修改React App以外部分的能力。
我們也在SSR中加入這種能力:
現(xiàn)在我們已經(jīng)顯示了一個(gè)具備基礎(chǔ)功能的React服務(wù)端渲染的案例。我們從一個(gè)返回HTML內(nèi)容的express應(yīng)用開始,慢慢加入了路由、狀態(tài)管理以及獲取數(shù)據(jù)的能力。最后我們還處理React App之外的部分。完整的代碼在master分支可以看到。
Conclusion正如本文所示,SSR并不適合一件難事,但是SSR也可以做的很復(fù)雜。如果一步一步來實(shí)現(xiàn)需要會(huì)更容易些。那么項(xiàng)目中是否需要加入SSR呢?具體情況具體分析。如果網(wǎng)站訪問量很大,則建議做SSR。但是如果你的應(yīng)用是類似于工具或者dashboard這種應(yīng)用,則沒必要花費(fèi)較多的精力來實(shí)現(xiàn)SSR。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/99040.html
摘要:解開多云戰(zhàn)略的神秘面紗組織今天需要采取的關(guān)鍵步驟是云行業(yè)正以閃電般的速度發(fā)展,企業(yè)采用多云技術(shù)由于需要更快的數(shù)字化轉(zhuǎn)型而日益成為主流。在多云環(huán)境中,規(guī)模和復(fù)雜性的挑戰(zhàn)只會(huì)增加。當(dāng)一個(gè)組織缺乏對(duì)其多云基礎(chǔ)設(shè)施的可視性時(shí),會(huì)出現(xiàn)許多問題。解開多云戰(zhàn)略的神秘面紗:組織今天需要采取的關(guān)鍵步驟是:云行業(yè)正以閃電般的速度發(fā)展,企業(yè)采用多云技術(shù)由于需要更快的數(shù)字化轉(zhuǎn)型而日益成為主流。Gartner預(yù)測(cè),到...
摘要:在看這篇長輪詢之前可以先看看輪詢技術(shù)沒有長,有助于理解長輪詢屬于輪詢的升級(jí)版,在客戶端和服務(wù)端都進(jìn)行了一些改造,使得消耗更低,速度更快。不間斷的通過查詢服務(wù)端。然后客戶端不間斷繼續(xù)發(fā)起請(qǐng)求數(shù)據(jù)不存在,繼續(xù)循環(huán)。 在看這篇Ajax長輪詢之前可以先看看Ajax輪詢技術(shù)(沒有長),有助于理解: Ajax長輪詢屬于Ajax輪詢的升級(jí)版,在客戶端和服務(wù)端都進(jìn)行了一些改造,使得消耗更低,速度更快。...
摘要:解開多云戰(zhàn)略的神秘面紗組織今天需要采取的關(guān)鍵步驟是云行業(yè)正以閃電般的速度發(fā)展,企業(yè)采用多云技術(shù)由于需要更快的數(shù)字化轉(zhuǎn)型而日益成為主流。在多云環(huán)境中,規(guī)模和復(fù)雜性的挑戰(zhàn)只會(huì)增加。當(dāng)一個(gè)組織缺乏對(duì)其多云基礎(chǔ)設(shè)施的可視性時(shí),會(huì)出現(xiàn)許多問題。解開多云戰(zhàn)略的神秘面紗:組織今天需要采取的關(guān)鍵步驟是:云行業(yè)正以閃電般的速度發(fā)展,企業(yè)采用多云技術(shù)由于需要更快的數(shù)字化轉(zhuǎn)型而日益成為主流。Gartner預(yù)測(cè),到...
摘要:解開多云戰(zhàn)略的神秘面紗組織今天需要采取的關(guān)鍵步驟是云行業(yè)正以閃電般的速度發(fā)展,企業(yè)采用多云技術(shù)由于需要更快的數(shù)字化轉(zhuǎn)型而日益成為主流。在多云環(huán)境中,規(guī)模和復(fù)雜性的挑戰(zhàn)只會(huì)增加。當(dāng)一個(gè)組織缺乏對(duì)其多云基礎(chǔ)設(shè)施的可視性時(shí),會(huì)出現(xiàn)許多問題。解開多云戰(zhàn)略的神秘面紗:組織今天需要采取的關(guān)鍵步驟是:云行業(yè)正以閃電般的速度發(fā)展,企業(yè)采用多云技術(shù)由于需要更快的數(shù)字化轉(zhuǎn)型而日益成為主流。Gartner預(yù)測(cè),到...
閱讀 1225·2021-11-11 16:54
閱讀 1738·2021-10-13 09:40
閱讀 932·2021-10-08 10:05
閱讀 3498·2021-09-22 15:50
閱讀 3701·2021-09-22 15:41
閱讀 1782·2021-09-22 15:08
閱讀 2338·2021-09-07 10:24
閱讀 3570·2019-08-30 12:52