Loading...
墨滴

白色座头鲸

2021/03/13  阅读:7  主题:全栈蓝

性能优化3

性能优化3

第二节讲到了性能指标的出处,以及标准的粗略解读,本章就要开始进入正题。讲解各项指标。

通过第一章,我们知道一个网页要开始展现出来,需要先从服务端取得文档(html文件),第二章我们知道了,文档属于一种资源,而资源加载的过程可以通过Resource Timing看到,宏观上分为三大类:

1.文档加载相关 2.内容呈现相关 3.交互响应相关

一 文档加载相关

文档加载过程时间线如图,这里主要介绍三个指标:TTFB、DCL 和 Load 时间。

1.1 TTFB(Time to First Byte)

定义:浏览器从请求页面开始到接收第一字节的时间,这个时间段内包括 DNS 查找、TCP 连接和 SSL 连接。

1.2 DomContentLoaded(DCL)

定义:DomContentLoaded 事件触发的时间。当 HTML 文档被完全加载和解析完成之后,DOMContentLoaded事件被触发,而无需等待样式表、图像和子框架加载完成。

1.3 Load(L)

定义:onLoad 事件触发的时间。页面所有资源都加载完毕后(比如图片,CSS),onLoad 事件才被触发。

二 内容呈现相关

2.1 First Paint(FP)

定义:第一个像素绘制的时间,不包括默认的背景,感觉没什么用

测量方式不用说了吧,performanceAPI提供。

2.2 First Contentful Paint(FCP)

定义:首次内容绘制,绘制内容是指来自的DOM内容,可以是图像,文字,svg,canvas等等,

测量方式:PerformanceApi

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntriesByName('first-contentful-paint')) {
    console.log('FCP candidate:', entry.startTime, entry);
  }
}).observe({type'paint'bufferedtrue});

2.2.1 How to improve FCP

1.减少资源的阻塞,例如不要把业务js放在顶部加载 2.压缩css和移除无用的css,可以使用purifyCss 3.pre-fetch dns链接 4.减小TTFB 5.避免多次重定向 6.preload必要的资源 7.避免巨大的网络负载 8.做好静态资源的缓存策略 9.避免过大的DOM,减少生成dom tree的时间 10.确保文本在Web字体加载期间保持可见 11.保持较低的请求计数和较小的传输大小

2.3 First Meaningful Paint (FMP)

定义:首次有意义的内容绘制时间,这里的有意义主要看网站,比如小说网站有意义的内容就是文字,漫画网站有意义的就是图片,如果是视频网站有效绘制就是视频,有用,但是现在很多性能测试工具已经不用这个指标了,换成了另外的指标了 Largest Contentful Paint,所以这里不再仔细介绍。

2.4 Largest Contentful Paint(LCP)

定义:可视区域中最大的内容元素呈现到屏幕上的时间,用以估算页面的主要内容对用户可见时间。这是一个新的指标,很多浏览器都没有实现。

如何测量:

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    console.log('LCP candidate:', entry.startTime, entry);
  }
}).observe({type'largest-contentful-paint'bufferedtrue});

2.4.1 How to improve LCP

1.采用PRRL模式

Push (or preload) 重要的资源.
Render:尽快的渲染初始路由页.
Pre-cache :预缓存资源,使用service worker等等.
Lazy load:懒加载剩下的资源和路由.

2.优化字体,图片,css,js 3.优化关键渲染路径

2.5 Speed Index(SI)

定义:这是一个表示页面可视区域中内容的填充速度的指标,可以通过计算页面可见区域内容显示的平均时间来衡量。

例如同样的一个页面:A在3秒的时候填充了百分之80的区域,B在3秒的时候也填充了百分之80的区域,5秒都完成了百分之百,但是A在1秒的时候已经完成了百分之80,B在3秒的时候才完成了百分之80;

通过计算可以得到

A:80% * 1 + 20% * 5 = 1.8
B:80% * 3 + 20% * 5 = 3.4

2.6 First Screen Paint(FSP)

定义:页面从开始加载到首屏内容全部绘制完成的时间,用户可以看到首屏的全部内容。

三 交互响应相关

3.1 Time to Interactive(TTI)

定义:从FCP开始,浏览器已经可以持续性的响应用户的输入。完全达到可交互状态的时间点是在最后一个长任务(Long Task)完成的时间, 并且在随后的 5 秒内网络和主线程不存在longtask或者不超过一个网络请求。

1.从FCP开始
2.longtask后五秒内不再有longtask产生并且不超过一个网络请求
3.在五秒处先前搜索到最后一个longtask结束的时间点
4.从FCP到这个longtask结束的时间点就是TTI

3.2.1 How to improve TTI

1.压缩代码 2.预链接必要的源 3.预加载css等资源 4.按需加载第三方的包 5.减少关键资源的请求深度,例如请求一层嵌套一层 6.减少js执行时长,优化代码 7.减少主线程中的工作,例如只加载必要的代码,使用节流处理频繁的input,减少css的资源查找等等 8.减少请求,压缩请求的内容使用gzip等等

3.2 Total Blocking Time(TBT)

定义:在TTI中,所有的longtask减去50ms的累计值,优秀的TBT应该控制在300ms以下。 当一个task超过50ms的时候就会导致UI卡顿等一些问题。

3.2.1 How to improve TBT

1.减少第三方包的依赖,

按需加载,能简单实现的 尽量不要安装一个包

2.优化代码,减少单个js任务的执行时间

禁止多层嵌套,可以改变数据结构,或者用空间换时间

3.最大成都的减少住主线程的工作

1.优化第三方js
2.debounce Input 操作
3.使用web worker
4.减少样式计算的复杂性
5.避免重回和重排的工作
6.提取关键css,延迟非关键的css加载
7.注意样式的书写,尽可能的不要写太多的Layout
8.更好的tree-shaking和code_split

4.控制请求的个数,并且降低传输的内容

3.3 First Input Delay (FID)

定义:当用户第一次与页面交互时到能够响应用户行为的时间,例如点击链接,输入表单,点击一个按钮。通常应该控制在100ms

测试方法:


new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    const delay = entry.processingStart - entry.startTime;
    console.log('FID candidate:', delay, entry);
  }
}).observe({type'first-input'bufferedtrue});

3.3.1 How to improve FID

1.减少第三方包的依赖 2.减少js执行时间 3.降低主线程序的工作 4.保持低请求数和资源传输大小

3.4 Cumulative Layout Shift (CLS)

定义:在一个页面的生命周期中,所有元素发生突然位移的分数总和。

看起来很难理解,举个例子🌰:

1.当我们要去点击一个元素的时候,突然这个元素向下偏移了。导致我点击到了别的东西。

2.突然间页面出现了一个元素把其他的元素挤跑了

分数如何计算的

例如一个元素在第一帧的时候,占据了viewport的上面百分之50,在下一帧就跑到了页面的最底部,那么这个元素并集所占viewport的百分比就是1,那么得分就是1分;

js中如何测量:

let cls = 0;

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    if (!entry.hadRecentInput) {
      cls += entry.value;
      console.log('Current CLS value:', cls, entry);
    }
  }
}).observe({type'layout-shift'bufferedtrue});

3.4.1 How to improve CLS

1.设置图片视频的大小,保证加载前和加载后占地面积一致 2.禁止在已存在内容在中插入内容 3.使用transform动画替代改变布局导致的动画

测试工具

目前主要的测试用具有

  • Chrome DevTools

  • Lighthouse

  • WebPageTest

  • web-vitals 这是一个js库,我打算用它来做一个性能检测的平台,性能监控的功能,不知道方案是否可行 还有一些其他的就不一一列举了。

总结

通过以上性能指标的介绍,大概总结出提高性能指标的手段主要有以下一些内容:

  • 减少第三方包的依赖
  • 按需加载包,路由
  • 资源嗅探prefetch, preload, dns-prefetch
  • 压缩资源
  • 使用存储工具缓存资源,静态资源做好缓存策略
  • 减少传输体的大小
  • 减少重回和重排
  • 减少重定向
  • 降低dom嵌套和css嵌套
  • 加载必要的css js资源。非必要的采用懒加载
  • 使用debounce和throttle
  • 降低主线程的占用时间
  • 保持低的请求数量 等等

一名在前线奋斗的菜鸟前端,希望和大家一起学习,进步~

1.关注前端工兵,不定时发放极客时间福利哦;

2.觉得文章不错,点个关注,再点个再看,也可以和我交流,共同进步;

前端工兵
前端工兵

白色座头鲸

2021/03/13  阅读:7  主题:全栈蓝

作者介绍

白色座头鲸