资讯专栏INFORMATION COLUMN

使用Performance对页面进行分析优化(实战篇)

luodongseu / 514人阅读

摘要:在此,我们可以使用懒加载方式对其进行优化,仅展示其对应类型的图,避免了不必要的资源浪费和计算时间。

这篇文章将介绍下实际使用performance对页面进行优化的过程。总的来说,chrome performance工具让我们更方便的发现在代码运行过程中的问题在哪里,便于对一些可能注意不到的问题进行定位、分析和优化。原文首发于个人博客

渲染优化

首先,我们对进入整个详情页进行分析,整个页面的结构大致如下,主要包含三个部分:基本信息,可视化图和时间轴。时间轴内部包含时间轴的详情信息,包括表格和几种类型的可视化图等,内部比较重。如图所示:

我们点击录制,查看进入页面的性能图:

优化点1

可以看到,渲染当前页面的耗时将近1.2s,我们看看到底是哪里出现了问题。对渲染部分进行放大,我们发现在渲染时间轴的过程中,大部分时间耗费在了每个时间节点详情内容的展示上面,但是默认状态下,他们是进行隐藏的。也就是说,我们进行了N个节点的不必要的渲染,只需把他们干掉就好了。

查看代码,发现是以下位置导致的,我们进行了一个展开盒子的封装,类似这样:


  

在非展开状态下,我们依然对内容进行了渲染,只是使用样式进行了隐藏,但是这样React仍然会进行虚拟dom的渲染和计算,在这里我们对其进行改造,让其只在展开时进行渲染,并尽量缓存渲染的结果。修改完成后,我们会发现,Scripting由之前的880+ms变成了670ms减少了200ms左右:

优化点2

我们继续看,会发现页面初始化时,详情部分会有大量的Evaluate Script耗时,主要是耗费在告警详情右侧的分类及各分类下的可视图及详情引起的。

我们可能会想,这里在初始化时并没有进行渲染,为什么仍然会耗费时长进行计算呢?继续追查我发现原因在这里:

在整个详情组件中,我们对包括http,tcp等所有类型的组件进行了引用,然后根据其类型进行组件的匹配,在各个组件中可能包含了每个类型对应的定义、分类和计算等等等等,不仅增加了加载时间,更延长了初始化时间,显然我们这么做是不对的。

在此,我们可以使用懒加载方式对其进行优化,仅展示其对应类型的图,避免了不必要的资源浪费和计算时间。

修改之后,我们再次进行性能测试,发现在进入页面时,详情组件的耗费时长由260ms变为不到2ms:

而Scripting由之前的670+ms变成了415ms减少了250ms左右:

至此,进入页面的耗时已由最开始的1.2s左右变成了现在的0.7s左右。

更新优化

我们在点击时间轴查看详情时,会进行几个操作。关闭其他已开启的详情内容,展开当前详情内容,根据当前的类型进行对应类型的详情内容展示,上边已经提到过。这个过程会涉及到React的update操作,我们来对这个过程进行一下优化。

优化点1

首先我们点击录制按钮,然后点击展开,并对其进行录制。我们会发现以下的结果:

点击展开按钮,Timeline组件进行了多次重复渲染,显然这是不应该的,我们来看下是哪里导致的。我们看到整个时间轴组件中,有这样一段代码,在时间轴组件中使用connect连接了timeline和alertList两个数据,其中,alertList数据是详情内种中对应的告警列表。两组数据对应的更改都会映射到组件的更新,比如时间轴的展开收起,以及alertList请求,请求成功及失败等。

按理来说,alertList对应的请求,仅对应到当前展开内容的更新即可。因此,我们对此有几种修改方案:

时间轴组件中弃用对alertList的引用,以保证alertList不会牵连到时间轴组件整体更新

将时间轴的渲染和详情渲染进行分离,向其传递各自对应的数据,通过PureComponent来控制更新

使用shouldComponentUpdate进行优化

在此我们采用第一种,避免alertList对整个组件的影响。

我们会发现,点开详情后,整个timeLine只进行了一次大更新,详情的更新只在展开的组件中进行。

优化点2

我们会发现,在对某一个时间点进行展开时,整个list列表的节点都进行了更新,如下图所示。显然这样的性能耗费是及其大且不重要的。假如列表的内容很多,那极有可能造成大量的更新导致页面卡死。

因为其他的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,极大的增加了体验。

其他优化过程与上面类似,不再赘述。

总结

通过配合performance工具进行一步步优化,整个页面的渲染和更新性能有了极大的提升,我们也借此知道了在平时书写代码过程中需要注意的问题。我们简单的做一下总结:

避免非展示状态的不必要的渲染

必要时,手动进行懒加载以避免大型模块对页面进行营销,避免加载不必要的模块

保证展示组件props的纯净性,避免因其他props的更改导致组件进行更新

必要时,可使用shouldComponent进行手动优化

平时可通过PureComponent来避免不必要的组件更新

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/98232.html

相关文章

  • 淘宝新势力周H5性能优化实战

    摘要:前言淘宝新势力周春上新是命运石链路链路第一次承接级大促,面对级大促内容丰富且复杂的页面需求,链路遇到了一些性能问题,在未进行性能优化之前,搭建出来的页面,业务方普遍反馈页面卡顿严重,无法滑动。 前言 淘宝新势力周(春上新)是命运石kimi链路(H5链路)第一次承接S级大促,面对S级大促内容丰富且复杂的页面需求,kimi链路遇到了一些性能问题,在未进行性能优化之前,搭建出来的页面,业务方...

    Lionad-Morotar 评论0 收藏0
  • 前端性能优化Performance神器

    摘要:需要注意的一点是,面板下的功能,是对于细节中的细节进行的优化。我们可以很清晰明了得分析按照活动,目录,域,子域,和进行分组的前端性能。个人理解的话,前者类似事件冒泡,后者类似事件捕获。同学在点我达,他们正在筹划改组成大前端团队。   对Chrome控制台有一定的了解的朋友都在知道,Network面板会包括很多网络请求方面的东西,包括Http相关的Request信息,Response信息...

    qujian 评论0 收藏0
  • 记录一次利用Timeline Performance工具进行 React性能优化的真实案例

    摘要:出现红帧表示页面已经超负荷,会出现卡顿,响应缓慢等现象。因此当滑动周日历时已经不会有红帧发生了。我的目的是每一次递归会调用一次与但是这样写只会在递归结束时调用一次因此修改如下这样优化之后,发现内存占用下降一些,但是红帧仍然存在。 性能优化可以说是衡量一个前端程序员react使用水平的重要标准。 在学习react之初的时候,由于对react不够了解,写的项目虽然功能都实现了,但是性能优化...

    jsyzchen 评论0 收藏0
  • 全新Chrome Devtools Performance使用指南

    摘要:分析每一秒的帧是用来分析动画的一个主要性能指标。轴代表了调用栈。在事件长条的右上角出,如果出现了红色小三角,说明这个事件是存在问题的,需要特别注意。双击这个带有红色小三角的的事件。 运行时性能表现(runtime performance)指的是当你的页面在浏览器运行时的性能表现,而不是在下载页面的时候的表现。这篇指南将会告诉你怎么用Chrome DevTools Performance...

    sumory 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<