凡所执念,皆成束缚 --《佛经》
大家好,我是柒八九。
前言
今天我们来聊聊另外一个比较重要的性能指标TTI
。
如果想了解该系列文章(浏览器底层原理&优化方案),可以参考我们已经发布的文章。如下是往期文章。
- 页面是如何生成的(宏观角度)
- Chromium 最新渲染引擎--RenderingNG
- RenderingNG中关键数据结构及其角色
- 浏览器之客户端存储
- 浏览器_知识点精讲
- 像素是怎样练成的
- 浏览器之资源获取优先级(fetchpriority)
- 浏览器之性能指标_FCP
- 浏览器之性能指标-LCP
- 浏览器之性能指标-CLS
- 浏览器之性能指标-FID
你能所学到的知识点
- 前置知识点
TTI
是个啥- 如何计算
TTI
TTI
得分- 如何测量
TTI
- 什么原因导致
TTI
变慢?- 优化TTI
好了,天不早了,干点正事哇。
1. 前置知识点
任务和主线程
一个任务是浏览器执行的任何离散工作单元。
任务包括
- 渲染、解析HTML和CSS
- 运行JavaScript代码
- 以及其他一些可能无法直接控制的工作
其中,编写并部署到网络上的JavaScript是主要的任务来源之一。
关于更多详细的内容,可以参考之前的像素是怎样练成的。这里不做展开。
上图是,在Chrome DevTools
的性能分析器中,通过click
事件处理程序触发的任务的描述
任务对性能有一些影响。
例如
- 在浏览器启动期间 下载JavaScript文件时,它会排队执行任务来解析和编译该JavaScript,以便后续可以执行它。
- 在页面生命周期的后期阶段,当你的JavaScript执行工作,比如通过事件处理程序驱动交互、JavaScript驱动的动画以及诸如分析数据收集等后台活动时,也会触发任务。
- 除了
Web Workers
和类似的API之外,所有这些都在主线程上执行。
主线程
在浏览器中,大部分任务都在主线程上运行。它被称为主线程有其原因:几乎所有你编写的JavaScript代码都在这个线程上执行。
主线程一次只能处理一个任务 。当任务的执行时间超过一定阈值(50毫秒),它们被归类为长任务。如果用户在长任务执行时尝试与页面进行交互,或者需要进行重要的渲染更新,浏览器将延迟处理这些工作。这导致交互或渲染延迟。
可以将主线程视为餐厅里的服务员。服务员需要接受订单、处理付款、送上食物、加满饮料等等。
如果服务员被某个任务拖累,比如花费太长时间处理订单(例如,客户点餐很复杂或犹豫不决),服务员就无法处理其他任务。
在Chrome的性能分析器中,长任务 通常以红色三角形 的形式呈现。任务的阻塞部分会被填充上带有红色斜线图案的纹理,以示区别。
你需要拆分任务。这意味着将一个长任务分割成较小的任务,使它们在单独运行时所需的时间更短。
当任务被拆分时,浏览器有更多机会响应更高优先级的工作,其中包括用户的交互操作。
在上述图例的顶部,由用户交互触发的事件处理程序必须等待一个长任务完成后 才能执行,这导致交互延迟
。而在底部,事件处理程序有机会更早地执行。由于事件处理程序有机会在较小的任务之间运行,它比等待长任务完成时运行要更快。
由于长任务的出现,它们可能会延迟FCP
和TTI
。在顶部的示例中,用户可能会感觉到延迟;而在底部,交互可能会感觉瞬间完成。
页面完全可交互
"页面完全可交互"(Page Fully Interactive
)是指在网页加载完成后,所有主要的用户交互元素和功能都已经加载并且可以响应用户的操作,用户可以在页面上执行各种操作而不会出现明显的延迟或等待。当页面完全可交互时,用户体验更加流畅,因为用户可以立即与页面进行交互,无需等待页面响应。
当一个网页达到页面完全可交互
的状态时,以下几个条件应当满足:
-
页面结构已经完全加载: 所有HTML文档、CSS样式表和JavaScript脚本都已下载完成,并且浏览器已经解析和构建了整个页面的DOM结构。
-
主要内容可见: 网页的主要内容已经在浏览器窗口中可见,用户可以看到页面的核心信息而不需要进行滚动或等待。
-
用户交互元素可用: 网页上的按钮、链接、表单等交互元素都已加载并且可以正常响应用户的点击、输入或其他操作。
-
动态功能可用: 如果网页中有使用JavaScript实现的动态功能,如下拉菜单、轮播图等,这些功能也已经可以正常使用。
-
响应时间短: 当用户执行交互操作时,网页的响应时间非常短,用户几乎感觉不到延迟。例如,点击按钮立即有响应,页面切换或动画流畅运行。
2. TTI
是个啥
TTI
:是Time to Interactive
的简写,中文名称可交互时间
。
它用于衡量网页加载完成后,用户可以与页面进行交互的时间。它是页面加载过程中的一个关键度量标准,更准确地反映了用户实际体验的时间点。
页面的
可交互性
通过以下四个标准来衡量:
- 浏览器显示有意义的内容
- 页面已准备好处理用户针对可见元素的操作
- 页面在50毫秒内响应用户交互
- 页面代码中最重要的脚本已被执行,使主线程处于空闲状态
重要的是要理解,TTI
不仅仅衡量页面的加载时间,同时也专注于页面的可交互性
。
加载时间 vs 可交互性
加载时间
与可交互性
是网页性能的不同但相关的两个性能指标。
加载时间
描述了加载网站内容所需的时间可交互性
描述了网站变得响应的时间
这听起来可能像是在比较两个同义词,但实际上它们之间的区别非常重要。
举一个比较贴切的例子:在周一早上,你被闹钟吵醒了,然后从生理上,睁开眼睛,然后来床上各种伸懒腰,这一系列的操作可以认为,你是为了迎接一天的工作的暴击 做的前期准备,也就是说,你的身体正在加载
。然而,此时的你,衣服没穿,脸没洗,牙没刷的你,是还没有到到工作状态。无法及时响应老板给你画的大饼 。 你还需要一顿早餐的补给,才可以完全响应老板的各种工作指派。也就是说,你只有在此时才处于 完全响应老板的工作。
TTI
是一种以用户为中心的指标,侧重于从客户的实际角度评估网页性能。
为了使用户留在一个网站上,在页面加载过程中必须迅速地发生四个关键时刻。
- 首先,用户收到一个可见的信号,表示页面正在加载中。
- 其次,加载的内容变得足够有用,以便理解页面的内容。
- 在第三步中,页面变得可交互。
- 最后,页面完全可交互,意味着用户可以顺畅地进行交互,没有中断。
我们可以将TTI
视为一种检查网站提供用户满意的体验所需时间的方式,其满意体验主要表现在感知速度方面。通过控制这个时间,我们可以降低跳出率并给用户留下良好的印象。
TTI 是核心网络指标吗?
TTI
不是核心网络指标
(Core Web Vitals)的指标。核心网络指标
是一组用于衡量用户体验不同方面的三个指标。其中,
这三个指标被认为是评估网站用户体验的关键要素。
其他网络关键指标不在核心网络指标
范畴内,但它们提供有关网站速度的额外信息
。
TTI
可能不是核心网络指标
的候选指标,并且可能不会影响我们在谷歌搜索中的排名。但仍然值得使用这个指标。一个良好的TTI
分数可以降低CLS
,并且TTI
仍然是衡量用户在访问初期对网站的感知的相关指标。
3. 如何计算TTI
TTI
的计量单位是秒 ,计算页面的TTI
需要识别FCP
和首个5秒静默窗口(Quiet Window)。
在这个窗口中,浏览器不应处理主线程上超过50毫秒的任何任务 ,也不应等待超过两个服务器响应请求。
TTI
是FCP
和静默窗口 之间的一个时间点,它恰好位于静默窗口之前 的最后一个长任务完成时。
TTI 起始点
计算TTI
分数的第一步是找到我们网站的FCP
。
FCP是一个指标,用于标识页面加载时间轴上
用户可以在屏幕上看到任何内容的第一个点 。较短的FCP
给用户一种,你的页面正在加载的赶脚。同时,他会下意识的认为,他想要的页面内容,马上就要呼之欲出了。
有里有一个小的提示点:不要将FCP
与LCP
混淆。LCP是一个性能指标,用于确定网页上最大元素在用户浏览器中变为可见的时间。
下图,简单的为我们展示了FCP
、LCP
和TTI
在页面加载中,可能存在的位置和方式。
LCP
总是在页面完全可交互之前准备好,但它不影响TTI
指标的计算。
TTI 结束点
在我们网页加载过程中,用户的浏览器会执行许多脚本。其中一些任务需要的时间超过50毫秒 ,并且这些任务与TTI
的测量相关。浏览器还会异步地向服务器发送资源请求 ,并且每个请求都会保持open
状态,直到获得响应。
有一个时刻,浏览器可以休息一下,我们称之为静默窗口(quiet window)。
这是在至少五秒内,浏览器不需要在主线程上执行任何长时间任务,并且最多只有2个资源请求处于"
open
状态的第一个时刻。
有一点可以确定,FCP
总是在静默窗口
之前发生的。
确定 TTI 得分
在这个时间范围内,我们应该寻找一个时刻,即浏览器在静默窗口之前 完成了最后一个长时间任务。
如果FCP
后没有任何超过50毫秒的任务 ,我们的TTI
等于我们的FCP
。
TTI vs FID
FID
衡量的是网页在FCP
和TTI
之间对用户交互作出响应所需的时间。TTI
衡量的是页面完全可交互所需的时间,而不是页面对用户操作作出反应所需的时间。
4. TTI
得分
和其他性能指标一样,TTI
也存在好坏阈值.
根据Lighthouse中TTI
的阈值如下:(这里有很多版本,我们采用市面上常见的版本)
- 良好 - 无需处理 = TTI 小于或等于 2.5 秒。
- 可以接受,但考虑改进 = TTI 在 2.5 秒到 3.2 秒之间。
- 超出推荐时间 = TTI 在 3.2 秒到 4.5 秒之间。
- 远远超出推荐时间 = TTI 高于 4.5 秒。
5. 如何测量TTI
测量TTI
的最佳方法是在网站上运行Lighthouse性能审核。
然而,目前,谷歌正在改变其Lighthouse 10
工具,将TTI
从中移除,并将其得分权重转移到CLS
。CLS
现在将占据整体性能得分的25%
,而TTI将构成该部分的10%
。
作为测量TTI
的替代工具有:
- WebPageTest
- Lighthouse 老版本 (这里不做展示了)
使用Webpagetest测量TTI
打开Webpagetest
网站,然后输入我们想要测试的URL。 (这里我们以字节跳动
官网为例)
在经过一段时间后,Webpagetest
会给出我们详细的针对网站的各个指标的数据。其中有很多我们熟悉的老朋友。(LCP
/FCP
/CLS
等)
如果我们想查看TTI
得分,我们需要点击Plot Full Results
按钮,因为在第一个结果屏幕上不会显示该得分。
向下滚动以查找TTI
指标。
6. 什么原因导致 TTI 变慢?
巨大的网络负载大小
FCP
是在页面上出现第一个"有意义"的元素时触发的。无论这个元素是什么类型的,如果在该元素之上嵌入了阻塞渲染的资源 ,例如指向大文件的 <script>
或 <link>
标签,这些资源会因为在不太好的网络连接下下载而导致显示被延迟。
为了解决这个问题,建议优化代码,使其更"轻量",通过尽可能减小文件大小,同时在可能的情况下脱离第三方库的依赖。
页面加载时包含过多的 JavaScript
基于这一点,其实我们之前在讲FCP/LCP
中多次提到,就是JS的按需加载 .我们应该秉承一个原则- 吃多少,拿多少 ,不要胡吃海喝,这样对胃
不好.我们可以只加载,当前视图中所用到的JS,而不贪杯.
同时进行多个网络请求
最后但同样重要的是,网络请求的数量是一个需要考虑的重要因素。
图片不会阻塞渲染。这意味着如果浏览器在解析 HTML 文件时遇到一个 <img>
标签,它会开始加载图片,并继续处理后续标签,而不必等待图片完全加载。这一点起初听起来可能很好。
另一方面,这也会导致页面上同时加载大量非优化的图片,这很可能需要更多时间来加载并保持这些请求连接打开,从而延长页面的TTI
.
从上面的多个角度,我们得到一个结论:
TTI
缓慢主要是由现代网站普遍使用的大量JavaScript引起的。
长时间的JavaScript任务,即执行时间超过50毫秒的任务 ,会占用主线程的大量时间,从而延迟TTI
的发生。
由于浏览器依赖主线程来完成各种任务,长时间的任务会使页面在任务完成之前变得不响应。
7. 优化TTI
要提高TTI,有两个关键因素需要考虑
- 优化JavaScript代码
- 减少服务器响应时间
优化JS
- 优化我们的代码,对未使用的脚本进行缩小,
- 压缩找到的最大文件
- 不要通过将所有JavaScript代码发送到一个文件中来使浏览器不堪重负,而是将代码拆分,并最初只发送访问者在开始时所需的必要代码
- 延迟加载第三方脚本,如社交分享按钮、视频播放器嵌入、广告的iframes等,同时优先处理对用户提供最大价值的脚本
- 使用
defer
属性告知浏览器不要等待特定的脚本,而是继续处理HTML
上面的一些优化方法,我们之前也有讲过,这里就不在过多解释了.
减少服务端反应时间
- 使用内容分发网络(CDN),将内容存储在靠近用户的服务器上
- 应用预取技术,例如提前渲染特定页面元素
- 避免使用生成额外HTTP请求的网络字体资源
后记
分享是一种态度。
参考资料:
全文完,既然看到这里了,如果觉得不错,随手点个赞和"在看"吧。