热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

reactbenchmark

简单的说一下如何在react开发中,进行benchmark,并且会简单的说一些可以提升性能的小技巧。Performance既然想要进行benchmark

简单的说一下如何在 react 开发中,进行 benchmark,并且会简单的说一些可以提升性能的小技巧。

Performance

既然想要进行 benchmark,那么就需要一个指标来衡量。react 官方已经提供了这样的工具供开发人员使用。

官方的文档可以参考这里Performance Tools,在这里我再做个简单的介绍。

引入

import Perf from 'react-addons-perf';

就可以将Performance Tool引入到当前的 react app 中使用了。

使用

Performance Tool的使用十分方便,在上一步引入的 Perf 本身是个对象,可以直接调用其方法,来进行性能测试。

获取指标的方法
  • Perf.start(): 开始记录
  • Perf.stop(): 停止记录
  • Perf.getLastMeasurements(): 获取最后一条记录
输出指标的方法

以下这些方法,如果不传入参数的话,都会调用Perf.getLastMeasurements()方法,获取最新的 measurements

  • Perf.printInclusive(measurements): 输出组件 lifecirlifecyclecle 全部执行完的时间
  • Perf.printExclusive(measurements): 只输出组件渲染所用的时间,不包括 componentWillMountcomponentDidMount的执行时间
  • Perf.printWasted(measurements): Wasted的是指页面中的 dom 实际并没有发生变化,但是组件仍然被渲染的操作,printWasted就是输出这些无意义操作所用的时间
  • Perf.printOperations(measurements): 详细输出每一个组件dom 操作(包括 innerHTML 和 remove)所用的时间和相关信息
一个实例截图

一个截图

一些优化技巧

functional

举个简单的例子,假设我们需要渲染一个并没有交互的组件,例如一句话,那么这个组件其实也不存在 lifecycle,那么可以直接使用函数式的方法输出这个组件

我做了个简单的 demo,可以 clone 下来自己看下

// 使用 component
class Text extends React.Component {render () {return (

{ this.props.text }
)}
}
export default Text// 使用匿名函数
export default (text) => {return (
{ text }
)
}

看下 Performance Tool输出的结果

一个截图

可以明显的看到Benchmark > FunctionWrap的总时间要小于Benchmark > ComponentWrapBenchmark > PureComponentWrap所用的时间

这是因为使用匿名函数,省掉了 lifecycle 的一系列函数调用的时间,Benchmark > PureCompnent耗时最长是因为React.PureComponent会在shouldComponentUpdate中默认进行shallowEqual的操作,所以初始化渲染会比较慢。

使用 PureComponent

React.PureComponentReact.Component的区别就在于PureComponent会默认带一个shouldComponentUpdate的方法,通过shallowEqual对比当前的 component 是否需要进行重新渲染。

有了这样的一个简单的判断,在不手动写shouldComponentUpdate方法时,也可以获得一定的性能提升。

具体的测试,同样可以看这个demo,里面有相关的测试。

一个隐形的坑

通常在可交互的组件上,我们会绑定一些事件,例如下面的例子

class User extends React.Component {render () {console.log('render user')return (

is a component

name: { this.props.data.name }

id: { this.props.data.id }

)}
}class PureUser extends React.PureComponent {render () {console.log('render pure user')return (

is a pure component

name: { this.props.data.name }

id: { this.props.data.id }

)}
}class Anonymous extends React.Component {constructor (props) {super(props)this.state = {data: Foo}}render () {return (
{ this.renderUser() }{ this.renderPureUser() }
)}changeData () {Pref.start()this.setState({data: Foo})}renderUser () {return }renderPureUser () {return }
}

在这个例子中会将state.data传递给自组件,同时会传递一个 onClick 的事件回调给子组件。

在运行这个例子时,我们会发现即使我们使用React.PureComponent,并且并没有实际改变 state.data的值,但是 这个组件还是会跟 组件一样,会重复被渲染。

究其原因,在于onClick这里使用了.bind方法,将changeData绑定到了当前的作用域内,但是.bind方法返回的是个匿名函数,所以事实上每次传入到子组件内的props都是不同的,PureComponent也会被重新渲染。

为了避免这种情况,可以将.bind方法前置,改在constructor中预先绑定,这样onClick将指向一个固定的函数,例子:

class PublicClassFields extends React.Component {constructor (props) {super(props)this.state = {data: Foo}this.changeData = this.changeData.bind(this)}......
}

这样的话,PureUser在执行 changeData后就不会被重新渲染了。

ps

后续还会有一些关于 react 性能相关的内容补充进来,同时也会不断的更新这个 repo中的实例。



推荐阅读
  • 本文介绍了在wepy中运用小顺序页面受权的计划,包含了用户点击作废后的从新受权计划。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 展开全部下面的代码是创建一个立方体Thisexamplescreatesanddisplaysasimplebox.#Thefirstlineloadstheinit_disp ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • 本文记录了在vue cli 3.x中移除console的一些采坑经验,通过使用uglifyjs-webpack-plugin插件,在vue.config.js中进行相关配置,包括设置minimizer、UglifyJsPlugin和compress等参数,最终成功移除了console。同时,还包括了一些可能出现的报错情况和解决方法。 ... [详细]
  • 先看看ElementUI里关于el-table的template数据结构:<template><el-table:datatableData><e ... [详细]
  • EPPlus绘制刻度线的方法及示例代码
    本文介绍了使用EPPlus绘制刻度线的方法,并提供了示例代码。通过ExcelPackage类和List对象,可以实现在Excel中绘制刻度线的功能。具体的方法和示例代码在文章中进行了详细的介绍和演示。 ... [详细]
author-avatar
丁丽君coolboy
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有