获取performance数据
Chrome是如何渲染页面的?
第一个请求
以第一个请求为例,我们来具体看一下 Chrome 是如何进行页面渲染的?依然是以对 https://www.bilibili.com 的请求为例,来看一下 1ms 的 performance 面板,即下图中红线部分、中间 NET 栏蓝色细长条开始的部分和 Network 中水平箱线图开始的部分。其中两边横线中间深浅色方框的部分是水平箱线图,是用来展示某部分在整体中的比例关系。比如我们看到这个长长的箱型图,通过直观感受,就能知道对前面一部分横线挺长的,蓝色部分里浅色部分很长,深色的短,右边的横线几乎看不到。那这些又分别能展示什么信息?首先,点开箱型图最下方的聚合面板(Summary),上面赫然写着:此乃页面源。欲求小破站, 终生皆让我……耗时一秒半。然后在 Network tab 里查看该请求的 timing 部分,可以得到如下图:这里的各个部分分别代表:请求其它资源
言归正传,我们现在获取到了 bilibili 网站的 HTML,接下来就需要对这个 HTML 进行处理。通过 response header 得到 content-type:html,此时会创建一个个渲染进程,也就是主线程的这个进程。但是可以看到在主线程中的蓝色 parse HTML 之前,已经有很多 set request 被发起了,而且这些 send request 都是 HTML 文档中的一些 js 和 css。为什么会这样呢?不应该是先解析 HTML,才能知道对哪些资源进行发起请求吗?在 HTML 中引入的 js,存在修改 Dom 的可能,所以浏览器一般在遇到 script 标签后,会先暂停 HTML 解析,优先 js 的下载和执行。但是下载是相对耗时的,如果因为下载时间久而卡住了页面解析,很容易导致用户体验变差,因此 Chrome 采用了一些优化策略。具体来说,就是当 Chrome 渲染引擎接收到 HTML 的字节流时候,会开启一个专门用来分析字节流中所包含 js、css 文件的预解析线程。解析到相关信息之后,预解析线程会提前开始下载这些资源文件,这样在需要使用的时候就可以直接执行,避免了下载的等待时间。但是也能观察到,在Parse HTML蓝色方块下方,还有一些 send request,这些怎么就不是提前下载的呢?我的理解是,这些资源其实都是在预解析线程下载的,尽管在时间上会存在重叠,但和主线程不属于同一个线程,所以 performance 工具会这么显示。但这又带来了另一个问题,为什么有些 js 明明在 HTML 的后面,却在前面就 send request 了,而有些 link/script 明明写在 HTML 里的前面,却在 performance 里后 send request?这是跟资源的优先级有关。比如普通的 script 标签引用的资源,普通 link 引用的资源,或是rel=prelaod 或 as="style"预加载的资源,可能会被优先处理。而当资源是 prefetch,或者用 <link rel="stylesheet" href="//s1.hdslb.com/bfs/static/jinkela/long/font/regular.css" media="print" onload="this.media='all'"/>这种方式的,由于优先级低,就会被延后下载。一般的其他资源,则按顺序下载。回到 Network,可以看到在 www.bilibil.com 的箱线图之后,是一连串 js、css、Webp 资源需要加载的请求被发起了。把鼠标移动到这些箱线图上,会看到上面有优先级 lowest low high highest,这就表示了资源的重要程度。那么这些资源的优先级是如何评定的?一般来说,访问域名获取的 HTML、 以及预加载资源时as="style",拥有最高优先级。普通的 <script> 、 <link> 标签、 使用preload的预加载,拥有 高优先级。使用了 async/defer 的 <script> 、as="script"的预加载资源拥有低优先级。使用了 <link rel="stylesheet" href="//s1.hdslb.com/bfs/static/jinkela/long/font/medium.css" media="print" onload="this.media='all'"> 这种方式的,和不加 as="xxx"的 prefetch 预加载,就相当于异步加载,拥有最低优先级。页面优化关注哪些指标
FCP
First content paint 代表浏览器渲染出第一个 Dom content 的时间。这里的 Dom content 包括图片、非空白 canvas、svgs 等。如果你的页面里有 iframe,iframe 里的任何东西都不会被当成 Dom content。FCP 好坏标准也是随着收集到的页面数据来不断变化的,我们可以从 httparchive 地址来查看现在世界上的页面的中位数是多少。根据目前的指标来看,FCP 时间可以简单的分为 3 档:0 - 1.9s,1.9s - 3s,3s以上,它们分别代表还行、很一般、不太行。当我们在某个页面中使用 LightHouse 进行评估的时候,可能会看到尽管 FCP 只有 1s,显示的也是橙色标记。LightHouse 里的得分是根据百分比来的。也就是说当你的 FCP 时间,是所有页面中的前 10%, 那么可以得到 90 分, 前 1% 可以得到 99 分,得到 90-100 分才会是绿色。其他的几个指标也是同样的评判标准。影响 FCP 的原因有很多,其中一个比较常见的原因是自定义字体的加载,字体文件的加载需要一定时间,在字体文件加载完成之前,不同的浏览器会采用不同的策略。edge:在字体准备好前使用系统字体Chrome:隐藏文本内容。如果 3s 后自定义字体还没准备好,则使用系统字体,直到字体准备好,然后替换字体。火狐:同 Chromesafari:隐藏文本直到字体准备好。一个简单的办法是在@font-face 演示里增加 font-display: swap设置 swap 就是告诉浏览器是使用该字体的文本应该立即使用系统字体进行显示,当自定义字体准备就绪后,替换系统字体。或者使用 prefetch / preload 来提前获取字体相关资源。@font-face {
font-family: 'Pacifico';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/pacifico/v12/FwZY7-Qmy14u9lezJ-6H6MmBp0u-.woff2) format('woff2');
font-display: swap;
}
Time to intercative
TTI 标记着页面多久可以进行完全交互。这里的完全交互是指:Speed Index
这个指标代表了用户感知的可见区域的页面加载的快慢。也分成 0-3.4s 、 3.4 - 5.8、超过 5.8 三挡。但是得分也同样是跟全球网页数据来对比的。提高 speed index 的主要是通过减少 js 对主线程阻塞,让一些非必要的 js 在 Dom 渲染后再执行。Total Block Time
Largest Contentful Paint
最大内容绘制。记录的是视口中最大的内容元素被渲染到屏幕的时间,也大致分为 0-2.5s、2.5s-4s、超过 4s 三个大范围。Cumulative Layout Shift
往期推荐
这里有最新开源资讯、软件更新、技术干货等内容
点这里 ↓↓↓ 记得 关注✔ 标星⭐ 哦