React 下同構(gòu)渲染的優(yōu)化手段
嗨,我是你穩(wěn)定更新、持續(xù)輸出的勾勾。

前面兩篇文章我寫了“手動實現(xiàn)一個自己的 React 服務(wù)端渲染”和“React 下的同構(gòu)渲染”。
今天我會結(jié)合這兩篇文章來聊聊如何優(yōu)化 React 下的同構(gòu)渲染。
主要從下面四點著手。
- 配置文件優(yōu)化
- 啟動指令優(yōu)化
- 打包體積優(yōu)化
- 代碼拆分
# 配置文件合并
不論客戶端還是服務(wù)端,都存在一套自己的配置文件。
webpack.client.js 和 webpack.config.js 在內(nèi)容層面,這里面的內(nèi)容有很多相同之處。
所以我們需要把這些雷同的代碼抽取出來,單獨創(chuàng)建一個基準(zhǔn)文件 webpack.common.js,然后通過一個叫 webpack-merge 的依賴包對它們進行拼裝。
- npm install webpack-merge??
參考網(wǎng)址:https://www.npmjs.com/package/webpack-merge
webpack.common.js 相同代碼抽離:
//webpack.common.js 內(nèi)容const path = require("path")module.exports = {mode:"development",module:{rules:[{test:/\.js$/,exclude:/node_modules/,use:{loader:"babel-loader",options:{presets:["@babel/preset-env","@babel/preset-react"]}}}]}}
webpack.client.js 客戶端打包文件內(nèi)容:
//webpack.client.jsconst path = require("path")const {merge} = require("webpack-merge")const baseConfig = require("./webpack.common")const config= {entry:"./src/client/index.js",output:{path:path.join(__dirname,"public"),filename:"build.js"}}module.exports = merge(baseConfig,config)
webpack.server.js 服務(wù)端打包文件內(nèi)容:
//webpack.server.jsconst path = require("path")const {merge} = require("webpack-merge")const baseConfig = require("./webpack.common")const config = {target:"node",entry:"./src/server/index.js",output:{path:path.join(__dirname,"build"),filename:"bundle.js"}}module.exports = merge(baseConfig,config)
這樣,基本的配置文件合并我們就完成了。
# 啟動指令優(yōu)化
在 package.json 的 scripts 下,我們配置了很多指令:客戶端打包指令,服務(wù)端打包指令,服務(wù)器啟動指令。
現(xiàn)在我們要做一件事,那就是用一個指令把這三個指令全部都運行了。
在這里我們使用一個工具 npm-run-all。
- Npm install npm-run-all??
參考地址:https://www.npmjs.com/package/npm-run-all
//package.json"scripts": {"dev": "npm-run-all --parallel dev:*","dev:server-build": "npx webpack --config webpack.server.js --watch","dev:client-build": "npx webpack --config webpack.client.js --watch","dev:server-run": "nodemon --watch build --exec \"node build/bundle.js\""},
對于這些指令的書寫,可以去地址中查找對應(yīng)的 API。
配置完之后我們只需要一個指令 npm run dev 就可以搞定這三個指令的啟動。
# 排除內(nèi)置模塊打包
在服務(wù)端打包后,可以看到這個打包文件特別大,達到了好幾兆。
這是因為它在打包的過程中把一些 node 的內(nèi)置模塊也一起打包了,所以我們需要把這些 node 內(nèi)置模塊在打包的時候過濾掉。
這里我們需要工具 webpack-node-externals。
- Npm install webpack-node-externals?
參考網(wǎng)址:https://www.npmjs.com/package/webpack-node-externals
在 webpack.server.js 中,我們添加一個屬性。
//webpack.server.jsconst path = require("path")const {merge} = require("webpack-merge")const nodeExternals = require("webpack-node-externals")const baseConfig = require("./webpack.common")const config = {target:"node",entry:"./src/server/index.js",output:{path:path.join(__dirname,"build"),filename:"bundle.js"},externals:[nodeExternals()] //新添加的}module.exports = merge(baseConfig,config)
之后再打包之后就可以看到 server 下打包的文件少了很多。
# 代碼拆分
在寫業(yè)務(wù)的過程中,建議將各個功能模塊獨立分開,這樣便于項目維護和迭代開發(fā)。
所以在 server 目錄下的 index.js 中,路由和渲染需要分離,不能混合在一起。
所以我們需要單獨建立一個 render.js 文件,內(nèi)容如下:
//server/render.jsimport React from "react"import Home from "../common/pages/home";import { renderToString } from "react-dom/server"export default ()=>{const content = renderToString(<Home/>)return `${content}`}
在 server/index.js 下的內(nèi)容:
//server/index.jsimport app from "./http"import render from "./render"app.get("/",(req,res)=>{res.send(render())})
以上就是 React 同構(gòu)渲染下我所列出的部分性能優(yōu)化,希望在開發(fā)過程中能對你有所幫助~
推薦閱讀:
手動實現(xiàn)一個自己的 React 服務(wù)端渲染
前端人因為 Vue3 的 Ref-sugar 提案打起來了!
點點“贊”和“在看”,保護頭發(fā),減少bug。
