add: 优化指标和工具
This commit is contained in:
parent
2e84359d65
commit
70fe324a5b
@ -27,7 +27,7 @@
|
||||
- 分享前端性能优化方面的经验和见解
|
||||
### 什么是前端性能优化
|
||||
|
||||
通常来讲,前端性能优化是指:从用户开始访问网站到整个页面完整地展现出来的过程中,通过各种优化策略和优化方法,让页面加在得更快,让用户的操作相应更及时,给用户更好的使用体验。
|
||||
通常来讲,前端性能优化是指:从用户开始访问网站到整个页面完整地展现出来的过程中,通过各种优化策略和优化方法,让页面加载得更快,让用户的操作相应更及时,给用户更好的使用体验。
|
||||
|
||||
### 学习前端性能优化的难点
|
||||
|
||||
@ -37,18 +37,19 @@
|
||||
|
||||
**大家都知道性能优化很重要,但是落实到具体,怎么去优化**?这就需要我们深入去了解前端技术背后的原理,才能总结出相应的优化方案,而且需要多年的经验积累。
|
||||
|
||||
当领导问:“为什么网页访问这么慢?”我们不能只是回答“网络不好”这么简单,
|
||||
|
||||
每个程序员如果想要成长,就不能回避“性能优化”这个话题。很多人写了多年的代码,一直在构建样式、写业务逻辑。但是平凡的程序员之路,何时才是尽头呢?怎么才能从团队中脱颖而出呢?如何区分出平凡程序员/大牛程序员/架构师的分水岭呢?
|
||||
当领导问:“为什么网页访问这么慢?”我们不能只是回答“网络不好”这么简单,每个程序员如果想要成长,就不能回避“性能优化”这个话题。很多人写了多年的代码,一直在构建样式、写业务逻辑。但是平凡的程序员之路,何时才是尽头呢?怎么才能从团队中脱颖而出呢?如何区分出平凡程序员/大牛程序员/架构师的分水岭呢?
|
||||
|
||||
公司评价一个程序员的价值,不是加班越多越好,也不是代码写得越多越好,而是看他是否能解决其他人解决不了的一些技术难题或者瓶颈。
|
||||
|
||||
只要产品上线了,随着业务规模量和用户访问量的扩大,性能优化就是不可回避的话题。在遇到性能问题时,有些人的解决办法是:用一些粗糙的手段把问题绕过去,但却给后面的人埋下了坑。
|
||||
|
||||
掌握正确和主流的优化方案,是非常重要的。我们需要学习一些主流的前端性能优化技术方案,掌握性能优化技术,提升Web性能;进而到达前端技术圈的上游,提高自己的核心竞争力。
|
||||
|
||||
职场晋升时,我们也要想一想:大部分人都在写业务代码,和别人相比,我的核心竞争力在哪里?除了技术深度、综合素质之外,还有其他的吗?性能优化,绝对是不能忽视的一方面。而且它是贯穿于开发和维护的的全过程。
|
||||
### 性能优化的意义
|
||||
|
||||
**高性能**可以带来更高的**用户参与度**、**用户留存**,进而带来更高的**转化率**和**SEO排名**,最终带来更高的**业务收益**。
|
||||
|
||||
1、随着互联网的发展,**网页的内容越来越丰富,功能越来越强大,页面也越做越漂亮**;带来的问题是,访问速度和体验会收到影响。只有对网站进行持续不断的优化,才能保证网页的访问速度可以跟得上用户体验的需求。
|
||||
|
||||
2、**高性能**可以带来更高的**用户参与度**、**用户留存**,进而带来更高的**转化率**和**SEO排名**,更好的**用户体验**,最终带来更高的**业务收益**。
|
||||
|
||||
随着时间的推移,如果一个网站由于各种原因导致心梗越来越差,以至于用户每打开一个页面都要等待很长时间,甚至出现加载失败的情况,那么,不仅新用户不会沉淀下来,老用户也会纷纷离去,最终导致产品的加速衰败。
|
||||
|
||||
@ -56,6 +57,22 @@
|
||||
|
||||
正因为如此,我们才需要通过性能优化的技巧,并结合其他的技术手段来不断提高网站和App的用户体验,从而助力公司的业务增长;同时,我们也可以借此提升自己的技术实力,这对个人的职业成长也会以后很大的帮助。
|
||||
|
||||
3、只要产品上线了,随着**业务规模量和用户访问量的扩大**,性能优化就是不可回避的话题。在遇到性能问题时,有些人的解决办法是:用一些粗糙的手段把问题绕过去,但却给后面的人埋下了坑。有些人说出一句万能的话:
|
||||
|
||||
|
||||
![](http://img.smyhvae.com/20210115-2150.jpg)
|
||||
|
||||
### 相关案例
|
||||
|
||||
- [Amazon发现每100ms延迟导致1%的销量损失](https://www.gigaspaces.com/blog/amazon-found-every-100ms-of-latency-cost-them-1-in-sales/)。
|
||||
|
||||
- 歌地图首页文件从100KB减少到70KB,流量在第一周涨了10%,在接下来的三周涨了25%。
|
||||
|
||||
- 腾讯根据长期数据监控发现,页面一秒钟延迟会造成页面访问量下降9.4%,跳出率增加8.3%,转化率下降3.5%。
|
||||
|
||||
|
||||
|
||||
|
||||
### 优化是在做什么
|
||||
|
||||
![](http://img.smyhvae.com/20210115-1507.png)
|
||||
@ -96,6 +113,26 @@
|
||||
|
||||
- 具备Web开发实战经验。
|
||||
|
||||
### 寻找性能瓶颈
|
||||
|
||||
- 了解性能指标,多快才算快。
|
||||
|
||||
- 利用测量工具和API
|
||||
|
||||
- 优化问题,重新测量。持续迭代。
|
||||
|
||||
### 移动端挑战多
|
||||
|
||||
- 移动端的硬件不如PC端,且网络不稳定。
|
||||
|
||||
- 屏幕尺寸和交互方式都是挑战。
|
||||
|
||||
- 移动端用户更佳缺乏耐心。而且,很多用户是利用碎片化时间访问网页。数据参考: **>3秒**的加载时间,导致 53%的跳出率(bounce rate)。
|
||||
|
||||
- 持续增长的移动端用户和电商业务。现在很多事情都是在移动端做的。
|
||||
|
||||
|
||||
|
||||
|
||||
## 前端性能优化全过程
|
||||
### 1、静态资源优化
|
||||
|
690
13-前端面试/02-前端性能优化/01-性能优化的指标和工具.md
Normal file
690
13-前端面试/02-前端性能优化/01-性能优化的指标和工具.md
Normal file
@ -0,0 +1,690 @@
|
||||
|
||||
|
||||
## 性能指标和优化目标之:加载
|
||||
|
||||
性能指标:我们在性能优化过程中可以参考的标准。这些标准都是业界或者前人总结出来的指导性经验。我们可以参考这些指标,去指导我们自己的优化。
|
||||
|
||||
### 打开网站的初体验
|
||||
|
||||
我们以淘宝网站为例。
|
||||
|
||||
![](http://img.smyhvae.com/20210115_1601.png)
|
||||
|
||||
上图中,鼠标长按刷新图标,松开鼠标后,会弹出三个选项,我们选择最后一个选项“清空缓存并硬性重新加载”。PS:只有淘宝等少数网站有这个选项,其他很多网站都没有。
|
||||
|
||||
![](https://img.smyhvae.com/20210115_1617.png)
|
||||
|
||||
上图中,打开 chrome 调试工具,点开「设置」icon,下面的四个选项中,除了“Group by frame”之外,其他的三个选项都可以勾选上。
|
||||
|
||||
我们可以看到淘宝网站的一些指标:
|
||||
|
||||
- 资源量是 1.3M。
|
||||
|
||||
- DOM加载完成时间(DOMContentLoaded):511ms。这是一个很关键的指标。
|
||||
|
||||
- 其他资源的总加载时间是 1.05秒。
|
||||
|
||||
### 保存快照
|
||||
|
||||
network里的信息挺多,我们可以将其保存下来,留着以后做分析、做对照。
|
||||
|
||||
![](http://img.smyhvae.com/20210115-1723.png)
|
||||
|
||||
如上图所示,我们可以在 network 的空白处右键,选择“Save all as HAR with content”,讲 network 信息保存为 HAR文件格式。
|
||||
|
||||
HAR是一种标准的Web格式,用户保存性能测试的结果。里面的数据是json格式。
|
||||
|
||||
我们可以使用第三方的 HAR 分析软件来打开 HAR 文件,比如:
|
||||
|
||||
- [Google 提供的 HAR 分析器](https://toolbox.googleapps.com/apps/har_analyzer/?lang=zh-CN)
|
||||
|
||||
- Fiddler 抓包工具
|
||||
|
||||
注意,HAR 文件包含了一些敏感信息:
|
||||
|
||||
![](http://img.smyhvae.com/20210115-1733.png)
|
||||
|
||||
|
||||
### 瀑布图 Waterfall
|
||||
|
||||
![](http://img.smyhvae.com/20210115_1618.png)
|
||||
|
||||
瀑布图可以非常直观地把网站的加载过程,用自上而下的方式表达出来,就像瀑布一样。
|
||||
|
||||
瀑布图有两中解读方式:一种是横向看,一种是纵向看。
|
||||
|
||||
**1、横向看**:
|
||||
|
||||
横向看的是具体的资源,每一行代表某个资源的加载信息。里面有一些色块来表达加载的过程,每个块的颜色不同。也就是说资源的下载不是单一的过程,而是经历了很多环节。
|
||||
|
||||
为了了解资源的具体加载过程,我们把鼠标悬浮在第一个资源的色块上,可以看见一个详情列表:
|
||||
|
||||
![](http://img.smyhvae.com/20210115_1632.png)
|
||||
|
||||
(1)等待:
|
||||
|
||||
- Queueing:排队。浏览器会对资源的请求做优先级排序。
|
||||
|
||||
(2)连接:
|
||||
|
||||
- DNS Lookup:DNS域名解析。每个资源都有域名,对域名做DNS解析,然后找到对应服务器的IP地址。
|
||||
|
||||
- initial connection:客户端和服务器之间建立TCP连接。
|
||||
|
||||
- SSL证书:该网站为了保证安全性,使用了 https 协议,启用了SSL证书。启用之后,需要做安全认证(SSL协商),这个过程也会耗时。到这里位置,我们可以看到,在请求资源之前,有很多的前置步骤。
|
||||
|
||||
(3)请求和响应:
|
||||
|
||||
- Request sent:到这一步,开始真正地请求资源。
|
||||
|
||||
- Waiting(**TTFB**):资源从请求到响应,有一个等待的时间。
|
||||
|
||||
- Content Download:资源的下载时间。如果值月太大,表明下载时间太长。有些资源会造成阻塞,导致网页的整体加载时间过长,让用户等待太久。
|
||||
|
||||
|
||||
**TTFB** 是一个很重要的指标,它表示的是:请求发出到响应,到底要经历多久。TTFB 可以给我们一个很直观的感受,我们网站的请求和响应到底是快还是慢,很大程度上是由 TTFB 决定。
|
||||
|
||||
影响 TTFB 的因素是什么呢?比如:
|
||||
|
||||
- 后台的处理能力的响应速度。
|
||||
|
||||
- 网络状况:是否有网络延迟。
|
||||
|
||||
**2、纵向看**:(主要看两点)
|
||||
|
||||
(1)看资源与资源之间的联系:如果发生阻塞,说明资源可能是串行地按顺序加载。可以按需要适当调整为并行。
|
||||
|
||||
(2)看关键的时间节点。Waterfall 中有**两根时间线**:蓝色的线是 DOM 加载完成的时间,红色的线是所有资源加载完成的时间。
|
||||
|
||||
|
||||
|
||||
## 性能指标和优化目标之:交互
|
||||
|
||||
上面的内容讲的是**加载**的性能,还有一个需要关注的性能指标是**交互**。也就是网站加载完成后,用户真正开始使用这个网站过程中的的交互体验。
|
||||
|
||||
关于交互体验的性能,我们需要关注的是:
|
||||
|
||||
- 交互动作的响应时间要短:比如点击按钮后的弹窗、在搜索框里输入关键字后的搜索结果。
|
||||
|
||||
- 页面滚动要流畅:可以查看 FPS 帧率。
|
||||
|
||||
- 异步请求接口的完成时间要短:比如关注/取关主播的响应、领取红包的操作。
|
||||
|
||||
### FPS帧率、FRS
|
||||
|
||||
这里首先科普两个概念:
|
||||
|
||||
- 刷新率:显示器每秒有多少帧画面。大多数显示器的刷新率是60帧/秒。
|
||||
|
||||
- 帧率(FPS:frames per second):视频或者动画的内容本身,每秒有多少帧。
|
||||
|
||||
上面的两个参数中,人眼最终看到的效果,是以最低的参数为准的。
|
||||
|
||||
持续滑动的过程中,如果页面输出到显示器的帧率低于60帧/秒,则人眼会感觉卡顿。
|
||||
|
||||
那么,在浏览器中如何实时显示内容的 FPS 参数呢?打开浏览器的控制台后,按住快捷键「Cmd + Shift + P」,然后输入 `frame`,选择`Show frames per second(FPS) meter`。如下:
|
||||
|
||||
![](http://img.smyhvae.com/20210115-1930.png)
|
||||
|
||||
![](http://img.smyhvae.com/20210115-2146.png)
|
||||
|
||||
**温馨提示**:
|
||||
|
||||
从 2020年7月起,chrome 官方已经取消了 fps参数的显示,改为了 [FRS](https://twitter.com/addyosmani/status/1281483292026400768):
|
||||
|
||||
![](http://img.smyhvae.com/20210115-2006.png)
|
||||
|
||||
FRS参数观察的是丢帧率:
|
||||
|
||||
![](http://img.smyhvae.com/20210115-2010.png)
|
||||
|
||||
|
||||
Chrome官方给我们提供了下面这个网站,用于观察 FPS 效果:
|
||||
|
||||
- <http://googlesamples.github.io/web-fundamentals/tools/chrome-devtools/rendering-tools/forcedsync.html>
|
||||
|
||||
我们可以借助第三方的 [chrome 插件]()来查看 fps参数。
|
||||
|
||||
## 用 RAIL 模型测量性能
|
||||
|
||||
RAIL 模型是Google提出的可以量化性能的测量**标准**。我们做性能优化时,要尽可能到这个标准。
|
||||
|
||||
在做性能优化的时候,我们需要有人告诉我们:做到多好才算好?有没有一些通用的标准?而 RAIL 模型 可以给我们带来量化的指标。
|
||||
|
||||
**RAIL 模型包括四个方面**:
|
||||
|
||||
![](http://img.smyhvae.com/20210115-2027.png)
|
||||
|
||||
- Response:响应
|
||||
|
||||
- Animation:动画
|
||||
|
||||
- Idle:空闲时间
|
||||
|
||||
- load:加载
|
||||
|
||||
参考链接:
|
||||
|
||||
- [[Web翻译]用RAIL模型测量性能](https://juejin.cn/post/6872474167543857165)
|
||||
|
||||
- <https://web.dev/rail/>
|
||||
|
||||
**RAIL 的目标**:
|
||||
|
||||
- 让良好的用户体验成为性能优化的目标
|
||||
|
||||
接下来,我们再看看看 RAIL 的评估标准。
|
||||
|
||||
### 1、响应
|
||||
|
||||
**目标**:处理用户发起的响应,应该在 50ms 内完成。
|
||||
|
||||
**准则**:
|
||||
|
||||
- 在50毫秒内处理用户输入事件。这适用于大多数输入,如点击按钮、切换表单控件或启动动画。这不适用于触摸拖动或滚动。
|
||||
|
||||
- 对于需要超过50毫秒才能完成的操作,需要提供反馈。
|
||||
|
||||
|
||||
![](http://img.smyhvae.com/20210115-2039.png)
|
||||
|
||||
如上图所示,Google经过大量研究发现,用户能够接受的最高延时是100ms。所以,从用户发起交互请求(输入任务)后,前端最好能在100ms内给出反馈。
|
||||
|
||||
**但是我们的预算只有50毫秒**。因为应用程序在接收到输入任务的时候,不一定会马上着手处理,它可能还有其他工作正在进行,这意味着当前的输入任务可能需要排队50ms左右。所以我们真正能处理这个请求的时间,并没有100ms。
|
||||
|
||||
|
||||
### 2、动画
|
||||
|
||||
**目标**:在10毫秒或更短的时间内制作出动画中的每一帧。(即:100帧/秒。)
|
||||
|
||||
我们知道,当动画的帧率是 >= 60帧/秒 的时候,人眼才不会觉得卡顿。此时的理论值为 1000毫秒/60帧 = 16.6 毫秒/帧。
|
||||
|
||||
10毫秒和16毫秒之间,隔了6秒。这6秒是什么呢?因为浏览器需要大约6毫秒的时间来渲染每一帧,所以,每一帧的准则建议是10毫秒,而不是 16.6毫秒。
|
||||
|
||||
假设动画本身是60帧/秒,那么,最终渲染出来的效果可能只有 45帧/秒。
|
||||
|
||||
**广义的动画**:
|
||||
|
||||
动画不仅仅是花哨的UI效果。每一种交互都被认为是动画。比如:
|
||||
|
||||
- 视觉动画
|
||||
|
||||
- 滚动
|
||||
|
||||
- 拖动、平移元素、放大图片等。
|
||||
|
||||
### 3、空闲时间
|
||||
|
||||
**目标**:最大化闲置时间,增加页面在50毫秒内响应用户输入的几率。
|
||||
|
||||
这个空闲时间,是和上面的第一点“响应”是结合在一起的。只有空闲足够多,当用户的交互来的时候,我们才能有足够的时间进行处理。
|
||||
|
||||
**准则**:
|
||||
|
||||
- 利用空闲时间做延迟加载。例如,页面在初始化的时候,尽可能少的加载数据,然后利用空闲时间加载其余部分。
|
||||
|
||||
- 在空闲时间内处理任务,时间不能超过50毫秒。否则,就阻塞了用户做其他的输入请求,导致卡顿。
|
||||
|
||||
- 如果用户在闲置时间工作期间与页面进行交互,那么这个交互应始终处于最高优先级,并中断闲置时间工作。
|
||||
|
||||
### 4、加载
|
||||
|
||||
**目标**:在5秒或更短的时间内加载页面并可以交互。
|
||||
|
||||
**准则**:
|
||||
|
||||
- 这里的5秒包括:加载、解析、渲染,并确保用户可以交互。
|
||||
|
||||
- 加载的过程中,可以使用loading框、进度条、骨架屏等方式缓解用户焦虑。
|
||||
|
||||
## 使用Chrome DevTools 分析性能
|
||||
|
||||
大家平时在用 Chrome DevTools 的时候,一般使用来开发调试、查看 DOM、css、接口请求等,但其实,这个工具非常强大。
|
||||
|
||||
### size:文件大小分析
|
||||
|
||||
![](http://img.smyhvae.com/20210116-0946.png)
|
||||
|
||||
可以把size从到小排序,看看哪个资源的文件较大。
|
||||
|
||||
另外,上图中的横线处说明:该文件在网络传输的时候会做压缩(125kb),拿到资源之后再解压还原(526kb)。
|
||||
|
||||
|
||||
|
||||
### preformance:性能表现
|
||||
|
||||
![](http://img.smyhvae.com/20210116-0959.png)
|
||||
|
||||
preformance的两个作用:
|
||||
|
||||
- Record button:记录页面加载、用户交互等全过程,直到我们手动点击停止按钮。
|
||||
- Reload button:记录页面从刷新到资源加载完成的过程。会自动停止记录。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
参数解读:
|
||||
|
||||
- Timing:关键的时间节点。
|
||||
|
||||
- Main:主线程做了哪些任务,以及调用关系。
|
||||
|
||||
Timing参数中,尤其注意看`DCL`(DOMContentLoaded),即DOM加载完成的时间节点。我们可以通过`Main`参数看看DOM在加载完成之前,都做了些什么事情。很有可能就是这些事情导致 `DCL`的时间过晚。
|
||||
|
||||
我们可以翻到`Main`里的最后一行(即最终调用的位置),往往这个位置就是我们自己写的代码。
|
||||
|
||||
|
||||
|
||||
### Diable cache
|
||||
|
||||
![](http://img.smyhvae.com/20210116-1014.png)
|
||||
|
||||
上图中的`Diable cache`是一个很重要的设置选项。
|
||||
|
||||
勾选`Diable cache`:
|
||||
|
||||
- 不走缓存,相当于页面初次访问。
|
||||
- 如果你希望改的代码立即生效,就一定要勾选上。
|
||||
|
||||
不勾选`Diable cache`:
|
||||
|
||||
- 走缓存,相当于页面二次、三次访问。
|
||||
- 很多时候,我们需要关心用户在第二次、第三次访问时候,他的访问速度如何、性能如何、我们设置的缓存有没有生效。此时就不要勾选上。
|
||||
|
||||
### 模拟网络情况
|
||||
|
||||
![](http://img.smyhvae.com/20210116-1023.png)
|
||||
|
||||
模拟网络状况(自定义参数):
|
||||
|
||||
![](http://img.smyhvae.com/20210116-1026.png)
|
||||
|
||||
|
||||
|
||||
### Performance monitor
|
||||
|
||||
|
||||
|
||||
![](http://img.smyhvae.com/20210116-1032.png)
|
||||
|
||||
|
||||
|
||||
### 快捷键ESC
|
||||
|
||||
按住快捷键ESC,会列出其他常用的功能菜单:
|
||||
|
||||
![](http://img.smyhvae.com/20210116-1028.png)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 使用 WebPageTest 评估网站性能
|
||||
|
||||
现在主流的性能测量工具:
|
||||
|
||||
- Chrome DevTools:开发调试、分析性能。
|
||||
|
||||
- Lighthouse 网站整体质量评估。
|
||||
|
||||
- WebPageTest:给网站提供多个地点的测试,以及全面的性能报告。
|
||||
|
||||
这一段,我们先来讲一讲 WebPageTest。
|
||||
|
||||
程序员经常说的有句话是:“我这儿能打开啊。我这儿不报错呀。”大家应该都懂这个梗,这就是为什么,我们要借助第三方的测试工具,而不仅仅只是自己电脑上访问正常就ok了。
|
||||
|
||||
我们需要借助 WebPageTest 这样的第三方测试工具,去模拟各种用户的真实场景。
|
||||
|
||||
|
||||
### WebPageTest 使用
|
||||
|
||||
网址:<https://www.webpagetest.org>
|
||||
|
||||
![](http://img.smyhvae.com/20210115-2203.png)
|
||||
|
||||
|
||||
WebPageTest 在世界各地提供了非常多的服务器,在每个服务器上部署了不同的浏览器,可以让我们有针对性的做测试。如果你做的是一款国际化网站,那更有必要使用一下了。
|
||||
|
||||
我们以JD网站举例:
|
||||
|
||||
![](http://img.smyhvae.com/20210115-2225.png)
|
||||
|
||||
按照上面的选项配置完成后,点击右侧的「Start Test」即可开始测试。然后等待:
|
||||
|
||||
![](http://img.smyhvae.com/20210115-2226.png)
|
||||
|
||||
|
||||
### WebPageTest 报告分析
|
||||
|
||||
淘宝网站性能测试报告:
|
||||
|
||||
- 2021年1月:https://www.webpagetest.org/result/210115_DiCB_f1344d732760365151755e89765b2d37/
|
||||
|
||||
- 2020年6月:https://webpagetest.org/result/200616_JK_78eebda338285ffe0c2e154ca5032839/
|
||||
|
||||
JD网站性能测试报告:
|
||||
|
||||
- 2021年1月:https://www.webpagetest.org/result/210115_DiGT_8d7370e91230b7d077e40b7aafb485a5/
|
||||
|
||||
拿到 WebPageTest 报告之后,我们来看看报告里的几个重点指标。
|
||||
|
||||
1、摘要里的参数:
|
||||
|
||||
- First Byte:第一个请求的响应时间。可以反映后台的处理能力,以及网络回路的情况。
|
||||
|
||||
- Start Render:从白屏到首次渲染的时间。
|
||||
|
||||
- Speed Index:速度指数。
|
||||
|
||||
- **Total Blocking Time**:页面被阻塞,导致用户不能交互的累计时间。
|
||||
|
||||
2、详情里的参数:**First View**。
|
||||
|
||||
First View展示的是:首次访问时,总的加载时间。这里面提供的瀑布图,比 chrome DevTools里提供的更为详细。
|
||||
|
||||
点击进入 First View 的详情之后,可以看到:所有的资源请求,都会在这里列出来。
|
||||
|
||||
- page is Interactive:页面在加载的过程中,大部分时间段,用户都是可以交互的。这是非常有用的一个指标。
|
||||
|
||||
- Brower Main thread:浏览器主线程的占用情况。可以看看空闲的时间多不多。
|
||||
|
||||
- CPU Utilization:CPU的使用情况。
|
||||
|
||||
- 多张图片的资源请求。
|
||||
|
||||
上图中,我们可以看到:多张图片的开始请求时间都是相同的。也就是说,如果让资源做**并行加载**,我们就可以加大地减少加载时间,最终所消耗的时间就由最大的图片来决定。这是一个很好的优化技巧,至于具体是怎么实现的,可以自行了解。
|
||||
|
||||
|
||||
我们看到,有一部分的请求,被高亮出来了:
|
||||
|
||||
![](http://img.smyhvae.com/20210115-2250.png)
|
||||
|
||||
上面这张图的意思是:302表示重定向,也就是说,这个资源已经不在原来请求的位置了,需要重定向才能找到真实的位置。这个地方其实可以做一个优化:
|
||||
|
||||
> 不需要去访问之前的无效的资源,可以直接去访问重定向后的那个资源。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### 局域网部署 WebPageTest 工具
|
||||
|
||||
如果我们开发的页面,还没有上线,公网则无法访问。这个时候我们也想通过WebPageTest看看网站的性能,那要怎么办呢?
|
||||
|
||||
我们可以在局域网部署 WebPageTest 工具,具体方法可自行研究。
|
||||
|
||||
|
||||
|
||||
## 使用LightHouse分析性能
|
||||
|
||||
我们之所以使用不同的性能测量工具,是因为他们都有不同的特点。WebPageTest 可以生成详细的性能测试报告;而 接下来要讲的 lighthouse 不仅可以帮我们生成测试报告,还可以给出一些针对性的优化建议。
|
||||
|
||||
### Lighthouse 介绍
|
||||
|
||||
![](http://img.smyhvae.com/20210115-1739.png)
|
||||
|
||||
lighthouse 是 chrome 浏览器的一个性能测量工具。我们先来看看它的性能指标,至于它具体使用,后续的内容再详细介绍。
|
||||
|
||||
|
||||
淘宝跑分举例:
|
||||
|
||||
|
||||
![](http://img.smyhvae.com/20210115-1758.png)
|
||||
|
||||
京东跑分举例:
|
||||
|
||||
![](http://img.smyhvae.com/20210115-1759.png)
|
||||
|
||||
|
||||
Lighthouse 跑分里,最重要的两个指标如下:
|
||||
|
||||
- First Contentful Paint:从白屏到第一次出现内容的时间。我们可以看到,上面提供了一些加载过程的截图,10屏里如果只有1到2屏是白屏,说明体验还是可以的。
|
||||
|
||||
- Speed Index:速度指数。
|
||||
|
||||
我们不需要关心这个指数是怎么来的,因为背后涉及一套很复杂的公式,我们暂时只需关注这个数值。
|
||||
|
||||
Speed Index 标准为4秒(超过4秒算比较慢的),我们测的淘宝的 speed index 是0.5s,很快了。但我们要结合网站本身的性质来权衡。并不是分数越高性能越高,比如百度这样的网站,页面上的内容很少,测出来的分数肯定很完美。而淘宝需要展示很多内容给用户看。所以,这个指标只是一个指导作用,并不一定能够达到最优的数值。
|
||||
|
||||
另外,Lighthouse 还会给出一些优化建议:
|
||||
|
||||
- Opportunities:优化建议。
|
||||
|
||||
- Diagnostics:问题诊断。
|
||||
|
||||
- Passed audits:表示这部分没有问题。
|
||||
|
||||
### 举例:确认某个JS 是否必须在首屏加载
|
||||
|
||||
就拿B站来举例,来看看它的lighthouse报告:
|
||||
|
||||
|
||||
![](http://img.smyhvae.com/20210116_0107.png)
|
||||
|
||||
上图中给出了一个优化建议:有些JS文件不是首屏加载必须的。
|
||||
|
||||
![](http://img.smyhvae.com/20210116_0108.png)
|
||||
|
||||
我们随便拿一个JS文件来测试(比如上图中,Header标签里的JS文件)。做法如下:
|
||||
|
||||
![](http://img.smyhvae.com/20210116-0901.png)
|
||||
|
||||
如上图所示,在 chrome 控制台输入快捷键「Cmd + Shift + P」,然后输入文本`block`,选择`Show Network request blocking`:
|
||||
|
||||
![](http://img.smyhvae.com/20210116-0903.png)
|
||||
|
||||
按照上面的步骤添加规则,点击add后,效果如下:
|
||||
|
||||
![](http://img.smyhvae.com/20210116-0904.png)
|
||||
|
||||
|
||||
然后,我们切换到控制台的 network面板,并刷新页面:
|
||||
|
||||
![](http://img.smyhvae.com/20210116-0905.png)
|
||||
|
||||
然后观察这个js资源是不是首屏加载所必须的。但我们也不能就此定论说这个资源一定可以延迟加载,也许它就是想让页面在一开始loading的时候就捕获日志。
|
||||
|
||||
对于我们自己的网站,这个资源是首屏加载必须的吗?一定要在第一时间加载吗?需要根据特定的业务做衡量。
|
||||
|
||||
|
||||
### 通过npm运行 Lighthouse工具
|
||||
|
||||
```bash
|
||||
# 安装
|
||||
npm install -g lighthouse
|
||||
|
||||
# 执行
|
||||
lighthouse https://www.jd.com
|
||||
|
||||
# 输出性能检测报告
|
||||
Generating results...
|
||||
html output witten to /Users/smyh/Documents/wpt-mac-agent/www.jd.com._2021-01-16_09-00-00.html
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 实时动态测量性能的API
|
||||
|
||||
Chrome DevTools能够检测各种性能参数,其实也是调用了一些性能相关的标准API。我们自己也可以直接在代码里调用这些api。
|
||||
|
||||
通过 `performance`对象提供的API,我们可以实时的、精细化、自定义测量性能,获取相应的参数。也可以把这些性能参数,打印到控制台,或者实时上报给后台监控系统。
|
||||
|
||||
### performance:获取常见性能参数
|
||||
|
||||
常见性能参数,计算公式如下:
|
||||
|
||||
> 时间戳1减去时间戳2,得到的差值,就是我们想要看到的耗时。
|
||||
|
||||
- DNS 解析耗时: domainLookupEnd - domainLookupStart
|
||||
|
||||
- TCP 连接耗时: connectEnd - connectStart
|
||||
|
||||
- SSL 安全连接耗时: connectEnd - secureConnectionStart
|
||||
|
||||
- 网络请求耗时 (TTFB): responseStart - requestStart。
|
||||
|
||||
- 数据传输耗时: responseEnd - responseStart
|
||||
|
||||
- DOM 解析耗时: domInteractive - responseEnd
|
||||
|
||||
- 资源加载耗时: loadEventStart - domContentLoadedEventEnd
|
||||
|
||||
- First Byte时间: responseStart - domainLookupStart
|
||||
|
||||
- 白屏时间: responseEnd - fetchStart
|
||||
|
||||
- 首次可交互时间(**TTI**): domInteractive - fetchStart
|
||||
|
||||
- DOM Ready 时间: domContentLoadEventEnd - fetchStart
|
||||
|
||||
- 页面完全加载时间: loadEventStart - fetchStart
|
||||
|
||||
- http 头部大小: transferSize - encodedBodySize
|
||||
|
||||
- 重定向次数:performance.navigation.redirectCount
|
||||
|
||||
- 重定向耗时: redirectEnd - redirectStart
|
||||
|
||||
比如说,如果我们想要获取 TTI参数,代码可以这样写:
|
||||
|
||||
```javascript
|
||||
// 计算一些关键的性能指标
|
||||
window.addEventListener('load', (event) => {
|
||||
// Time to Interactive
|
||||
let timing = performance.getEntriesByType('navigation')[0];
|
||||
console.log(timing.domInteractive);
|
||||
console.log(timing.fetchStart);
|
||||
|
||||
let diff = timing.domInteractive - timing.fetchStart;
|
||||
console.log("TTI: " + diff); // 打印 TTI 参数
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 观察长任务
|
||||
|
||||
```javascript
|
||||
const observer = new PerformanceObserver((list) => {
|
||||
for (const entry of list.getEntries()) {
|
||||
console.log(entry)
|
||||
}
|
||||
})
|
||||
|
||||
observer.observe({entryTypes: ['longtask']})
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 页面可见性的状态监听
|
||||
|
||||
使用场景举例:
|
||||
|
||||
- 比如说,我们正在做一个视频网站(或者游戏页面)。如果用户当前没有在看这个视频,而是切换别的页面了。此时,我们可以对视频做节流等处理,避免造成性能的浪费。等用户再回到当前页面之后,再恢复之前的状态。
|
||||
- 当设备进入待机模式时(用户按下电源键关闭屏幕),网站想要关闭设备声音。
|
||||
|
||||
针对这种场景,我们可以使用`visibilitychange`进行监听:
|
||||
|
||||
```javascript
|
||||
// 见面可见性的状态监听
|
||||
let vEvent = 'visibilitychange';
|
||||
if (document.webkitHidden != undefined) {
|
||||
// webkit prefix detected
|
||||
vEvent = 'webkitvisibilitychange';
|
||||
}
|
||||
|
||||
function visibilityChanged() {
|
||||
if (document.hidden || document.webkitHidden) {
|
||||
console.log("Web page is hidden.")
|
||||
} else {
|
||||
console.log("Web page is visible.")
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener(vEvent, visibilityChanged, false);
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 网络状况监听
|
||||
|
||||
使用场景举例:
|
||||
|
||||
- 高清图片按需加载:如果用户的网络条件较好,就加载高清图片资源;如果网络条件不好,就加载文件较小的图片资源。
|
||||
|
||||
代码举例:
|
||||
|
||||
```javascript
|
||||
var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
|
||||
|
||||
var type = connection.effectiveType;
|
||||
|
||||
function updateConnectionStatus() {
|
||||
// type是之前的网络状态,connection.effectiveType是当前最新的网络状态
|
||||
console.log("Connection type changed from " + type + " to " + connection.effectiveType);
|
||||
|
||||
type = connection.effectiveType;
|
||||
}
|
||||
|
||||
connection.addEventListener('change', updateConnectionStatus);
|
||||
```
|
||||
|
||||
打印结果举例:
|
||||
|
||||
```
|
||||
Connection type changed from 4g to 3g
|
||||
```
|
||||
|
||||
### 检测元素的可见状态,方便做曝光埋点
|
||||
|
||||
我们可以通过`IntersectionObserver:`这个API来检测元素的可见状态:
|
||||
|
||||
![](http://img.smyhvae.com/20210116-1119.png)
|
||||
|
||||
|
||||
|
||||
做曝光上报的埋点:判断某个DOM(或者某个楼层)是否出现在视窗中,出现了就收集数据上报给服务端。
|
||||
|
||||
本质就是要计算某一元素和另一元素(视窗)的相对位置/相对可视状态,然后进行一些操作(一般是上报给服务端)。
|
||||
|
||||
参考:
|
||||
|
||||
- [前端埋点之曝光实现](https://cnodejs.org/topic/5e0a0edb0696c446bf650dec)
|
||||
- [点击埋点和曝光卖点的封装](https://github.com/Hugohui/vueTrackSdk)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
```
|
Loading…
Reference in New Issue
Block a user