博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
react性能优化
阅读量:5916 次
发布时间:2019-06-19

本文共 2691 字,大约阅读时间需要 8 分钟。

如果想提高性能就需要知道什么地方会影响性能?

从过往的经验和实践中,影响网页性能最大的因素就是浏览器的重绘和回流,React背后的虚拟DOM就是尽可能的减少浏览器的重绘和回流。

那在此之上,我们还能做什么来防止不必要的渲染?

在这之前,先跟我一起了解下***函数式编程***

什么是函数式编程?

函数式编程起源于数学,假设我们定义一个加法的方法f,然后改变输入为f(1,3),那么无论这个方法的上下文,无论什么时间调用多少次,返回结果都是4,用数学表达就是f(x,y) = z,给定输入x,y作用在f上,始终结果是z

函数式编程讲究的三个原则:

1.相同的输入得到相同的输出
2.没有副作用
3.不依赖外部的状态(方法内的状态都只在方法的生命周期内存活,不能在方法中使用共享变量,因为这样会给方法带来不可知对的因素)

那说了这么多函数式编程有什么好处呢?

1、函数式编程不依赖外部状态这一特点,使得我们可以利用CPU在分布式集群上做并行计算,这对于多种科学计算和资源密集型计算任务是非常核心的一点,让计算机高效处理这类任务变动的可能 2、相同的输入得到相同对的输出,这让我们的代码变得可预测,可以非常方便的进行方法级别的测试。


说完函数式编程,我们再回头说说react的性能优化 《深入React技术栈中》这样描述的“ react的设计是有函数式编程的基因的,react组件本身就是纯函数,react的createElement方法保证了组件是纯净的,即传入相同的props得到一定的虚拟dom,整个过程可预测”。

那么优化的时候我们可以考虑通过拆分组件为子组件,进而对组件进行更细粒度的控制。


那接下来就要考虑如何做更细粒度控制,避免多次无用渲染?

react官方有提供PureComponent类,凡是继承自这个类的组件,react都会默认在shouldComponentUpdate中替你做这样一件事,浅比较你的新传入的props和state是否和现在的props,state。所谓的浅比较就是只比较props和state中数据的引用地址,引用地址不改变就不会重新渲染。

很显然,问题来了,如果我的数据结构嵌套很深,那岂不是会忽略掉深层次的数据变化,而导致页面不渲染? 因此react官方提醒道,继承PureComponent之前最好props,state的结构简单,对于嵌套深的结构就不要继承PureComponent了


那对于深层次的数据结构就这样放弃使用puerRender了吗?答案当然不是了,不过先不急着说这个,我们先说对于结果简单的可以继承PureComponent的我们要注意些什么?

item.val>10)}>复制代码

这种直接将props设置成对象或者数组的方式,每次都会触发重新渲染,哪怕值没有改变。

原因在于每次调用react组件都会重新创建组件,就算传入的数组或对象值没有改变,但是引用地址发生改变了。

解决方法,将对象提前赋值为常量,不直接使用字面量即可 2、

复制代码

设置props方法并通过bind绑定this的方式,每次都会触发重新渲染

原因在于bind会返回一个函数,每次执行bind返回的函数的引用地址改变了

解决办法采用箭头函数

3、

class NameItem extends Component {    render(){        return (        
a child
) }} 复制代码

对于设置了子组件的react组件,每次都会重新渲染。

原因在于,组件编译之后其实是这样的

复制代码

children引用改变了,导致每次都会重新渲染

解决办法让NameItem(也就是Item的父组件)继承pureComponent,根据浅比较策略不会对Item的children进行深比较,也就不会重新渲染


说完简单的数据结构,我们再来说下对于props和state比较复杂的数据结构应该怎么处理,答案是采用immutable。

简单说下immutable

持久化数据存储:对immutable对象进行修改的时候都会返回一个新的immutable对象,也就是使用旧数据创建新数据时,包证了旧数据可用 结构化共享:如果树中一个节点变化,则只修改这个节点和受它影响的父节点,其他节点实现共享,避免了深拷贝带来的性能问题

如何使用immutable实现pureRender?

答案是在shouldComponentUpdate中利用immutable进行深比较,抛弃之前的PureComponent的浅比较

import React from 'react';import {is} from 'immutable';class App extends Component { shouldComponentUpdate(nextProps,nextState){   const thisProps = this.props || {};   const thisState = this.state || {};   if(Object.keys(thisProps).length !== Object.keys(nextProps.keys).length ||   Object.keys(thisProps).length !== Object.keys(nextProps.keys).length){       return true;   }   for(const key in nextProps){     if(nextProps.hasOwnProperty(key) && !is(thisProps[key],nextProps[key])){       return true;     }   }   for(const key in nextState){     if(nextState.hasOwnProperty(key) && !is(thisState[key],nextState[key])){       return true;     }   }   return false; }}复制代码

转载于:https://juejin.im/post/5c82157bf265da2dd7741142

你可能感兴趣的文章
Tsuru 1.7.0-rc4 发布,基于 Docker 的 PaaS 框架
查看>>
正则表达式学习
查看>>
使用Webpack + Gulp便捷开发运行于Dcloud平台HTML5 Plus Runtime引擎的HybridAPP项目的一些经验分享...
查看>>
前端进阶之 a 可以同时 == 1 && == 2 && == 3吗?
查看>>
告别抽象的JS执行环境、作用域、作用域链、闭包
查看>>
9012到了!AI时代里,只会简单编程的你会怎么样?
查看>>
1月10日云栖精选夜读:专访金榕:四年蜕变,阿里iDST是如何登上浪潮之巅的?...
查看>>
区块链100讲:梅克尔树保障区块链数据不可篡改,想换根就要砍树!
查看>>
如何使用jstack分析线程状态
查看>>
运营不需要人脉?
查看>>
Spring Cloud Config服务器
查看>>
fprobe使用
查看>>
yum 安装rabbitMQ
查看>>
GLSL变量
查看>>
测试人员必学的软件快速测试方法(二)
查看>>
linux下以RPM包安装Oracle 客户端
查看>>
ant_Jmeter持续集成测试报告优化之添加throughput显示
查看>>
Hive(一):Hive的安装部署
查看>>
Codeforces Round #219 (Div. 1) A. Counting Kangaroos is Fun 【二分】
查看>>
day6作业--选课系统
查看>>