关闭

React性能优化整理

时间: 2019-09-22阅读: 939标签: 性能

class 组件的优化

通过判断减少数据变化触发的重新渲染, 以及之后的 DOM diff

shouldComponentUpdate(nextProps, nextState) {
  if (this.props.color !== nextProps.color) {
    return true;
  }
  if (this.state.count !== nextState.count) {
    return true;
  }
  return false;
}

JavaScript 对象引用问题

函数式语言当中, 语言设计允许两个对象一样, 举例 Clojure:

(= {:a 1} {:a 1}) ; true

(identical? {:a 1} {:a 1}) ; false

递归匹配, 性能并不高.

JavaScript 对象基于引用传值, 比较单一

{a: 1} === {a: 1} // false

大体方案, 通过手动维护, 让相同的数据尽量保证引用一致, 控制性能.

function updateColorMap(colormap) {
  return {...colormap, right: 'blue'};
}

useMemo 优化

每个函数体当中生成的对象都会有新的引用, useMemo 可以保留一致的引用.

const myObject = useMemo(() => ({ key: "value" }), [])

注意: 用花括号直接写对象基本上就是新的引用了,

{}
{a: 1}

{...obj}

一般组件内部不变的对象, 都是从 state, ref, 再或者组件外全局有一个引用.


react.memo 优化

判断参数是否改变, 如果没有改变, 就直接复用已有的组件, 不重新生成:

const MyComponent = react.memo(function MyComponent(props) {
  /* only rerenders if props change */
});

React.memo 有第二个参数, 用于自定义判断的规则:

const MemoItem = React.memo(Item, (prevProps, nextProps) => {
  if (prevProps.item.selected === nextProps.item.selected) {
    return true;
  }
  return false;
});

useCallback 优化

使用 React.memo 包裹组件:

let Inner: FC<{
  onClick: () => void
}> = React.memo((props) => {
  return <div>
    <span>inner</span>
    </div>;
});

使用 useCallback

let Outer: FC<{}> = React.memo((props) => {
  const [counter, setCounter] = useState(0);
  const onClick = useCallback(()=>{ 
    setCounter(prevState => ++prevState)
  },[]);
  return <div>
    <span>outer: {counter}</span>
    <Inner onClick={onClick} />
  </div>;
});

避免 render 当中的 DOM 操作

let NewComponent: FC<{}> = React.memo((props) => {

  let elRef = useRef<htmlDivElement>()

  // 错误写法
  if (elRef.current) {
    elRef.current.style.color = 'red'
  }

  return <div ref={elRef}></div>;
});

DOM 发生改变的时候, 一般会有比较多后续的布局和 compose 计算去绘制新的界面.

特别是在脚本执行过程当中发生的话, 会对性能有明显影响.

脚本执行完再执行, 让浏览器自动处理(合并, 避免频繁 DOM 操作).


业务相关

  • immer 对优化方案的影响
  • Rex 组件当中优化的坑
  • 路由相关的优化
  • 性能调试

Immer 对优化方案的影响

let a = {}
let b = produce(a, draft => {
  draft.b = 1
})

a === b // false

如果数据不发生改变, 直接用原始数据.

(Hooks API 之后, 数据被拆散了, 可以减少 immer 的使用.)


Rex 当中优化的相关

class 组件, 高阶组件当中自动做了基础的优化.

shouldComponentUpdate(nextProps: IRexDataLayerProps, nextState: any) {
  if (!shallowequal(nextProps.parentProps, this.props.parentProps)) return true;
  if (!shallowequal(nextProps.computedProps, this.props.computedProps)) return true;
  return false;
}

Hook API, 没有中间一层组件, 直接触发当前组件更新, 存在性能问题.(还要考虑优化方案)

let contextData = useRexContext((store: IGlobalStore) => {
  return {
    data: store.data,
    homeData: store.homeData,
  };
});

业务当中一般可以接受, 因为数据通常都是在更新的. 新能敏感场景需要额外考虑.


ruled-router 提供的优化

/home/plant/123/shop/456/789

解析为

{
  "raw": "home",
  "name": "home",
  "matches": true,
  "restPath": ["plant", "123", "shop", "456", "789"],
  "params": {},
  "data": {},
  "next": {
    "raw": "plant/:plantId",
    "name": "plant",
    "matches": true,
    "restPath": ["shop", "456", "789"],
    "params": {
      "plantId": "123"
    },
    "data": {
      "plantId": "123"
    },
    "next": {
      "raw": "shop/:shopId/:corner",
      "name": "shop",
      "matches": true,
      "next": null,
      "restPath": [],
      "data": {
        "shopId": "456",
        "corner": "789"
      },
      "params": {
        "plantId": "123",
        "shopId": "456",
        "corner": "789"
      }
    }
  }
}

生成对象保存起来, 路由发生变更时再重新解析. 这样对象引用一般保持一致.

来自:https://segmentfault.com/a/1190000020769066


站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/6081

关闭

如何优化css expression性能?

IE 浏览器中 CSS Expression 特性的最大的问题:会反复执行,每秒钟可能执行了成百上千次,有严重的性能问题。何对 CSS Expression 进行优化呢?至少:如果我们将 CSS Expression 在匹配的元素中仅执行一次,性能将会提升很大。

php中一些提高性能的技巧

【概述】* 把类定义成static* echo比print快* 用全等号代替双等,减少类型转换* echo用逗号连接字符串效率高* require比require_once()快,并且尽量不要使用相对路径

页面渲染性能控制-重绘与回流

页面的显示过程分为以下几个阶段:生成DOM树(包括display:none的节点),在DOM树的基础上根据节点的集合属性(margin,padding,width,height等)生成render树

JavaScript最佳实践:性能

该函数可能看上去完全正常,但是它包含了三个对于全局document对象的引用。如果在页面上有多个图片,那么for循环中的document引用就会被执行多次甚至上百次,每次都会要进行作用域链查找

优化 web 应用程序性能方案总结

在开发 web 应用程序时候,性能都是必不可少的话题。而大部分的前端优化机制都已经被集成到前端打包工具 webpack 中去了,当然,事实上仍旧会有一些有趣的机制可以帮助 web 应用进行性能提升

前端性能的本质是什么?

性能一直以来是前端开发中非常重要的话题。随着前端能做的事情越来越多,浏览器能力被无限放大和利用:从 web 游戏到复杂单页面应用,从 NodeJS 服务到 web VR/AR 和数据可视化,前端工程师总是在突破极限

小程序Canvas性能优化实战

在小程序中使用canvas组件绘制地铁图,地铁图包括地铁线路、站点图标、线及站点名称文字,绘制元素为线、圆、图片、文字。 支持拖动平移和双指缩放。

优化网站性能规则_前端性能优化策略【网络加载、页面渲染】

前端网站性能优化规则:网络加载类、页面渲染类。包括:减少 HTTP 资源请求次数、减小 HTTP 请求大小、避免页面中空的 href 和 src、合理设置 Etag 和 Last-Modified、使用可缓存的 AJAX、减少 DOM 元素数量和深度等

如何将 HTML5 性能发挥到极致

HTML5作为新兴领域越来越热。然而在移动设备硬件性能弱于PC的背景下,对性能的需求显得更为重要,而HTML5性能优化前与优化后有着极大的差别,如何优化才能提高性能,对此熟知的人很少。本文以LayaAir引擎为例

JS如何提高展开运算符的性能?

展开运算符或三个点,接受一个数组数组或通常是可迭代的[... arrayOrIterable]并将数组元素分解,并使用这些分解部分构造一个新数组。展开运算符可以放在数组中的任何位置:

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!