React服務端渲染(二)

4、如何做到前端路由和後端路由同步;

說到前後端路由同步,有個問題就又拋出來了,什麼是前後端路由同步?爲什麼要前後端路由同步?
讓我們看看react-router中的hashhistorybrowserHistory;
hashHistory:

http://noah.dabanma.com/#/index

browserHistory:

http://noah.dabanma.com/index

這裏我們選擇browserHistory來做前端路由;這樣更容易跟後端路由匹配;
好了,言歸正傳,那麼什麼是前後端路由同步,爲什麼要前後端路由同步?我總結下來就是:

意思是讓前後端路由保持一致或存在某一對應關係,訪問一個地址之後,前端路由和後端路由能夠相對應上,保證渲染的組件一致,保證數據一致。

詳細的說一下:
這裏寫圖片描述

這就是打開一個網頁的路由流程圖。

前後端路由的匹配方法react-router已經給出,match方法。

import React from 'react';
import { match, RouterContext } from 'react-router';

function clientRouter(ctx, next) {
    let _renderProps;
    match({routes:Root(), location:ctx.url}, (err, redirectLocation, renderProps) => {
        _renderProps = renderProps
    })
    if(_renderProps) {
        ctx.render = (props, router) => {
            return stringToHtml(<Provider store={props}><RouterContext {..._renderProps} /></Provider>, props, router);
        }
    }
    next();
}

這是一箇中間件,每次對後端的請求都會走這個中間件,那麼每次都會走match方法來匹配路由,渲染相應的組件。

5、如何拆分js和css,並且在切換頁面的時候加載相對應的js和css;

我用webpack拆分了js和css,將公用的js代碼打包到vendor.js中,然後以頁面爲單位拆分相應的js文件和css文件,根據頁面的路由命名。

這樣做的目的是減輕首屏加載的負擔,頁面只需要加載自己的js和css就可以。切換頁面的時候,再根據路由請求相應的js和css文件即可。

這裏拋出個問題,如何在切換頁面的時候,異步請求響應的js和css文件?

我的思路是:

  • 首先用webpack的pluginassets-webpack-plugin是可以生成一個json文件的,這個json文件中包含打包的情況:
{
    "index": {
        "js": "/js/index-d4727d0c.js",
        "css": "/css/index.css"
    },
    "test": {
        "js": "/js/test-d4727d0c.js"
    },
    "vendor": {
        "js": "/js/vendor-d4727d0c.js"
    }
    ···
}
  • 既然webpack生成了這個json文件,那麼在後端我們可以用fs模塊讀取這個json內容,就可以在後端路由中找到對應的js和css文件,添加到字符串模板中,讓瀏覽器去渲染;

這裏有個點可以優化,每次切換頁面的時候,我們不一定非得去請求後端,請求後端只是爲了SEO,那麼不需要做SEO的頁面我們可以不請求後端,只要加載對應頁面的js和css就好,然後用瀏覽器去解析js文件中的react代碼,做到存前端渲染。這樣提升了速度。

這樣的優化,又拋出兩個問題:

1.前面介紹過,數據是從後端通過字符串模板傳給前端的,那麼純前端渲染就拿不到數據;
2.js和css也是通過後端路由匹配,獲取到相應的js和css,通過字符串模板傳給前端的,純前端渲染也是拿不到對應頁面的js和css文件的;

問題1的解決方案是在react生命週期componentDidMount中發起與在後端路由中同樣的請求,這樣由前端發起請求得到數據。

問題2的解決方案是將webpack生成的json也寫入字符串模板中,可在前端獲取。

6、如何做到服務端渲染和前端渲染隨意切換

服務端渲染和前端渲染的切換,歸根結底在路由上的切換;
前端渲染跳轉的方式:

import {Link, browserHistory} from 'react-router';

browserHistory.push('/index')
或者
<Link to='/index' >跳轉</Link>

後端渲染跳轉方式:

location.href = '/index';
7、做到服務端渲染和前端渲染可隨意切換後,如何保證服務端和前端數據保持同步;

這個問題在上面的優化中提到過,若想做到前後端渲染隨意切換,那麼服務端和前端必須都具有各自獨立獲取數據的能力,並且兩端數據要求統一。
我的思路是:

  • 既然前後端的請求是一樣的,數據會一致,數據接口也相同,那麼將首屏渲染的請求提取出來是一個可行的辦法;
  • 根據webpack生成的json數據,查找組件和後端路由的對應關係,可將組件的請求同步到後端路由中;
  • 這樣,就可以實現跳轉頁面的時候,前後端渲染隨意切換;

到這裏將react服務端渲染基本介紹完了,當然還有很多細節沒有寫進來,如果有更好的方案和意見建議,請在評論區留言。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章