react + redux Router + node实践总结(react性能优化)

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,略小些)
            • 地现有项目入侵太严重(旧项目评估时间后再用,新的项目使用)
      • key: 尽量不使用索引值做为key值,因为当我们操作数组时,数组发生变化 ,索引值也会发生变化 ,所以react会重新生成DOM树
  • Redux性能优化
    -reselect: 对redux做数据计算缓存
  • React同构
    • 首页使用服务端渲染,其他页面仍然使用浏览器渲染
    • React服务端渲染SSR
      • 服务端渲染介绍
        • 传统服务端渲染:JSP、smaty、jinja2等
          • 服务端语言模板+数据
            • 前后端一体
            • 后端模板+数据生成html给浏览器
            • 首屏快,每次获取都会刷新页面
          • 优点:首屏快
          • 缺点:每次都会刷新页面
        • 浏览器渲染:通过js获取数据(ajax获取)
          • 浏览器渲染的APP
            • 后端只提供静态资源和接口
            • 前端写模板,渲染,MVVM框架
            • 单页应用 ,页面跳转也不刷新,体验好,首屏慢,SEO不好实现
          • 优点: 交互体验好,无需每次都刷新页面,进行 局部刷新
          • 缺点:首屏慢
        • 前后同构,首屏服务端渲染
          • 服务端生成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

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值