服務(wù)器端渲染主要有兩個(gè)優(yōu)勢(shì),一是加快首屏渲染時(shí)間,二是有利于SEO。本文將通過(guò)圖文簡(jiǎn)要分析一下服務(wù)器渲染如何減少首屏渲染時(shí)間。
我們來(lái)看看服務(wù)器端與客戶(hù)端渲染的流程圖:



圖一為客戶(hù)端渲染流程圖,圖二,三為服務(wù)器端渲染流程圖。
兩個(gè)渲染圖都可以分為兩個(gè)階段:
一:客戶(hù)端發(fā)送請(qǐng)求,服務(wù)器端返回html文件。
二:客戶(hù)端請(qǐng)求js文件,下載完成后本地建立react實(shí)例。
盡管服務(wù)器渲染第一階段的流程圖很長(zhǎng),但是因?yàn)榉?wù)器渲染速度很快,因此實(shí)際耗時(shí)與客戶(hù)端渲染幾乎相同。
第一階段結(jié)束時(shí),服務(wù)器端返回渲染結(jié)果,用戶(hù)即可看到首屏。而對(duì)于客戶(hù)端渲染,需要等待一次腳本下載時(shí)間,以及在客戶(hù)端的渲染時(shí)間。由于客戶(hù)端的硬件以及網(wǎng)絡(luò)條件的差異,這兩段時(shí)間開(kāi)銷(xiāo)可能十分顯著。
客戶(hù)渲染與服務(wù)器渲染第二階段基本一致。所不同的是,服務(wù)器渲染流程中,在客戶(hù)端生成vdom后,并不會(huì)重新渲染,而是比較現(xiàn)有dom的checksum來(lái)決定是否重新渲染。
實(shí)戰(zhàn)中的服務(wù)器端渲染需要配置很多問(wèn)題,比如說(shuō):
- 如何保持前后端數(shù)據(jù)一致
- 如何在后端進(jìn)行路由,且和前端共享路由代碼
- 服務(wù)器端如何打包靜態(tài)資源
前后端數(shù)據(jù)一致
我們假設(shè)使用redux作為store。在服務(wù)器渲染時(shí),將store傳入渲染函數(shù),隨后將store作為全局變量插入到返回的html文件中。
在客戶(hù)端文件中,使用該全局變量作為store的初始值。代碼片段如下:
//server side
var root = renderToString(
<Provider store={store}>
<RouterContext {..._renderProps}/>
</Provider>
)
ctx.render('home', {
root,
state: store.getState()
})
//view template
script.
window.REDUX_STATE = !{JSON.stringify(state)}
//client side
const store = configureStore(window.REDUX_STATE);
路由控制
首先將具體的路由提取到單一文件中。
const routes = (
<Route path="/" component={NavBar}>
<IndexRoute component={App} />
<Route path="/Person" component={Person} />
<Route path="/Profile" component={Profile} />
</Route>
)
隨后在客戶(hù)端與服務(wù)器端:
//客戶(hù)端
<Provider store={store}>
<Router history={browserHistory}>
{routes}
</Router>
</Provider>
//服務(wù)器
match({routes, location: ctx.url}, (error, redirectLocation, renderProps) => {
_renderProps = renderProps
});
<Provider store={store}>
<RouterContext {..._renderProps}/>
</Provider>
這里match,RouterContext都是react-router為了服務(wù)器渲染準(zhǔn)備的函數(shù)。
服務(wù)器端如何打包靜態(tài)資源
這個(gè)沒(méi)什么經(jīng)驗(yàn)。
大家可以看看這篇文章http://www.itdecent.cn/p/0ecd727107bb。 我的這篇文章主要是根據(jù)ChikaraChan的文章寫(xiě)的學(xué)習(xí)筆記。
ChikaraChan為服務(wù)器端渲染寫(xiě)了一個(gè)腳手架。除了我剛剛提到的幾個(gè)問(wèn)題,他還考慮開(kāi)發(fā)項(xiàng)目的其他很多問(wèn)題。
參考文章