首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >基于 RUM 的前端优化理论与实践 - 性能篇(一)

基于 RUM 的前端优化理论与实践 - 性能篇(一)

作者头像
腾讯云可观测平台
发布于 2021-09-10 10:11:35
发布于 2021-09-10 10:11:35
98000
代码可运行
举报
运行总次数:0
代码可运行

作者:李振,腾讯云前端性能监控负责人

前言

对于前端来说,最重要的是体验,而在前端体验中,最为核心的就是性能。

相信大多数用户接入前端性能监控(RUM)都是为了通过 RUM 质量评价体系来验证前端性能和质量如何,而直接影响性能和质量的则是一系列的指标,因此了解页面性能指标显得格外重要!

前端性能监控 RUM 是腾讯云的大前端领域页面质量和性能监控平台,聚焦提升用户体验。了解详情

通俗点说,某用户想了解页面访问速度快,是否快,究竟有多快?怎么衡量?需要一个中立的裁判来裁决,而 RUM 的角色正是这个裁判。

本文会结合前端监控 SDK 源码 - Aegis 和 Google 最新的页面性能规范为大家讲解下列两大个主题:

1.前端页面性能关键指标的规范和计算规则。

2.如何看懂 RUM 可视化图表?并通过图表数据进行项目优化?

页面性能指标有哪些?

在前端监控中指标众多繁杂,例如:白屏时间、首屏时间、FCP、FMP、LCP、FID、TTFB等等,一般人难以把握。我们从中抽取一些最常见,最实用的规范跟大家一一解释。

  • 网络连接瀑布图(TL;DR)

要解释这些指标,还是要先祭出网络连接瀑布图,想必只要对页面性能稍有了解的用户都见过这张图。

与这张图一一对应的,是浏览器里面的 `performance.timing` 属性,我们将其同时打印出来,做一个数据的对比说明。

  • navigationStart: 表示从上一个文档卸载结束时的 unix 时间戳,如果没有上一个文档,这个值将和 fetchStart 相等。
  • unloadEventStart: 表示前一个网页(与当前页面同域)unload 的时间戳,如果无前一个网页 unload 或者前一个网页与当前页面不同域,则值为 0。
  • unloadEventEnd: 返回前一个页面 unload 时间绑定的回调函数执行完毕的时间戳。
  • redirectStart: 第一个 HTTP 重定向发生时的时间。有跳转且是同域名内的重定向才算,否则值为 0。
  • redirectEnd: 最后一个 HTTP 重定向完成时的时间。有跳转且是同域名内部的重定向才算,否则值为 0。
  • fetchStart: 浏览器准备好使用 HTTP 请求抓取文档的时间,这发生在检查本地缓存之前。
  • domainLookupStart/domainLookupEnd: DNS 域名查询开始/结束的时间,如果使用了本地缓存(即无 DNS 查询)或持久连接,则与 fetchStart 值相等
  • connectStart: HTTP(TCP)开始/重新 建立连接的时间,如果是持久连接,则与 fetchStart 值相等。
  • connectEnd: HTTP(TCP) 完成建立连接的时间(完成握手),如果是持久连接,则与 fetchStart 值相等。
  • secureConnectionStart: HTTPS 连接开始的时间,如果不是安全连接,则值为 0。
  • requestStart: HTTP 请求读取真实文档开始的时间(完成建立连接),包括从本地读取缓存。
  • responseStart: HTTP 开始接收响应的时间(获取到第一个字节),包括从本地读取缓存。
  • responseEnd: HTTP 响应全部接收完成的时间(获取到最后一个字节),包括从本地读取缓存。
  • domLoading: 开始解析渲染 DOM 树的时间,此时 Document.readyState 变为 loading,并将抛出 readystatechange 相关事件。
  • domInteractive: 完成解析 DOM 树的时间,Document.readyState 变为 interactive,并将抛出 readystatechange 相关事件,注意只是 DOM 树解析完成,这时候并没有开始加载网页内的资源。
  • domContentLoadedEventStart: DOM 解析完成后,网页内资源加载开始的时间,在 DOMContentLoaded 事件抛出前发生。
  • domContentLoadedEventEnd: DOM 解析完成后,网页内资源加载完成的时间(如 JS 脚本加载执行完毕)。
  • domComplete: DOM 树解析完成,且资源也准备就绪的时间,Document.readyState 变为 complete,并将抛出 readystatechange 相关事件。
  • loadEventStart: load 事件发送给文档,也即 load 回调函数开始执行的时间。
  • loadEventEnd: load 事件的回调函数执行完毕的时间。

根据上述的定义,我们总结出来常见的页面指标的计算公式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 计算加载时间getPerformanceTiming() {const t = performance.timing;const times = {};// 页面加载完成的时间,用户等待页面可用的时间  times.loadPage = t.loadEventEnd - t.navigationStart;// 解析 DOM 树结构的时间  times.domReady = t.domComplete - t.responseEnd;// 重定向的时间  times.redirect = t.redirectEnd - t.redirectStart;// DNS 查询时间  times.lookupDomain = t.domainLookupEnd - t.domainLookupStart;// 读取页面第一个字节的时间  times.ttfb = t.responseStart - t.navigationStart;// 资源请求加载完成的时间  times.request = t.responseEnd - t.requestStart;// 执行 onload 回调函数的时间  times.loadEvent = t.loadEventEnd - t.loadEventStart;// DNS 缓存时间  times.appcache = t.domainLookupStart - t.fetchStart;// 卸载页面的时间  times.unloadEvent = t.unloadEventEnd - t.unloadEventStart;// TCP 建立连接完成握手的时间  times.connect = t.connectEnd - t.connectStart;return times;}

RUM使用了哪些性能指标?

下列我通过各前主流图表来深入了解 RUM 的性能指标。

  • 页面加载瀑布图

瀑布图是表示网站资源如何下载、由引擎解析的图表,其包含首耗时、请求响应等8个性能指标,它让我们可以查看资源之间的顺序和依赖关系。有助于确定加载过程中发生重要事件的位置,还可以让用户轻松看到他们的网站性能的好坏,从而准确显示哪些速度正在减慢网站性能。

Aegis SDK 源码中对其的计算规则如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const t: PerformanceTiming = performance.timing;if (!t) return;// 这里不知道为什么有时候 t.loadEventStart - t.domInteractive 返回一个很大的负数,暂时先简单处理let resourceDownload = t.loadEventStart - t.domInteractive;if (resourceDownload < 0) resourceDownload = 1070;result = {dnsLookup: t.domainLookupEnd - t.domainLookupStart,tcp: t.connectEnd - t.connectStart,ssl: t.secureConnectionStart === 0 ? 0 : t.requestStart - t.secureConnectionStart,ttfb: t.responseStart - t.requestStart,contentDownload: t.responseEnd - t.responseStart,domParse: t.domInteractive - t.domLoading,resourceDownload};

备注:`resourceDownload` 有时会出现一个极大的负数,所以做了简单兼容,取了几个项目的平均值。其他的页面性能指标计算规则大家可以通过代码比较直观的看出来。

RUM  中有一个首屏时间,那么Aegis SDK 是如何计算这个指标的呢?

1. 默认通过 MutationObserver 这个 API 来监控浏览器 document 对象的 DOM 变化,只计算在首屏内的 DOM 元素,把 DOM 变化时间作为 x 轴,单位时间内 DOM 变化的数量作为 y 轴,绘制曲线后,我们找到 DOM 变化最高点,认为是首屏完成。

2. 如果开发者觉得该算法不准确,希望自己标记 DOM 元素,可以添加属性 <div AEGIS-FIRST-SCREEN-TIMING></div>,把某个元素识别为首屏关键元素,SDK 认为只要用户首屏出现此元素就是首屏完成。也可以添加属性 <div AEGIS-IGNORE-FIRST-SCREEN-TIMING></div>,把该 DOM 列入黑名单。

除了上述的数据外,RUM 还根据上报的数据计算了以上几个页面性能相关的指标。计算公式如下:

1. 首字节(TTFB) = DNS + SSL +TCP + TTFB

2. DOM Ready = DNS + SSL +TCP + TTFB + ContentDownload + DomParse

3. 页面完全加载 =DNS + SSL +TCP + TTFB + ContentDownload + DomParse + ResourceDownload

  • 良好网站的基本指标- Web Vitals

上述计算首屏的算法是 Aegis SDK 自主提供的算法,用户场景千变万化,无法覆盖所有场景,而且这个算法也无法得到所有开发者的认同。这个时候就需要祭出 Web Vitals 了。

什么是 Web Vitals?

Google 给的定义是一个良好网站的基本指标 (Essential metrics for a healthy site)。

为什么还要再定义一个新的指标集呢?

因为过去要衡量一个好的网站,需要使用的指标太多,推出 Web Vitals 是简化这个学习的曲线,站主只要关注 Web Vitals 指标表现即可。

目前 Google 的 Web Vitals  源码 中提供了5个指标,分别为:

1. CLS(Cumulative Layout Shift - 累积布局移位): CLS 会衡量在网页的整个生命周期内发生的所有意外布局偏移的得分总和。得分是零到任意正数,其中 0 表示无偏移,且数字越大,网页的布局偏移越大。

2. FCP(First Contentful Paint - 首次内容绘制):FCP 度量从页面开始加载到页面内容的任何部分呈现在屏幕上的时间,页面内容包括文本、图像(包括背景图像)、<svg>元素或非白色的<canvas>元素。

3. FID(First Input Delay - 首次输入延迟):从用户首次与您的网页互动(点击链接、点按按钮,等等)到浏览器响应此次互动之间的用时。这种衡量方案的对象是被用户首次点击的任何互动式元素。

4. LCP(Largest Contentful Paint - 最大内容绘制):LCP 度量从用户请求网址到在视口中渲染最大可见内容元素所需的时间。最大的元素通常是图片或视频,也可能是大型块级文本元素。

5. TTFB (Time To First Byte - 从服务器接收到第一个字节耗时) TTFB 是发出页面请求到接收到应答数据第一个字节的时间总和,它包含了 DNS 解析时间、 TCP 连接时间、发送 HTTP 请求时间和获得响应消息第一个字节的时间。

目前 RUM 采有了其中最重要的三个属性:LCP,FID 和 CLS。

这里可以看出与之前 “首屏时间” 比较模糊的定义不同,Google 对 Web Vitals 给出了非常明确的指标定义,并且官方提供了算法支持,那么我们是不是可以直接用 LCP 取代我们自己写的 “首屏算法” 呢?目前显然还是不可行的,由于 LCP 底层使用的是 PerformanceObserver ,还存在兼容性问题,因此短期内还无法完全替代。

不过,在可预见的未来,Web Vitals 会成为业界的主流衡量标准,到那个时候,我们也可以卸下历史包袱,全面拥抱开源算法了。

如何分析性能数据&指导开发优化?

拥有了 RUM  这个好用的工具,下面就可以用数据指导开发和决策了。

我们的项目接入到 RUM 后,怎么样根据 RUM 展示的数据来优化项目呢?

  • 优化举例

下列拿某团队邀请我们对其项目做的一次针对性优化举例。

首先开发者的核心诉求是页面响应快,性能好。而上图这个数据无论如何都称不上快,可以看到首屏时间达到了 4.8s,LCP 的时间超过了 4s,仅仅达到了 “POOR” 的级别,CLS 的数据也不容乐观。

我们首先仅从表面数据进行分析,对比了该项目下全部页面的数据,通过 “Top访问页面”  tab 对页面进行分析,先按照 “首屏时间” 倒排序。

这里发现了第一个问题,开发者把多个项目的页面都使用了同一个上报ID进行上报,导致一些比较差的页面对整体数据产生了影响,因此我们建议用户尽可能根据代码组织和业务组织的方式区分不同的上报ID,方便定点发现问题。

排除了页面的干扰,我们再分析一下网络和区域干扰。

从上图可以看出来,网络状况和地区差异对页面首屏数据影响都不是很大。

再回到前面的瀑布图,从图中可以看到该项目主要的瓶颈其实在 “资源加载” 的耗时。通过对用户页面的资源加载情况进行分析,立刻找到了原因。

用户使用的是 React 框架,在没有服务端渲染的情况下,页面是会在加载主 JS 后才渲染的,而用户大部分 JS 文件都打包成一个 bundle ,导致产生了一个超大的 JS 文件,这个 JS 文件就成为了用户页面渲染的瓶颈。除此之外还发现了该 JS 文件没有支持 HTTP2 协议。

  • 资源加载优化

根据上述数据显示,我们建议用户做以下优化:

1. 拆包,通过把公共外部依赖打包成为 vendor,并且对组件做异步加载。

2. 去掉一些非必需的包,比如用户引入了全量的 lodash,让其改成 lodash-es,方便 webpack 做 treeshaking;去掉仅为了把某个时间做格式化而引入的 moment;去掉 jquery,而当初引入 jquery 仅仅为了查询某个元素而,真是得不偿失。

3. 建议使用 webpack-bundle-analyzer 对打包后的代码进行分析,查看哪些包不需要引用,或者可以单独打包。

4. 网络协议方面全面引入 HTTP2,合并了一些小的静态资源,把一些小的 svg 改成了 base64。

通过简单的分析,找到页面性能洼地,用户根据建议简单优化,效果十分显著,全量发布后不久数据就得到大幅提升,首屏时间从 4.8s 优化到 3.2s,最重要的是 “资源加载” 耗时直接减半。

然后发现了另外一个问题,用户的 “资源加载” 时间已经大幅度降低了,但是为什么 “首屏耗时” 没有相应的同比降低呢?

我们通过对用户页面分析发现,该页面在加载完成后,会执行非常多的 JS 代码逻辑,包括一些数据上报,用户行为收集,还有加载侧边栏,弹出广告等。这里带来了 2 个问题。

1. 页面主进程阻塞严重,Aegis SDK 的一些逻辑在执行的时候受到了影响,导致实际执行时间要晚于设定的时间,所以上报的“首屏耗时”其实要比实际晚的。

2. 用户的页面会在首屏完成后,继续加载很多DOM元素,也就是有很多 DOM 元素的变化,导致了 Aegis SDK 计算出来的首屏时间也要晚于真实的“首屏时间”。

于是我们建议用户把一些非必要操作都放在定时器中执行,以提升页面性能,提升用户体验。用户根据我们的建议通过定时器和异步改造,又大幅度提升了页面的“首屏时间”。

这个时候的“首屏耗时”已经是优化之初的 1/2 了,对于大多数用户来说,50% 的性能提升其实已经可以去交差了,但是我们看到用户另外几个指标依然不是很完美。其中 CLS 的得分一直是 “POOR” 的状态。

  • CLS 指标优化

CLS 指的是页面布局偏移量,再次简单分析,我们发现用户有一个长列表是页面主要渲染内容,该列表存在的问题是:因为数据不多,一般在 4 - 10 条数据,所以开发者没有对列表做分页。

没有分页带来的问题是,列表无法在渲染之初就确定长度,导致获取数据后渲染列表的时候页面发生较大的偏移,同时也带来了超多的 DOM 变化。

这个是导致 CLS 大的核心原因,当然也带来了 “首屏耗时” 的同步增加,除此之外,前面提到的一些异步数据,如广告挂件等也带来了这个问题。

给用户的建议如下:

1. 在一开始就确定列表高度(加入分页),通过骨架屏优化加载效果,同时减少 DOM 变化。

2. 广告挂件使用绝对布局,使其脱离文档流,减少DOM变化。

3. 一些其他元素,如图片等,确定长度和宽度属性,这些值允许浏览器在将图像渲染到位之前保留视觉空间。

4. 一些元素的变化,通过 CSS 实现,而不是使用 JS 改变元素属性实现。

再次优化后用户页面首屏和 CLS 数据变化惊人,达到了业界主流水平。最后我们看一下整体数据效果。

就目前的数据来看,用户页面性能仍然有可提升空间,更深层次的优化需要借助 Chrome Performance 工具进行了解,我们会以这个主题另开一篇文章进行讲解和分析,敬请期待。

总结

以上仅仅是我们使用 RUM 做优化的凤毛麟角,其中涉及到的知识都是前端开发耳熟能详的。我们旨在通过好用的工具,指导开发同学做决策,从而达到优化的效果。引用 Lord Kelvin 的一句名言,如果你无法衡量它,你就无法提升它。

联系我们

如有任何问题,欢迎扫码添加云监控助手为好友,备注 RUM,入群交流。

点击阅读原文,立即体验 RUM

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-09-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯云可观测 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
超全对照!前端监控的性能指标与数据采集
导语 | 前端监控可以让你更了解自己的网站,更早地发现和解决存在的问题,再通过优化来提升网站的性能和体验。那么,如何衡量一个网站的好坏?有什么指标?性能数据如何采集?本文围绕这些问题和你一起探讨。 一、为什么要做前端性能监控 可能你也有过这样的经历: 有用户反馈你的网站很慢,然后你立马紧张地在浏览器上打开用户反馈的网站。经过检查,可能你的网站一切正常,也可能你的网站真的很慢,甚至打不开了。 有一天老板问你:“咱们的网站性能体验怎么样?”你该如何回答?“挺好的,很快,这个月没有发生过故障....”老板再
腾讯云开发者
2021/06/02
4.4K0
腾讯前端团队是如何做web性能监控的?
也许你有听过一个问题,你这款 web 应用性能怎么样呀?你会回答什么呢?是否会优于海量 web 应用市场呢?本文就来整理下如何进行 web 性能监控?包括我们需要监控的指标、监控的分类、performance 分析以及如何监控。
zz_jesse
2020/06/24
7.9K0
腾讯前端团队是如何做web性能监控的?
目前为止整理最全的前端监控体系搭建篇(长文预警)
PV(page view) 是页面浏览量,UV(Unique visitor)用户访问量。PV 只要访问一次页面就算一次,UV 同一天内多次访问只算一次。
前端达人
2022/04/18
13.3K1
目前为止整理最全的前端监控体系搭建篇(长文预警)
Web 性能优化-首屏和白屏时间
白屏时间是指浏览器从响应用户输入网址地址,到浏览器开始显示内容的时间。 首屏时间是指浏览器从响应用户输入网络地址,到首屏内容渲染完成的时间。
李振
2021/11/26
3.1K0
Web 性能优化-首屏和白屏时间
【案例分享】腾讯游戏说:从 Web 性能评估探寻前端优化策略
刘馨忆 腾讯 IEG 公共数据平台部前端开发工程师,硕士毕业于英国曼彻斯特大学。主要负责内容生态相关toB 业务系统的开发,对内容审核链路、数据可视化看板有丰富的开发经验。 前言 作为一名前端开发者,想必你一定知道前端技术的迅猛发展。每过一段时间都会有热火朝天的新技术或者新开发方式,前端开发者也经常嘲讽“求不要更新了,学不动了”、“一入前端深似海”等。随着前端技术和业务的发展,我们也难免会遇到前端项目重构的问题,那究竟该如何评估目前前端技术框架的质量,众多性能指标我们该如何衡量呢? 本文将介绍新一代 We
腾讯云可观测平台
2022/03/18
1.1K0
如何使用Performance API 来衡量应用性能?
从历史上看,我们对客户端性能监控方式非常有限,而且还遇到了API浏览器的限制,阻碍了我们准确地衡量客户端性能。
泯泷、
2024/03/11
2630
浏览器的performance API与页面首屏加载分析
现代浏览器提供了performance(性能)这个API来帮助我们分析页面的加载性能,从MDN上可以看到从IE9时代(约2011年)就开始支持了,所以目前来说兼容性还算可以,所以可以研究一下这个API具体有啥功能。
用户1749219
2021/04/09
2.7K0
浏览器的performance API与页面首屏加载分析
10分钟彻底搞懂前端页面性能监控
前端页面性能是一个非常核心的用户体验指标。本文介绍阿里UC 岳鹰全景监控平台 如何设计一个通用、低侵入性、自动上报的页面性能监控方案。主要采用的是Navigation Timing API以及sendBeacon等方法。
杂货铺老板
2019/10/18
2.1K0
10分钟彻底搞懂前端页面性能监控
Chrome Dev Tools 之 Performance
作为前端开发,肯定对 Chrome 的 dev tools 不陌生,除了日常 Debug,还提供了一个非常强大的功能:performance 用做性能分析。
CS逍遥剑仙
2020/02/01
1.7K0
前端性能监控
主要对 W3C 工作小组提出的各个草案和标准做了一些解读,各个草案的时间点,以及关注的内容等。
上山打老虎了
2022/06/15
1.7K0
前端性能监控
ACP互联网架构认证笔记-ARMS业务实时监控服务
ARMS是一款阿里云应用性能管理(APM)类监控产品。一共提供三种监控,应用监控,前端监控,自定义监控。
freesan44
2021/10/12
1.3K0
拯救你的年底 KPI:前端性能优化
(给全栈前端精选加星标,提升前端技能) 原文地址:https://juejin.cn/post/6911472693405548557 作者:贩卖焦虑 前言 性能优化 ,每个工程师跑不掉的一个话题。
Nealyang
2021/01/13
1.1K0
拯救你的年底 KPI:前端性能优化
【总结】2072- 前端常见性能优化策略
采用域名分片技术,将资源放到不同的域名下。接触同一个域名最多处理6个TCP链接问题。
pingan8787
2024/06/19
2220
【总结】2072- 前端常见性能优化策略
前端埋点数据收集及上报方案
埋点,它的学名是事件追踪(Event Tracking),主要是针对特定用户行为或业务过程进行捕获、处理和发送的相关技术及实施过程。埋点是数据领域的一个专业术语,也是互联网领域的一个俗称。
落落落洛克
2021/10/12
7.2K0
window.performance 网页性能计算
performance 是 浏览器提供的一个js对象,里面存储了各种性能指标。
shirishiyue
2018/11/16
1.8K0
window.performance 网页性能计算
使用performance进行网页性能监控
由于项目需要, 需要对网页的一些性能进行监控, 接触到了performance, window.performance 提供了一组精确的数据,经过简单的计算就能得出一些网页性能数据, 将这些数据存储为
用户1741436
2018/05/16
1.8K0
页面性能监测之performance
最近,需要对业务上的一些性能做一些优化,比如降低首屏时间、减少核心按钮可操作时间等的一些操作;在这之前,需要建立的就是数据监控的准线,也就是说一开始的页面首屏数据是怎样的,优化之后的数据是怎样,需要有一个对比效果。此时,performance 这个API就非常合适了。
Tiffany_c4df
2019/09/04
2.1K0
页面性能监测之performance
Web页面全链路性能优化指南
性能优化不单指优化一个页面的打开速度,在开发环境将一个项目的启动时间缩短使开发体验更好也属于性能优化,大文件上传时为其添加分片上传、断点续传也属于性能优化。在项目开发以及用户使用的过程中,能够让任何一个链路快一点,都可以被叫做性能优化。
唐志远
2022/10/27
2K0
Web页面全链路性能优化指南
从零开始搭建前端数据监控系统(二)-前端性能监控方案调研
1. 业界案例 目前前端性能监控系统大致为分两类:以GA为代表的代码监控和以webpagetest为代表的工具监控。 代码监控依托于js代码并部署到需监控的页面,手动计算时间差或者使用浏览器的的API进行数据统计。 影响代码监控数据的因素有以下几种: 浏览器渲染机制; 浏览器对API的实现程度,比如performance API; 工具监控不用将统计代码部署到页面中,一般依托于虚拟机。以webpageTest为例,输入需统计的url并且选择运行次url的浏览器版本,webpageTest后台虚拟机对url进
寒月十八
2018/01/30
2.6K0
从零开始搭建前端数据监控系统(二)-前端性能监控方案调研
深入分析window.performance以及上报收集到数据(前端性能监控)
Web Performance提供了可以通过的函数(performance 属性提供)测试当前网页或者 web应用的性能,获取更为精确的原始数据,以毫秒为单位。一般放在window.onload事件中读取各种数据,有些值必须在页面完全加载之后才能得出。
can4hou6joeng4
2023/11/29
6510
推荐阅读
相关推荐
超全对照!前端监控的性能指标与数据采集
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档