React性能优化
在浏览器的地址栏中添加react_perf后缀,可进行react的性能测试
- React组件性能优化
- 单组件性能优化:尽可能减少数据的复杂性,
- 属性传递优化
- 尽可能不反复定义数据
- 定义事件时,使用在constructor中进行bind(this),尽量不要在render时进行bind或者使用箭头函数,因为每一次render时,都会执行下bind,或者重新定义一次函数,性能不好
- 为子组件传递属性时,属性需要提前定义,而不是直接在元素中使用,例如:Demo name={{react:’redux’}},如此会每次渲染时都会重新去生成这个对象,应该在constructor中或者render时提前定义,使用定义好的值传递
- 为子组件传递属性时,尽量减少传递的数量,尽量不使用Demo {…this.state}方式,避免属性值的冗余
- 尽可能不反复定义数据
- 多组件优化
- 使用 shouldComponentUpdate(nextProps, nextState)控制渲染
- 使用class Demo extends React.PureComponent, 可省略shouldComponentUpdate
- PureComponent(会对props和state进行浅对比,或值与上一次的值相同则不渲染页面)
- 使用immutable.js(使数据结构不可变,由此可直接使用=进行比较)
- 语法有map(定义数据),set(设置数据),get(获取数据),is(比较两个对象)
- let obj = Map({‘name’: ‘lmh’, ‘comp’: Map({name: ‘zddi’})})
- let obj1 = obj.set(‘name’, ‘woniu’)
- let name = obj1.get(‘name’)
- is(obj, obj1)
- 可将state定义为map对象
- immutable优点
- 减少内存使用
- 并发安全(不需要担心其他人对其进行修改)
- 降低项目复杂度
- 便于比较复杂数据,定制shouldComponentUpdate方便
- 时间旅行功能方便(因为每次都会生成新的数据)
- 函数式编程(数据不可变,故写纯函数会比较方便)
- immutable缺点
- 学习成本
- 库的大小(可使用seamless-immutable,略小些)
- 地现有项目入侵太严重(旧项目评估时间后再用,新的项目使用)
- 语法有map(定义数据),set(设置数据),get(获取数据),is(比较两个对象)
- key: 尽量不使用索引值做为key值,因为当我们操作数组时,数组发生变化 ,索引值也会发生变化 ,所以react会重新生成DOM树
- 属性传递优化
- 单组件性能优化:尽可能减少数据的复杂性,
- Redux性能优化
-reselect: 对redux做数据计算缓存 - React同构
- 首页使用服务端渲染,其他页面仍然使用浏览器渲染
- React服务端渲染SSR
- 服务端渲染介绍
- 传统服务端渲染:JSP、smaty、jinja2等
- 服务端语言模板+数据
- 前后端一体
- 后端模板+数据生成html给浏览器
- 首屏快,每次获取都会刷新页面
- 优点:首屏快
- 缺点:每次都会刷新页面
- 服务端语言模板+数据
- 浏览器渲染:通过js获取数据(ajax获取)
- 浏览器渲染的APP
- 后端只提供静态资源和接口
- 前端写模板,渲染,MVVM框架
- 单页应用 ,页面跳转也不刷新,体验好,首屏慢,SEO不好实现
- 优点: 交互体验好,无需每次都刷新页面,进行 局部刷新
- 缺点:首屏慢
- 浏览器渲染的APP
- 前后同构,首屏服务端渲染
- 服务端生成HTML结构
- node在服务端解析首屏模板(如此,js无需进行渲染的逻辑,JS首屏只需要做流水的操作,即js中的事件操作)
- React支持ssr
- React同构的API
- 后RenderToString和RenderToStaticMarkup
- React16新出的RenderToNodeStream,性能更好,是之前的3倍
- React16里,客户端hydrate取代render
- 项目SSR具体步骤:SSR实战,build代码后的事情
- 后node使用babel-node配置node里的react环境
- 修改客户端代码,抽离APP组件,前后端共享
- 服务端生成DOM结构,渲染,加载build后的css和js
- 服务端生成HTML结构
- 传统服务端渲染:JSP、smaty、jinja2等
- 服务端渲染介绍
eslint代码规范
在package.json中的eslintConfig中进行配置
"eslintConfig": {
"extends": "react-app", // 继承react中的eslint配置
"rules": {
"eqeqeq": ["off"], // 关闭使用===进行比较
"jsx-a11y/accessible-emoji": [0], // 关闭emoji使用span包裹
"semi": ["warn","never"] // 不使用分号
}
},
async+await优化异步代码
// 传统写法
export function readMsg(from) {
return (dispatch, getState) => {
axios.post('/user/readmsg', {from})
.then(res => {
const userid = getState().user._id
if(res.status === 200 && res.data.code === 0) {
dispatch(msgRead({userid, from, num: res.data.num}))
}
})
}
}
// async+await配合使用,await必须在async内部
export function readMsg(from) {
return async(dispatch, getState) => {
const res = axios.post('/user/readmsg', {from})
// 若有多个请求,处理会更方便
// 同步的形式写异步代码
const res1 = axios.post('/user/recvmsg', {from})
const userid = getState().user._id
if(res.status === 200 && res.data.code === 0) {
dispatch(msgRead({userid, from, num: res.data.num}))
}
}
}
React动态解决方案:Ant Motion
npm install rc-queue-anim –save
打包编译
npm run build
- 编译打包后,生成build目录
- express中间件,拦截路由,手动渲染index.html
- build设置为静态资源地址
项目上线流程 - 购买域名
- DNS解析到你服务器的IP
- 安装nginx
- 使用pm2管理node进程
使用babel-node在后端支持jsx环境
- npm install babel-cli –save
- 在根目录下新建.babelrc文件,将package.json中的babel的配置复制至此文件
React服务端渲染SSR实战
- node环境使用babel-node支持jsx
- 设置css和图片的hook
- npm install css-modules-require-hook
- npm install asset-require-hook –save(注:所有的图片要使用require去引用 )
- renderToString渲染html
React16新特性
- 新的核心算法Fiber
- 图1是16之前的算法,图2是Fiber算法
- 之前的算法:在调用一个组件实例树时,是递归调用,递归渲染,每个更新都是立即执行,由于react.js是单线程,所以每一个调用都是同步的,由此在计算时会出现阻塞,任务会进行排队,如果排队占用主线程较长时,就会出现图1的情况,任务都处在排队状态
- Fiber算法:基于一个执行单元,多个Fiber对应一个组件,我们可以对一个Fiber进行暂停、继续以及修改优先级,我们可以先渲染一部分然后把主线程交出来再渲染一部分,如此整个渲染对浏览器主线程的占用如图2
- render可以返回数组,字符串
- 错误处理机制
- 在App的componentDidCatch对错误进行统一处理
- portals组件:react可以渲染在它之外的元素
- 更好更快的服务端渲染(流式渲染)
- 之前版本的renderToString,解析为字符串
- 新版本的renderToNodeStream解析为可读的字节流对象
- 使用ReactDom.hydate取代render
- 体积更小,MIT协议(16后完全开源)
React16服务端渲染:更快的流式渲染
- 之前版本的renderToString,解析为字符串
- 新版本的renderToNodeStream解析为可读的字节流对象
- 使用ReactDom.hydate取代render
项目总结
- React、Redux、React-router4、redux-thunk、antd-mobile
- Socket.io、mongodb、express
- 自己实现redux、React服务端渲染SSR