关于前端:在瀑布下用火焰烤饼三步法助你快速定位网站性能问题超详细

30次阅读

共计 6415 个字符,预计需要花费 17 分钟才能阅读完成。

DevUI 是一支兼具设计视角和工程视角的团队,服务于华为云 DevCloud 平台和华为外部数个中后盾零碎,服务于设计师和前端工程师。

官方网站:devui.design

Ng 组件库:ng-devui(欢送 Star)

官网交换:增加 DevUI 小助手(devui-official)

DevUIHelper 插件:DevUIHelper-LSP(欢送 Star)

引言

性能,是一个问题。

每个我的项目成长到肯定的规模,都简直必然要遇到性能问题,当遇到性能问题时,咱们是:

一脸懵逼,就晓得很卡、很慢,不晓得为什么

还是

可能疾速洞察性能瓶颈,找到卓有成效的优化计划

取决于咱们对性能的了解深浅,以及是否有一套好的工具和办法。

接下来给大家分享我本人在定位业务性能问题时罕用的三步法,为了不便记忆,我把它总结为一句话:

在瀑布下用火焰烤饼

话不多说,喝口水间接开撸!

Performance 面板简介

介绍三步法之前,先来简略理解下 Chrome 开发者工具的 Performance 性能面板,以及性能剖析报告的根本组成。

生成性能剖析报告

以 DevUI 团队的掘金个人主页为例,应用 Chrome 浏览器拜访:https://juejin.cn/user/712139267650141

而后按 F12 关上 Chrome 的开发者工具,抉择 Performance 性能面板。

这时咱们会看到一个简略的指引:

指引外面有两个按钮,下面的按钮是手动录制,上面的是主动录制,咱们点击傻瓜式的主动录制,主动录制会主动刷新页面,在页面加载实现之后,生成该页面的性能剖析报告,无需人工干预,十分不便。

等个几秒钟报告就生成好了,一眼看去,花花绿绿的,不晓得从何看起?

性能报告的组成

咱们对生成的性能剖析报告做一个简略的面板分类,看起来就很清晰了。

工具栏

性能报告的顶部是一个工具栏(或者叫控制面板),外面有一堆按钮,我这边用得比拟多的是后面三个,其中前两个在指引里曾经介绍过了,第三个是用来革除报告的。

还有两个暗藏的性能也很有用,一个是模仿慢网速的,另一个是模仿慢 CPU 的,对挪动端利用做性能优化可能会用到。

概览面板

工具栏上面是一个概览面板,显示了整个页面加载过程中的 FPS(Frames Per Second,每秒传输帧数),用来评估页面的晦涩度,有大片红色阐明页面可能存在卡顿。

FPS 上面是 CPU 解决各个工作破费的工夫,再往下是网络申请的耗时,概览面板最上面是每一帧的截图。

线程面板

概览面板往下是线程面板,默认开展的是网络申请瀑布图,其余线程的详情都是收起的。

每个线程面板对性能剖析都有价值,而我最罕用的是瀑布图和火焰图,前面会重点剖析这两个图,如何利用这两张图来剖析网站的性能瓶颈。

内存面板

再往下是内存面板,内存面板须要在控制面板中手动关上,它是一个分类的内存占用折线图。

每条折线是一种工作随时间推移的内存占用:

  • JS 堆栈
  • 文档
  • HTML 节点
  • 事件监听
  • GPU 内存

详情面板

最上面是详情面板,首先看到的是一个饼图,这个饼图显示了各种类型工作的占比,这个十分有用,是否一眼看出什么类型的工作是性能瓶颈。

是资源加载还是脚本执行?是页面渲染还是图像绘制?又或者是闲暇工夫太长?

第一步:看饼图

方才介绍 Performance 面板的组成时,提到了 3 个十分有用的性能剖析利器,别离是 详情饼图 申请瀑布图 主线程火焰图

我把这三张图总结成一句话:

在瀑布下用火焰烤饼

这句话也是我本人在做性能剖析和优化时,屡试不爽的小技巧。

详情面板中的饼图用于展现各种类型工作的耗时占比。

次要有以下几种工作:

  • 蓝色是资源加载
  • 黄色是脚本执行
  • 紫色是页面渲染
  • 绿色是图形绘制
  • 红色是闲暇工夫

还是举方才的例子。

从饼图能够看出占比最多的是 脚本执行 闲暇

脚本执行工夫长,咱们大略能够猜想外面可能存在长工作(Long task);

而闲暇占比多可能是期待服务器的响应工夫太长。

饼图能够疾速造成根本的判断,而具体起因则须要剖析瀑布图和火焰图。

第二步:看瀑布图

咱们来看下申请瀑布图,瀑布图和火焰图都是线程面板的一部分,瀑布图的横轴是时间轴,瀑布图上有很多五光十色的色块,这些色块就是 申请块,每种色彩代表一类资源:

  • 蓝色是 HTML 文件
  • 紫色是 CSS 文件
  • 黄色是 JavaScript 文件
  • 绿色是图片
  • 灰色是后盾接口

咱们次要关注那些 长色块,长色块意味着耗时长,可能是性能瓶颈。

还是看下掘金个人主页的瀑布图。

总结瀑布图的特点

咱们先察看这张图有什么特点,图形察看能力,置信大家小学就曾经造就起来了,大抵咱们能够总结出以下比拟显著的特点:

  • 特点一:大瀑布被分成三个小瀑布
  • 特点二:最右边的小瀑布大部分都是黄色色块,两头的小瀑布大部分是灰色色块,最左边的小瀑布大部分是绿色色块
  • 特点三:前两个瀑布之间有一段间距,两头什么色块都没有
  • 特点四:后两个瀑布被一个灰色色块的“尾巴”连在了一起
  • 特点五:顶部有一个超长的灰色色块

相似的特点咱们还能够总结出很多来,然而这些特点阐明了什么呢?是否帮忙咱们定位性能瓶颈呢?

答复这些问题须要咱们对瀑布图以及浏览器原理有很多的意识,咱们一步步来剖析吧。

剖析瀑布图的含意

咱们按从左到右,从上到下的程序进行剖析,最右边有两个色块,一个灰色色块,一个蓝色色块,咱们别离点击这两个色块,在详情面板看下它们的详情信息。

先看灰色色块

咱们有留神到这个申请的启动器(Initiator)是一个 Chrome 插件:chrome://new-tab-page/omnibox.mojom-lite.js

因而咱们不关注,接着看蓝色色块

后面咱们曾经介绍了,蓝色色块代表 HTML 文件,咱们从详情的 Mime Typetext/html也能够验证这一点。

咱们滚动鼠标滚轮,把这个瀑布图放大,看这个蓝色申请块的细节

申请块的组成

通过查看细节图,咱们有了新的发现:

每个申请块都由四局部组成:

  1. 左侧线:代表申请发送之前的工夫(Before Request Sent)
  2. 浅色块:代表申请曾经发送(Request Sent),直到服务器返回第一个字节给浏览器(TTFB, Time to First Byte)
  3. 深色块:服务器返回的内容全副下载到浏览器(Content Download)
  4. 右侧线:期待主线程解决(Waiting for main thread)

这个 HTML 文件是整个网页渲染的终点,胜利申请并下载这个文件,才会有接下来的故事。

这个申请块的浅色块局部占比比拟大,依据后面的介绍,浅色局部代表的是服务器的响应速度,浏览器曾经早早地收回了申请,服务器却迟迟才给回应(第一个字节达到浏览器)。

两头可能是网络慢,也可能是服务器处理速度慢,须要具体排查,毕竟这个 HTML 文件不算大,才 111KBb,却花了 179ms。

比照另外一个文件 layouts.default.js,体积比它大 124KB,申请耗时却比它小一半多,才 74ms。(起初发现这个数据不稳固,这个 HTML 文件应该不至于形成性能瓶颈)

另外所有后续的申请都依赖于这个 HTML,没有它其余申请都不会产生,它是一个阻塞申请,性能必须要有保障。

发现可能的性能瓶颈

咱们持续看左边的申请块,顶部那个超长的灰色块仍然是 Chrome 插件的申请,咱们不论,看上面那一堆黄色的申请块,这些都是 JavaScript 文件。

HTML 文件下载完了之后,就会开始一行一行解析其中的 HTML 标签,遇到设置了谁、src属性的 <script> 标签,就会去下载 src 指定的 JavaScript 脚本文件。

从瀑布图能够看出,一共并行下载了 8 个 JavaScript 文件,它们的域名都是一样的:sf1-scmcdn2-tos.pstatp.com

不是说 Chrome 浏览器对同一个域名,并行的申请数最大是 6 个吗?

不仅仅是 JavaScript 文件,上面还有 3 个同域名的图片资源,也是在并行申请的,也就是说简直同时发动了 11 个申请。

这阐明

掘金的动态资源服务器降级到了 HTTP/2

HTTP/ 2 的多路复用能够实现一个 TCP 连贯同时传输多个资源。

咱们到 Network 面板里去看下这些 JavaScript 的申请详情,果然和咱们猜想的统一,这一点必须给掘金点个赞????

发一个某 86 网站和掘金的比照图,大家感受一下

某 86 网站:

掘金:

尽管前者更像一个瀑布,然而我喜爱后者丝滑般的体验。

咱们再来认真看这 8 个申请,置信粗疏的你肯定发现了一个景象:

  1. 它们的共同点除了方才提到的域名一样外,这些申请块的左右线都很短
  2. 有三个特地长的申请块,别离是 1 /5/8,须要分外关注

申请块的左右线都十分短是一个好景象,阐明没有什么等待时间,所有工夫都用在了传输数据上。

咱们别离点击 1 /5/ 8 申请块看它们的详情

申请块详情
1大小:4KB
耗时:635ms
5大小:90KB
耗时:635ms
8大小:3.9MB
耗时:633ms

这十分奇怪,1/ 5 的资源大小和 8 的不在一个量级上,耗时却比 8 还多。

为了确定这是偶尔的,还是必然的,我又录制了两次这个掘金个人主页的性能报告

这次和预期的基本一致,8 耗时比其余都长,这个 JavaScript 文件 3.9MB,太大了,很可能是性能瓶颈。

其余

让咱们持续往下剖析,黄色 JavaScript 色块上面一共有三种色彩的色块:

  • 紫色:CSS 款式文件
  • 绿色:图片文件
  • 灰色:字体文件(大小为 189KB)

这几个文件体积都不大,并且通过屡次生成性能报告,发现这几个申请耗时都不如第 8 个 JavaScript 文件长,所以初步判断这些申请不形成性能瓶颈。

接着看两头那个瀑布,通过屡次生成性能报告,发现两头瀑布并没有什么特地耗时的申请,不过不论生成多少次报告,有一点是确定的,就是

这三个瀑布之间总是有些空白

这些空白到底阐明了什么呢?

看完火焰图,置信你就会恍然大悟。

第三步:看火焰图

在看正式的火焰图之前,先来看一个瀑布图和火焰图放在一起的成果

看完这张瀑布和火焰的比照图,你肯定看出了一个景象

瀑布图有空白的中央,火焰图就有色彩;

瀑布图有色彩的中央,火焰图就是空白。

But Why?

要答复这个问题须要理解浏览器主线程执行工作的原理,以及火焰图是做什么的,别着急,让咱们一步步来剖析。

火焰图是什么

火焰图也是线程面板的一部分,它代表的是浏览器主线程的工作流:

随着页面的加载,工夫的推移,主线程顺次做了什么事儿

火焰图的横轴是工夫,纵轴是一个个的宏工作。

每个宏工作上面若干个微工作,每个微工作上面有可能有很多子工作,顺次类推。

因为有些工作的嵌套层级深,有些嵌套层级浅,所以出现倒立的火焰状。

每种类型的工作色彩都不一样(无需记忆,有个大抵的印象即可):

  • 解析 HTML Parse HTML:蓝色
  • 解析款式 Parse Stylesheet:蓝色
  • 评估脚本 Evaluate Script:黄色
  • 从新计算款式 Recalculate Style:深紫色
  • 绘制 Paint:深绿色
  • 执行微工作 Microtasks:黄色
  • Ajax 申请 XHR Load:黄色
  • 函数调用 Function Call:黄色
  • 触发定时器 Timer Fired:黄色

还是先大略看下掘金个人主页的火焰图

总结火焰图的特点

而后用咱们小学就学会的 看图找法则 的技能,找到这个图有什么特点,大抵扫一眼,咱们就能总结出至多以下几个特点:

  • 特点一:总的来看两边是空白,两头有三个大火焰
  • 特点二:两边的两个大火焰正好对应瀑布图的两个空白(这就解释了为什么瀑布图的三个小瀑布之间有空白)
  • 特点三:有些宏工作特地长,并且背景色是红色的暗影线(而不是灰色)、右上角有一个红色的小三角形

多花点工夫,可能咱们还能有更多的发现,不过这几个是最不言而喻的。

为了答复这些问题,咱们须要近距离察看下火焰图。

剖析火焰图的含意

既然火焰图代表主线程每个工夫点都在干嘛,那么空白天然就意味着主线程没在干活,那么,它在干嘛呢?

它在期待

期待什么呢?

期待服务器返回一些必要的资源和数据

所以

火焰图的空白处都是浏览器在期待服务器返回数据

寻找长工作

在所有主线程执行的工作中,咱们尤其须要关注的是那些耗时特地长的长工作(Long task),这些长工作的特点后面曾经说了:

背景色是红色的暗影线

右上角有一个红色的小三角形

三个长工作 1s 钟就找到了

剖析长工作

接下来是剖析长工作,找到耗时长的具体模块 / 组件 / 办法。

咱们把最左边最大的那个火焰放大,看看外面到底有些什么机密。

放大之后,咱们很快就发现这个耗时 591ms 的长工作,有 90% 的工夫都破费在了一个叫 init 的办法上,这个办法一共执行了 6 次,其中 3 /4/ 6 耗时尤其长

第 n 个 init 办法详情
3耗时:197ms
4耗时:93ms
6耗时:111ms

这个 init 办法到底是做什么的呢?

可能是挂在 Vue 组件的,会不会是有些组件特地大,外面的逻辑太简单,这里须要掘金的前端给出答案。

再看下右边那个第二大的火焰,同样滚动鼠标滚轮把它放大

咱们发现其中有一个 forEach 循环特地耗时,这个循环如同在计算什么货色,一共花了 150ms。

这个仍然须要看下具体的源码能力找到问题的根因。

通过火焰图发现性能瓶颈的案例

最初给大家分享下我本人之前在 XBoard 看板我的项目中,通过火焰图发现一个依赖库的性能问题。

也是遵循一样的思路:

  1. 找到长工作
  2. 将长工作的火焰图放大
  3. 一层层往下找,直到找到一个耗时长的有名字的办法(现网大部分代码被压缩混同了,看不出名字,开发环境会更不便定位到存在性能问题的办法)
  4. 在火焰图中点击这个办法,看详情面板中 Function 后的链接,点击这个链接,间接跳转到相应文件中的指定办法中
  5. 在源码中搜寻这个办法名字,找到它
  6. 寻找解决方案

过后 XBoard 看板页有一堆长工作,我找了其中的 TOP3

而后将第一个长工作放大,很快就有了播种,我发现其中有一个叫 drawQrCode 的办法耗时比拟长,一共花了 192ms。

接着通过查看详情,发现这是一个依赖库的办法,该依赖库定义了一个 drawQrCode 用来绘制二维码,而这个二维码其实不在看板页面上,而是须要通过鼠标 hover 到某个按钮上才加载进去。

所以过后解决的计划就是提早 drawQrCode 办法的执行,即:

首页加载时,不执行 drawQrCode 办法,当鼠标移到相应按钮上时,才执行。

瀑布图和火焰图的关系

瀑布图和火焰图是互相补充、互相验证的关系。

瀑布图代表浏览器发动向服务器的申请,而后浏览器依据服务器返回的数据,通过脚本执行相应的逻辑和页面的渲染。

当瀑布图有申请块时,阐明浏览器在向服务器申请数据,如果浏览器必须依赖这些数据来做下一步的页面渲染,那么在服务器返回数据之前,很可能浏览器就没事干,而后火焰图上呈现空白,饼图也会呈现闲暇(Idle)。

当浏览器拿到服务器返回的数据时,主线程正在解决这些数据,并渲染页面,因而很可能就没法向服务器发申请,这时瀑布图就会呈现空白。

所以

  1. 发现瀑布图呈现空白,很可能存在长工作,须要找到具体的耗时办法,并进行优化
  2. 发现火焰图呈现空白,很可能是某些后盾接口慢或者存在超大动态资源,须要定位到慢的起因,并想方法优化

小结

本文先给大家简略介绍了如何生成网站的性能剖析报告,以及这份报告的大抵组成;

接着跟大家分享我本人在定位业务性能问题时,常常应用的三步法:在瀑布下用火焰烤饼;

从饼图中咱们能够对网站的性能有一个大抵的意识,从瀑布图疾速地发现慢接口和大资源,而从火焰图中,咱们能够粗疏地洞察到具体哪个模块 / 哪个组件 / 哪个办法可能成为性能瓶颈。

最初给大家举荐 Google 官网的性能评估指南:
https://developers.google.com/web/tools/chrome-devtools/evaluate-performance

退出咱们

咱们是 DevUI 团队,欢送来这里和咱们一起打造优雅高效的人机设计 / 研发体系。招聘邮箱:muyang2@huawei.com。

文 /DevUI Kagol

往期文章举荐

《手把手教你应用 Rollup 打包???? 并公布本人的工具库????》

《大厂是如何用 DevCloud 流水线实现自动化部署 Web 利用的?》

《Web 界面深色模式和主题化开发》

正文完
 0