React 下同构渲染的优化手段

勾勾的前端世界

共 3827字,需浏览 8分钟

 ·

2020-12-06 11:13

嗨,我是你稳定更新、持续输出的勾勾。



前面两篇文章我写了“手动实现一个自己的 React 服务端渲染”和“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.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 服务端打包文件内容:

//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)


这样,基本的配置文件合并我们就完成了。


# 启动指令优化


在 package.json 的 scripts 下,我们配置了很多指令:客户端打包指令,服务端打包指令,服务器启动指令。


现在我们要做一件事,那就是用一个指令把这三个指令全部都运行了。


在这里我们使用一个工具 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\""  },


对于这些指令的书写,可以去地址中查找对应的 API。


配置完之后我们只需要一个指令 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.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 下打包的文件少了很多。


# 代码拆分


在写业务的过程中,建议将各个功能模块独立分开,这样便于项目维护和迭代开发。


所以在 server 目录下的 index.js 中,路由和渲染需要分离,不能混合在一起。


所以我们需要单独建立一个 render.js 文件,内容如下:

//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 下的内容:

//server/index.jsimport app from "./http"import render from "./render"app.get("/",(req,res)=>{    res.send(render())})


以上就是 React 同构渲染下我所列出的部分性能优化,希望在开发过程中能对你有所帮助~


推荐阅读:

React 下的同构渲染

手动实现一个自己的 React 服务端渲染

不会真的有人不知道 API 如何设计吧。

别再复制粘贴了!高效工作神器—— plop

API 终结者 —— 杀手 Reflect

前端人因为 Vue3 的 Ref-sugar 提案打起来了!

CRA 为什么要做成“黑盒”

基操勿 6 | Node.js 的异步I/O到底有多秀?


点点“”和“在看”,保护头发,减少bug。

浏览 30
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报