老板让你做性能优化,第一步你应该做什么?🔥🔥

35,510 阅读13分钟

前言

项目的性能决定了用户对项目的整体感观度,优秀的性能可以保证项目的流畅与自然给用户愉快的体验感受。当我们开发完成一个项目以后最重要的环节就是要保证项目拥有一个良好的性能,所以开发完成以后需要我们针对项目做好性能优化。

那么,要使一个项目拥有良好的性能,我们需要怎么去做性能优化呢?

第一步就是定义好性能指标,而为网站量身定制一套最佳指标也是性能优化中最重要的一个环节。

性能是相对的

首先我们要知道如何评价一个页面性能的好坏。
性能是 相对 的,怎么说呢?举几个例子你就懂了:

  • 设备不同:同一个网站,我访问的时候我感觉一般般,有时还有卡顿,首次加载还有点慢,但是小刘访问就挺好,首次加载贼快,页面一点都不卡顿。那为什么会这样呢?原因其实就是我用的手机是老款的诺鸡亚,网络用的是3G网络。而小刘用的是最新款的爱疯100,网络妥妥的10G网络。
  • 实现方式不同:两个网站,他们完成加载的速度完全一样,但其中一个却显示的内容比另一个快很多。那为什么会这样呢?原因是其中一个用的是按需加载,而另一个却是要等所有内容都加载完才显示。
  • 使用技术不同:两个图形编辑网站,其中一个各种性能都比另一个强一点点,但是在图形编辑的时候却差另一个差很多,比如说不够顺畅,元素不能太多否则还会卡顿。原因是内部实现机制不一样,操作不顺畅的是用原生DOM实现的,操作顺畅的是用canvas或webGL绘制的。

因此,当我们在做性能相关的东西时,重要的就是要做到精确,并且根据能够进行定量测量的客观标准来定义性能。

而这些定量测量的客观标准就是指标。

指标

指标的定义必须多样化,不可单一,举个例子:我们只定义一个首屏加载指标,那一个页面首屏加载很快我们是不是就说他的性能很好呢?答案是否定的,也许它加载快但渲染很慢,甚至交互还卡顿,多次卡顿还无响应。

这样的性能能叫好么?肯定就是垃圾啊。

鉴于上述原因,只用一项指标去捕获页面的所有性能特征是远远不够的,它并不能清楚地表明项目性能的好坏。

如何定义指标?

Chrome团队成员与W3C Web性能工作组共同合作,致力打造一组新的标准化API和指标,用来更准确地测量网页性能。为确保这些指标与用户息息相关,还围绕下面几个关键问题构建出了指标框架:

  1. 是否正在发生? 导航是否成功启动?服务器有响应吗?
  2. 是否有用? 是否渲染了足够的内容让用户可以深入其中?
  3. 是否可用? 页面是否繁忙,用户是否可以与页面进行交互?
  4. 是否令人愉快? 交互是否流畅自然,没有延迟和卡顿?

如何测量指标?

性能指标一般通过以下两种方式来进行测量:

  • 在开发环境中:使用工具在稳定、受控的环境中模拟页面加载
  • 在实际情况中:基于真实用户的实际页面加载与页面交互

这两种测量方式并没有优劣之分,通常我们会同时使用这两个方式来确保良好的性能。

开发环境

在开发环境中测试性能对于新功能的开发过程至关重要。功能在发布到生产环境之前,不可能基于真实用户体验对性能特征进行测量。因此在功能发布之前,在开发环境中对其进行测试是测试性能的最佳方法。

实际情况

虽然在开发环境中测试是一种合理的性能代理,但这种测试方式不一定能反映所有用户在实际情况下对网站的体验。

根据用户的设备性能以及他们的网络状况,网站的性能也可能会有很大差异。而用户是否与页面进行交互也会导致这种性能差异。

此外,页面加载具有不确定性。例如,加载个性化内容或广告的网站可能会因为用户差异而呈现不同的性能特征。实验室测试并不会捕获到这些差异。

要想真正了解您的网站为用户呈现的性能表现,唯一的方法就是在这些用户进行页面加载和页面交互时对页面性能进行实测。这种类型的测量通常被称为真实用户监控,或简称为 RUM。

需要测量哪些指标呢?

需要测量的指标我们可以分为两类,一类是核心指标也叫基本指标,另一类是自定义指标。

核心指标

核心指标是我们页面做性能测试时必不可少的几个指标。

FCP(First Contentful Paint)首次内容绘制

指浏览器从响应用户输入网络地址到页面内容的任何部分在屏幕上完成渲染的时间。这个就是实际有意义的首屏时间。

其实这里还有一个核心指标:FP(First Paint)首次绘制,但正常情况下做FCP就没必要做FP了。

LCP(Largest Contentful Paint)最大内容绘制

表示可视区最大内容(文本块或图像元素)在屏幕上完成渲染的时间。该时间会随着页面渲染变化而变化,因为页面中的最大元素在渲染过程中可能会发生改变,另外该指标会在用户第一次交互后停止记录。

TTI(Time to Interactive)可交互时间

测量页面从开始加载到视觉上完成渲染、初始脚本完成加载,并能够快速、可靠地响应用户输入所需的可交互状态时间。 可交互状态指的是页面上的 UI 组件是可以交互的(可以响应按钮的点击或在文本框输入文字等)。

TBT(Total Blocking Time)总阻塞时间

指 FCP(首次内容绘制) 与 TTI (可交互时间)之间的总时间。这期间,主线程被阻塞的时间过长,无法作出输入响应。举个例子说明一下:

主线程上的任务时间轴

上图为页面加载期间浏览器主线程的图表, 上方的时间轴上有五个任务,其中三个是长任务,因为这些任务的持续时间超过50毫秒。下图显示了各个长任务的阻塞时间:

显示阻塞时间的主线程任务时间轴

因此,虽然在主线程上运行任务的总时间为 560 毫秒,但其中只有 345 毫秒被视为阻塞时间。

CLS (Cumulative Layout Shift) 累积布局偏移

累积布局偏移 (CLS) 是一个以用户为中心的测量视觉稳定性的重要指标,因为该项指标有助于量化用户发生意外布局偏移的频率,较低的 CLS 有助于用户的使用体验。 如果还不知道什么是CLS的话找了个图可以看着理解一下:

未标题-1.gif 解释一下就是想点取消,但因为别内容加载出来把按钮顶下去了,所以点成了确定订单。大写的尴尬!!

注意:2021年6月1日:CLS 的实现方式已发生变更。想了解具体的变更原因可以查看 不断发展 CLS 指标

以前 CLS 测量的是整个页面生命周期内发生的所有单次布局偏移分数的总和

现在 CLS 测量的是整个页面生命周期内发生的所有意外布局偏移中最大一连串的布局偏移分数

布局偏移:每当一个可见元素的位置从一个已渲染帧变更到下一个已渲染帧时,就发生了布局偏移 。

一连串的布局偏移:也叫会话窗口,是指一个或多个快速连续发生的单次布局偏移,每次偏移相隔的时间少于 1 秒,且整个窗口的最大持续时长为 5 秒。

最大的一连串:是指窗口内所有布局偏移累计分数最大的会话窗口。

FID(First input delay)首次输入延迟

测量从用户第一次与您的网站交互(例如当他们单击链接、点按按钮或使用由JavaScript驱动的自定义控件)直到浏览器实际能够对交互做出响应所经过的时间。页面的 FID 应为100 毫秒或更短。

上述的几个核心指标其实就是最近几年比较重要的几个核心指标,但核心指标会随着时间的推移而发展。针对 2020 年的指标构成侧重于用户体验的三个方面:加载性能、交互性和视觉稳定性。

2020年的核心Web指标为三大指标:

  • LCP(Largest Contentful Paint)最大内容绘制、
  • FID(First Input Delay)首次输入延迟
  • CLS(Cumulative Layout Shift) 累积布局偏移。

每项指标所测量的用户体验是不同的:

  • LCP 测量感知加载速度,并在页面的主要内容基本加载完成时,在页面加载时间轴中标记出相应的点;
  • FID 测量响应度,并将用户首次尝试与页面交互的体验进行了量化;
  • CLS 测量视觉稳定性,并对可见页面内容的意外布局偏移量进行了量化。

最后就是每项核心Web指标都有一个相关联的阈值,这些阈值将性能分为"良好"、"需要改进"或"欠佳":

企业微信20220716-190224@2x.png

良好欠佳百分位数
最大内容绘制≤2500ms>4000ms75
首次输入延迟≤100ms>300ms75
累积布局偏移≤0.1>0.2575

自定义指标

上面列出的核心性能指标有助于大致了解网络上大多数网站的性能特征。并且这些指标还可以作为网站的一组通用指标,有利于与竞争对手进行性能比较。

但某些情况下我们需要为网站量身定制一些指标来衡量我们网站的性能。这种专门为网站量身定制的指标往往才是最佳指标,我们称之为自定义指标。

还有就是,在很多人心里可能会觉得核心指标比自定义指标重要,其实不是这样的。举个例子:
LCP 指标用于测量页面的主要内容何时完成加载,但在某些情况下,最大元素并不是页面主要内容的一部分,因此LCP就不再是相关指标,他对我们的性能测试就没有意义。

为解决自定义指标的情况,Web性能工作组还推出了一系列较低级别的标准化API,可用于我们自定义指标:

  • 用户计时 API :该规范定义了一个接口,以帮助 Web 开发人员通过访问高精度时间戳来衡量其应用程序的性能。
  • 长任务 API :该档定义了一个 API,网页作者可以使用该 API 来检测“长任务”的存在,这些任务会长时间垄断 UI 线程并阻止其他关键任务的执行
  • 元素计时 API:本文档定义了一个 API,可以在屏幕上显示大型或开发人员指定的图像元素和文本节点时进行监控。
  • 导航计时API:该规范定义了Web应用程序的接口,以访问用于导航文档的完整计时信息。
  • 资源计时 API:该规范定义了Web应用程序的接口,以访问文档中资源的完整计时信息。
  • 服务器计时:该规范使服务器能够将有关请求响应周期的性能指标传达给用户代理。它还标准化了JavaScript接口,以使应用程序能够收集和处理并对这些指标采取行动以优化应用程序交付。

那么通过上面这些标准化API,我们就可以去定义我们自己的自定义指标。核心指标能为我们提供一个很好的性能基线,但在许多情况下,需要测量更多指标,才能刻画出具体网站的完整体验。 因此以用户为中心的自定义指标,从普遍意义上,通过它们可以更好衡量我们网站更细节的性能。

下面将列出一些针对我们编辑器页面的一些自定义指标。

注意:下面就是我根据我们网站列的一些自定义指标,网站还没上线,等上线了我再把网址贴出来,同样的自定义指标之后也会不断修改,让它更能反应我们网站的性能测试。所以文章之后也会不断更新。感兴趣的可以收藏,以后就能看着我是如何自定义性能指标,又是如何做筛选的了。

话不多说,直接进入自定义指标定义吧。

下面将结合我们自己的业务场景、类别、用户认知、瞬时性和持续性来针对编辑器项目定义一些自定义指标。(其实我真的不想放表格,表格换成图少了一千字呢!!!但掘金的表格是真的难编辑)

aaaaaa.jpg

以上所有指标都需要结合用户的真实体验来收集和优化,以用户为中心,常用功能需要提高指标级别。

还需要根据用户的认知去做对应的性能优化,在用户的认知中应该“快”那就必须快,在用户的认知中可以“慢”那就尽量快。

结语

以面就是本章的所有内容了,希望对正在做网页性能的你有所帮助。

同时呢定义完指标之后就会着手去做性能优化,之后会陆续把如何做性能优化也陆续写文发出来。

感谢阅读。感谢支持。

我正在参与掘金技术社区创作者签约计划招募活动,点击链接报名投稿