如何对页面进行简单的性能检测与分析

avatar
前端开发工程师 @bigo

file

本文首发于:github.com/bigo-fronte… 欢迎关注、转载。

前言

页面性能的好与坏,直接影响到用户的留存。对于前端开发者来说,不能以感官的体验进行判断,而是需要了解页面的性能指标,并且尝试将这些指标量化,根据量化的指标进行针对性的改进,才能真正达到优化的效果。一般页面的性能指标有:

  1. 白屏时间
  2. 首屏时间
  3. 用户可操作时间
  4. 页面总下载时间
  5. 网络请求时间
  6. 内存占用、cpu占用,等等。

本文通过对Performance API、chrome 的Performace面板、Lighthouse的简介,讲解如何使用这些工具对页面进行简单的性能检测与分析。

Performance API

Performace是 html5的新特性之一,该接口会返回当前页面性能相关的信息。它是 High Resolution Time API 的一部分,同时也融合了 Performance Timeline API、Navigation Timing APIUser Timing APIResource Timing API

此处只介绍如何使用Timing中的指标进行性能分析,获取Timing中的指标的方式:

// Level 1 (即将弃用)
window.performace.timing

// Level 2
window.performance.getEntriesByType("navigation")[0]

下图是 Navigation Timing Level 1 的处理模型,从当前浏览器窗口卸载旧页面开始,到新页面加载完成,整个过程一共分为 9 个模块:提示卸载旧文档、重定向/卸载、应用缓存、DNS 解析、TCP 握手、HTTP 请求处理、HTTP 响应处理、DOM 处理、文档装载完成

level1

Navigation Timing Level 2 给出了新的时间线,新版的时间线将描述资源加载的时间用 PerformanceResourceTiming 对象封装了起来。

image.png

指标说明

指标说明
navigationStart表示从上一个文档卸载结束时的unix时间戳,如果没有上一个文档,这个值将和 fetchStart 相等。
unloadEventStart表示前一个网页(与当前页面同域)unload的时间戳,如果无前一个网页unload或者前一个网页与当前页面不同域,则值为0。
unloadEventEnd返回前一个页面 unload 时间绑定的回调函数执行完毕的时间戳
redirectStart第一个HTTP重定向发生的时间。如果没有跳转,或者不是同一个域名内部的跳转,则返回值为0。
redirectEnd最后一个HTTP完成的时间。如果没有跳转,或者不是同一个域名内部的跳转,则返回值为0。
fetchStart返回浏览器准备使用HTTP请求读取文档时的Unix毫秒时间戳。该事件在网页查询本地缓存之前发生。
domainLookupStart返回域名查询开始时的Unix毫秒时间戳。如果使用持久连接,或者信息是从本地缓存获取的,则返回值等同于fetchStart属性的值。
domainLookupEnd返回域名查询结束时的Unix毫秒时间戳。如果使用持久连接,或者信息是从本地缓存获取的,则返回值等同于fetchStart属性的值。
connectStart返回HTTP请求开始向服务器发送时的Unix毫秒时间戳。如果使用持久连接(persistent connection),则返回值等同于fetchStart属性的值。
connectEnd返回浏览器与服务器之间的连接建立时的Unix毫秒时间戳。如果建立的是持久连接,则返回值等同于fetchStart属性的值。连接建立指的是所有握手和认证过程全部结束。
secureConnectionStart返回浏览器与服务器开始安全链接的握手时的Unix毫秒时间戳。如果当前网页不要求安全连接,则返回0。
requestStart返回浏览器向服务器发出HTTP请求时(或开始读取本地缓存时)的Unix毫秒时间戳。
responseStart返回浏览器从服务器收到(或从本地缓存读取)第一个字节时的Unix毫秒时间戳。
responseEnd返回浏览器从服务器收到(或从本地缓存读取)最后一个字节时(如果在此之前HTTP连接已经关闭,则返回关闭时)的Unix毫秒时间戳。
domLoading返回当前网页DOM结构开始解析时(即Document.readyState属性变为“loading”、相应的readystatechange事件触发时)的Unix毫秒时间戳。
domInteractive返回当前网页DOM结构结束解析、开始加载内嵌资源时(即Document.readyState属性变为“interactive”、相应的readystatechange事件触发时)的Unix毫秒时间戳。
domContentLoadedEventStart返回当前网页DOMContentLoaded事件发生时(即DOM结构解析完毕、所有脚本开始运行时)的Unix毫秒时间戳。
domContentLoadedEventEnd返回当前网页所有需要执行的脚本执行完成时的Unix毫秒时间戳。
domComplete返回当前网页DOM结构生成时(即Document.readyState属性变为“complete”,以及相应的readystatechange事件发生时)的Unix毫秒时间戳。
loadEventStartload事件发送给文档,也即load回调函数开始执行的时间。
loadEventEndload 事件的回调函数执行完毕的时间。

关键指标计算

以下给出统计页面性能指标的方法。

let times = {};
let timing = window.performance.timing;

// 优先使用 navigation v2  https://www.w3.org/TR/navigation-timing-2/
if (typeof window.PerformanceNavigationTiming === 'function') {
    timing = window.performance.getEntriesByType('navigation')[0] || timing;
}

//重定向时间
times.redirectTime = timing.redirectEnd - timing.redirectStart;

//DNS查询耗时
times.dnsTime = timing.domainLookupEnd - timing.domainLookupStart;

//TTFB 获得首字节耗费时间
times.ttfbTime = timing.responseStart - timing.navigationStart;

//查询缓存数据时间
times.appcacheTime = timing.domainLookupStart - timing.fetchStart;

//卸载页面的时间
times.unloadTime = timing.unloadEventEnd - timing.unloadEventStart;

//tcp连接耗时
times.tcpTime = timing.connectEnd - timing.connectStart;

//request请求耗时
times.reqTime = timing.responseEnd - timing.responseStart;

//解析dom树耗时
times.analysisTime = timing.domComplete - timing.domInteractive;

//白屏时间 
times.blankTime = (timing.domInteractive || timing.domLoading) - timing.fetchStart;

//首屏时间
times.firstPaint = timing.domComplete - timing.fetchStart;

//domReadyTime
times.domReadyTime = timing.domContentLoadedEventEnd - timing.fetchStart;

利用Performace API,可以对用户侧的页面性能指标进行上报统计,通过量化的数据,针对性的进行优化。需要注意的是,对于spa,如果前端路由更改,Performace的数据并不会更新,因此如果需要统计子路由的指标,需要自定义上报。

Chrome Performance面板

Performance 是 Chrome 提供给我们的开发者工具,用于记录和分析我们的应用在运行时的所有活动。它呈现的数据具有实时性、多维度的特点,可以帮助我们很好地定位性能问题。

使用 Performance 工具时,为了规避其它 Chrome 插件对页面的性能影响,我们最好在无痕模式下打开页面。

面板分为4个部分:

面板区域说明
控制面板开始记录,停止记录和配置记录期间捕获的信息。
概览面板对页面表现(行为)的一个概述。
火焰图面板可视化 CPU 堆栈(stack)信息记录。
统计面板以图表的形式汇总数据。
image-20210228235735591

控制面板

开启记录,停止记录,配置记录期间需要记录的内容。

概览面板

概括区域由三个图形记录组成:

数据类型说明
FPS绿色的柱越高, FPS 值也越高,红色则说明可能出现了卡顿。
CPU表明了哪些事件在消耗 CPU 资源。
NET蓝色 代表 HTML 文件,黄色 代表 Script 文件,紫色 代表 Stylesheets 文件, 绿色 代表 Media 文件,灰色 代表其他资源。

火焰图面板

  • 从不同的角度分析框选区域 。例如:Network,Frames, Interactions, Main等。
  • 在 Flame Chart 面板上你可以看到三条线,蓝线代表 DOMContentLoaded 事件,绿线代表渲染开始的时间( time to first paint),红线代表 load 事件。

统计面板

统计面板选择因点击选择不同的目标统计的内容不同。

  • Summary面板:概括了浏览器加载的总时间。
颜色含义
蓝色Loading,加载
黄色Scripting,脚本
紫色Rendering,渲染
绿色Painting,绘制
深灰Other,其他
浅灰Idle,空闲
  • Bottom-Up面板:展示事件各个阶段耗费的时间。

  • Call Tree面板:查看事件的调用栈。

  • Event Log面板:事件日志信息。

Lighthouse

Lighthouse 是 Google 开发的一款工具,用于分析网络应用和网页,收集现代性能指标并提供对开发人员最佳实践的意见。为Lighthouse 提供一个需要审查的网址,它将针对此页面运行一连串的测试,然后生成一个有关页面性能的报告。

image

Lighthouse主要监测指标

指标说明
性能(Performance)页面的性能评分,包括:首次内容绘制(First Contentful Paint)、首次有效绘制(First Meaningful Paint)、首次 CPU 空闲(First CPU Idle)、可交互时间(Time to Interactive)、速度指标(Speed Index)、输入延迟估值(Estimated Input Latency)。
PWA(Progressive Web App)验证PWA的各个方面的性能情况。
可访问性(Accessibility)监测页面的可访问性与优化建议。
最佳实践(Best Practice)页面是否符合最佳实践。
搜索引擎优化(SEO)页面是否针对搜索引擎结果排名进行了优化。

Lighthouse评分计算

  • 0 - 49(慢):红色
  • 50 - 89(平均值): 橙色
  • 90 - 100(快): 绿色

Lighthouse使用

  1. 使用chrome插件扩展
  2. 使用chrome调试面板中的LightHouse
  3. 通过命令行使用LightHouse

使用charome插件扩展

  1. 安装: chrome.google.com/webstore/de…
  2. 使用:在需要收集指标的页面,点击下Generate report。

image

使用chrome调试面板中的LightHouse

打开chrome的控制面板,选中Lighthose选项卡,即可配置生成报告。

image

通过命令行使用LightHouse

安装:

npm install -g lighthouse
# or use yarn:
# yarn global add lighthouse

使用: 执行lighthouse url 即可生成报告。

Bigo前端构建平台Almond

当然,也可以使用bigo研发平台Almond上的页面性能分析工具,对H5页面实现一键性能分析。H5上线前,需经过评测,各项性能指标达到内部要求的指标之后,才能上线。目前已累计评测页面超过1800个。

image

目前Bigo前端正在快速发展,团队规模超过100人,有nodejs、小游戏、中后台、c端业务、前端架构等多个技术方向,各个方向均有较好的实践,欢迎各位加入,共同成长,一起建设更专业的前端团队。

总结

利用Performace API,chrome Performace以及Lighthouse这几个工具,可以多维地了解页面的性能情况,了解、获取优化建议,从而可以对页面进行针对性的优化。

以上,如有错误,欢迎指正。

引用

10分钟彻底搞懂前端页面性能监控

Navigation Timing API

前端性能优化指南[6]--Web 性能标准

欢迎大家留言讨论,祝工作顺利、生活愉快!

我是bigo前端,下期见。