笔记: React 性能优化(Redux)

 

场景:父节点触发了更新,但是在子节点中只有部分(图中是绿色) 是真正需要更行并渲染, 其他的不需要。

笔记: React 性能优化(Redux)_第1张图片

理想情况下是只渲染必要的节点,React 默认是从最顶的绿色节点开始以下的所有子节点会被渲染。

可以参考 reactjs.org - Optimizing Performance 使用 shouldComponentUpdate 或者 PureComponent 进行优化。

如果组件继承了 Component, 则可以通过 shouldComponentUpdate 方法处理不必要的渲染,返回 false 则不调用 render 方法, 否则反之。 默认返回 true

如果组件继承了 PureComponent, 我们就不用写 shouldComponentUpdate 来处理了, 但是 PureComponent 只进行浅表比较。

使用 shouldComponentUpdate 的时候需要确保:

  1. shouldComponentUpdate 检查够快
  2. shouldComponentUpdate 检查够简单

对象的比较

对象的属性如果修改了, 但是对象还是原来的对象, 那么判等 === 结果是 true。如果单纯使用 === 会导致需要调用 render 的时候也没有调用 render

如果使用 const newValue2 = Object.assign({}, oldValue);, 不论对象是否改变, 通过判等(===)结果都是 false。 可以解决 浅表对比导致误判,但是解决不了冗余处理的问题。

如果是对于对象里面的属性进行深层的对比:

const isObjectEqual = (obj1, obj2) => {
    if(!isObject(obj1) || !isObject(obj2)) {
        return false;
    }

    // are the references the same?
    if (obj1 === obj2) {
       return true;
    }

   // does it contain objects with the same keys?
   const item1Keys = Object.keys(obj1).sort();
   const item2Keys = Object.keys(obj2).sort();

   if (!isArrayEqual(item1Keys, item2Keys)) {
        return false;
   }

   // does every object in props have the same reference?
   return item2Keys.every(key => {
       const value = obj1[key];
       const nextValue = obj2[key];

       if (value === nextValue) {
           return true;
       }

       // special case for arrays - check one level deep
       return Array.isArray(value) &&
           Array.isArray(nextValue) &&
           isArrayEqual(value, nextValue);
   });
};

const isArrayEqual = (array1 = [], array2 = []) => {
    if (array1 === array2) {
        return true;
    }

    // check one level deep
    return array1.length === array2.length &&
        array1.every((item, index) => item === array2[index]);
};

可以使用一些工具帮助我们找到有性能问题的地方:

  1. console.time
  2. React.perf
  3. 浏览器工具: Firefox, Chrome

例如:

export default store => next => action => {
    console.time(action.type);

    // `next` is a function that takes an 'action' and sends it through to the 'reducers'
    // this will result in a re-render of your application
    const result = next(action);

    // how long did the render take?
    console.timeEnd(action.type);

    return result;
};
import Perf from 'react-addons-perf';

export default store => next => action => {
    const key = `performance:${action.type}`;
    Perf.start();

    // will re-render the application with new state
    const result = next(action);
    Perf.stop();

    console.group(key);
    console.info('wasted');
    Perf.printWasted();
    // any other Perf measurements you are interested in

    console.groupEnd(key);
    return result;
};

规范化状态 和 非规范化状态, 尽量使用规范化状态

 

笔记: React 性能优化(Redux)_第2张图片

 

函数调用缓存库 memoization library - alexreardon/memoize-one

列表拖放库 Beautiful and accessible drag and drop for lists with React - atlassian/react-beautiful-dnd


参考文档:

  1. Performance optimisations for React applications
  2. Performance optimisations for React applications: Round 2
  3. reactjs.org - Optimizing Performance
  4. reactjs.org - Performance Tools

只是部分笔记, 详细的请查阅参考文档

你可能感兴趣的:(JavaScript,React,reactjs)