React 下同构渲染的优化手段
嗨,我是你稳定更新、持续输出的勾勾。
前面两篇文章我写了“”和“”。
今天我会结合这两篇文章来聊聊如何优化 React 下的同构渲染。
主要从下面四点着手。
- 配置文件优化
- 启动指令优化
- 打包体积优化
- 代码拆分
# 配置文件合并
不论客户端还是服务端,都存在一套自己的配置文件。
webpack.client.js 和 webpack.config.js 在内容层面,这里面的内容有很多相同之处。
所以我们需要把这些雷同的代码抽取出来,单独创建一个基准文件 webpack.common.js,然后通过一个叫 webpack-merge 的依赖包对它们进行拼装。
- npm install webpack-merge
参考网址:https://www.npmjs.com/package/webpack-merge
webpack.common.js 相同代码抽离:
//webpack.common.js 内容
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 客户端打包文件内容:
//webpack.client.js
const 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 服务端打包文件内容:
//webpack.server.js
const 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)
这样,基本的配置文件合并我们就完成了。
# 启动指令优化
在 package.json 的 scripts 下,我们配置了很多指令:客户端打包指令,服务端打包指令,服务器启动指令。
现在我们要做一件事,那就是用一个指令把这三个指令全部都运行了。
在这里我们使用一个工具 npm-run-all。
- Npm install 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\""
},
配置完之后我们只需要一个指令 npm run dev 就可以搞定这三个指令的启动。
# 排除内置模块打包
在服务端打包后,可以看到这个打包文件特别大,达到了好几兆。
这是因为它在打包的过程中把一些 node 的内置模块也一起打包了,所以我们需要把这些 node 内置模块在打包的时候过滤掉。
这里我们需要工具 webpack-node-externals。
- Npm install webpack-node-externals
参考网址:https://www.npmjs.com/package/webpack-node-externals
在 webpack.server.js 中,我们添加一个属性。
//webpack.server.js
const 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 下打包的文件少了很多。
# 代码拆分
在写业务的过程中,建议将各个功能模块独立分开,这样便于项目维护和迭代开发。
所以在 server 目录下的 index.js 中,路由和渲染需要分离,不能混合在一起。
所以我们需要单独建立一个 render.js 文件,内容如下:
//server/render.js
import React from "react"
import Home from "../common/pages/home";
import { renderToString } from "react-dom/server"
export default ()=>{
const content = renderToString(<Home/>)
return `
<html>
<head>
</head>
<body>
<div id="root">${content}</div>
</body>
<script ></script>
</html>
`
}
在 server/index.js 下的内容:
//server/index.js
import app from "./http"
import render from "./render"
app.get("/",(req,res)=>{
res.send(render())
})
以上就是 React 同构渲染下我所列出的部分性能优化,希望在开发过程中能对你有所帮助~
推荐阅读:
点点“赞”和“在看”,保护头发,减少bug。