React性能优化整理

更新日期: 2019-09-22阅读: 2.3k标签: 性能

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


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

提高js加载速度,实现js无阻塞加载方式,高性能的加载执行JavaScript

为解决JS加载速度慢,采用js的延时加载,和动态加载。由于js的堵塞特性,当浏览器在加载javascript代码时,不能同时做其他任何事情,如果javascript执行时间越久,浏览器等待响应的时间就越久。

如何提高CSS性能?CSS优化、提高性能提升总汇

如何提高CSS性能,根据页面的加载性能和CSS代码性能,主要表现为: 加载性能 (主要是从减少文件体积,减少阻塞加载,提高并发方面入手),选择器性能,渲染性能,可维护性。

前端性能优化_css加载会造成哪些阻塞现象?

css的加载是不会阻塞DOM的解析,但是会阻塞DOM的渲染,会阻塞link后面js语句的执行。这是由于浏览器为了防止html页面的重复渲染而降低性能,所以浏览器只会在加载的时候去解析dom树,然后等在css加载完成之后才进行dom的渲染以及执行后面的js语句。

2018 前端性能检查表

性能十分重要。然而,我们真的知道性能瓶颈具体在哪儿吗?是执行复杂的 JavaScript,下载缓慢的 Web 字体,巨大的图片,还是卡顿的渲染?研究摇树(Tree Shaking),作用域提升(Scope Hoisting)

高性能Javascript总结

Js高性能总结:加载和运行、数据访问、DOM编程、算法和流程控制、响应接口、Ajax 异步JavaScript和XML、编程实践...

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

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

前端性能的本质是什么?

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

BigPipe_高性能流水线页面技术

BigPipe是一个重新设计的基础动态网页服务体系。大体思路是,分解网页成叫做Pagelets的小块,然后通过Web服务器和浏览器建立管道并管理他们在不同阶段的运行。这是类似于大多数现代微处理器的流水线执行过程:多重指令管线通过不同的处理器执行单元,以达到性能的最佳。

用CSS开启硬件加速来提高网站性能

你知道我们可以在浏览器中用css开启硬件加速,使GPU (Graphics Processing Unit) 发挥功能,从而提升性能吗?现在大多数电脑的显卡都支持硬件加速。鉴于此,我们可以发挥GPU的力量,从而使我们的网站或应用表现的更为流畅。

原生js实现懒加载并节流

像淘宝网站等,页面中有着大量图片,一次性全部加载这些图片会使浏览器发送大量请求和造成浪费。采用懒加载技术,即用户浏览到哪儿,就加载该处的图片。这样节省网络资源、提升用户体验、减少服务器压力。

点击更多...

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