这篇文章将介绍下实际使用performance对页面进行优化的过程。总的来讲,chrome performance工具让咱们更方便的发如今代码运行过程当中的问题在哪里,便于对一些可能注意不到的问题进行定位、分析和优化。原文首发于我的博客chrome
渲染优化
首先,咱们对进入整个详情页进行分析,整个页面的结构大体以下,主要包含三个部分:基本信息,可视化图和时间轴。时间轴内部包含时间轴的详情信息,包括表格和几种类型的可视化图等,内部比较重。如图所示:缓存
图片描述dom
咱们点击录制,查看进入页面的性能图:tcp
优化点1
能够看到,渲染当前页面的耗时将近1.2s,咱们看看究竟是哪里出现了问题。对渲染部分进行放大,咱们发如今渲染时间轴的过程当中,大部分时间耗费在了每一个时间节点详情内容的展现上面,可是默认状态下,他们是进行隐藏的。也就是说,咱们进行了N个节点的没必要要的渲染,只需把他们干掉就行了。工具
图片描述性能
查看代码,发现是如下位置致使的,咱们进行了一个展开盒子的封装,相似这样:测试
<Box data={data} border collapse loading={loading}>
<AlertDetail />
</Box>
在非展开状态下,咱们依然对内容进行了渲染,只是使用样式进行了隐藏,可是这样React仍然会进行虚拟dom的渲染和计算,在这里咱们对其进行改造,让其只在展开时进行渲染,并尽可能缓存渲染的结果。修改完成后,咱们会发现,Scripting由以前的880+ms变成了670ms减小了200ms左右:优化
图片描述this
优化点2
咱们继续看,会发现页面初始化时,详情部分会有大量的Evaluate Script耗时,主要是耗费在告警详情右侧的分类及各分类下的可视图及详情引发的。lua
clipboard.png
咱们可能会想,这里在初始化时并无进行渲染,为何仍然会耗费时长进行计算呢?继续追查我发现缘由在这里:
clipboard.png
在整个详情组件中,咱们对包括http,tcp等全部类型的组件进行了引用,而后根据其类型进行组件的匹配,在各个组件中可能包含了每一个类型对应的定义、分类和计算等等等等,不只增长了加载时间,更延长了初始化时间,显然咱们这么作是不对的。
在此,咱们可使用懒加载方式对其进行优化,仅展现其对应类型的图,避免了没必要要的资源浪费和计算时间。
clipboard.png
修改以后,咱们再次进行性能测试,发如今进入页面时,详情组件的耗费时长由260ms变为不到2ms:
clipboard.png
而Scripting由以前的670+ms变成了415ms减小了250ms左右:
clipboard.png
至此,进入页面的耗时已由最开始的1.2s左右变成了如今的0.7s左右。
更新优化
咱们在点击时间轴查看详情时,会进行几个操做。关闭其余已开启的详情内容,展开当前详情内容,根据当前的类型进行对应类型的详情内容展现,上边已经提到过。这个过程会涉及到React的update操做,咱们来对这个过程进行一下优化。
优化点1
首先咱们点击录制按钮,而后点击展开,并对其进行录制。咱们会发现如下的结果:
clipboard.png
点击展开按钮,Timeline组件进行了屡次重复渲染,显然这是不该该的,咱们来看下是哪里致使的。咱们看到整个时间轴组件中,有这样一段代码,在时间轴组件中使用connect链接了timeline和alertList两个数据,其中,alertList数据是详情内种中对应的告警列表。两组数据对应的更改都会映射到组件的更新,好比时间轴的展开收起,以及alertList请求,请求成功及失败等。
clipboard.png
按理来讲,alertList对应的请求,仅对应到当前展开内容的更新便可。所以,咱们对此有几种修改方案:
时间轴组件中弃用对alertList的引用,以保证alertList不会牵连到时间轴组件总体更新
将时间轴的渲染和详情渲染进行分离,向其传递各自对应的数据,经过PureComponent来控制更新
使用shouldComponentUpdate进行优化
在此咱们采用第一种,避免alertList对整个组件的影响。
咱们会发现,点开详情后,整个timeLine只进行了一次大更新,详情的更新只在展开的组件中进行。
clipboard.png
优化点2
咱们会发现,在对某一个时间点进行展开时,整个list列表的节点都进行了更新,以下图所示。显然这样的性能耗费是及其大且不重要的。假如列表的内容不少,那极有可能形成大量的更新致使页面卡死。
clipboard.png
由于其余的list列表节点都引用了alertList这个prop, 当其进行改变时,全部的节点都会进行更新,因此咱们须要使用shouldComponentUpdate手动对其进行优化:
// 当开关状态变化时,才重新渲染,不然不须要
shouldComponentUpdate (nextProps, nextState) {
const opened = _.get(this.props, 'open')
const willOpen = _.get(nextProps, 'open')
if (opened === willOpen && !willOpen) {
return false
} else {
// 相似pureComponent进行浅比较
return !_.isEqual(this.props, nextProps) || !_.isEqual(this.state, nextState)
}
}
再次进行录制,咱们发现只要当前Item进行了更新,整个Timeline更新时间缩短到不到40ms,极大的增长了体验。
clipboard.png
其余优化过程与上面相似,再也不赘述。
总结
经过配合performance工具进行一步步优化,整个页面的渲染和更新性能有了极大的提高,咱们也借此知道了在平时书写代码过程当中须要注意的问题。咱们简单的作一下总结:
避免非展现状态的没必要要的渲染必要时,手动进行懒加载以免大型模块对页面进行营销,避免加载没必要要的模块保证展现组件props的纯净性,避免因其余props的更改致使组件进行更新必要时,可以使用shouldComponent进行手动优化平时可经过PureComponent来避免没必要要的组件更新