HonkAnything worth spreading.

Web 前端性能指标

性能分类

加载性能

请求资源时会受设备、浏览器、协议、网络类型和延迟等影响(CDN,ISP,缓存,代理,防火墙,负载均衡器和服务器)。

  • 首次绘制(FP,First Paint)

    标记浏览器渲染任何在视觉上不同于导航前屏幕内容的时间点。

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

    标记浏览器渲染来自 DOM 第一位内容的时间点,该内容可能是文本、图像等元素。

  • 首次有效绘制(FMP,First Meaningful Paint)

    标记浏览器已渲染出可以与用户互动的足够内容。每个网站对“哪些部分对用户最为有用”都有自己的定义。

  • 主角元素计时(Hero Element Timing)

    网页的这些“最重要部分”通常称为主角元素。例如,在新闻网站上,主角元素可能是重大新闻和置顶大图。

    在网页上,几乎总有一部分内容比其他部分更重要。 如果页面最重要的部分能迅速加载,用户可能不会注意到其余部分是否加载。

  • 耗时较长的任务(Long Tasks)

    浏览器是单线程,通过将任务添加到主线程上的队列等待逐个执行来响应用户输入。在某些情况下,运行这些任务可能要花费较长时间,这时主线程就会被阻塞,而队列中的所有其他任务都必须等待。

    应用有 100 毫秒的时间响应用户输入。如果超过此时间,用户就会认为应用反应迟缓。要实现小于 100 毫秒的响应,应用必须在每 50 毫秒内将控制返回给主线程,这样应用就可以执行其像素管道、对用户输入作出反应,等等。Long Tasks API 可以将任何耗时超过 50 毫秒的任务标示为可能存在问题,并向应用开发者显示这些任务。

  • 可交互时间(TTI,Time to Interactive)

    标记应用已进行视觉渲染并能可靠响应用户输入的时间点。TTI 指标可识别页面初始 JavaScript 已加载且主线程处于空闲状态(没有耗时较长的任务)的时间点。

  • 速度指标(Speed Index)

    表明网页填充页面内容的速度,分数越低越好。

  • 首次 CPU 闲置时间(First CPU Idle)

    首次 CPU 闲置时间,标记了网页的主线程首次有空处理输入操作的时间。

  • 潜在最久的首次交互延迟(Max Potential First Input Delay)

    测量用户首次与网站交互时(比如点击链接)到浏览器实际能够回应这次互动的时间范围,以毫秒为单位。

上述大部分指标可直接使用 Lighthouse 获取。

渲染性能

目前大多数设备的屏幕刷新率为 60 次/秒。因此,如果在页面中有一个动画或渐变效果,或者用户正在滚动页面,那么浏览器渲染动画或页面的每一帧的速率也需要跟设备屏幕的刷新率保持一致。

其中每个帧的预算时间仅比 16 毫秒多一点 (1 秒/ 60 = 16.66 毫秒)。但实际上,浏览器有整理工作要做,因此所有工作需要在 10 毫秒内完成。如果无法符合此预算,帧率将下降,并且内容会在屏幕上抖动,造成卡顿。

像素管道

像素至屏幕管道中的关键点:

完整的像素管道

  • JavaScript。一般来说,我们会使用 JavaScript 来实现一些视觉变化的效果。比如用 jQuery 的 animate 函数做一个动画、对一个数据集进行排序或者往页面里添加一些 DOM 元素等。除了 JavaScript,还有其他一些常用方法也可以实现视觉变化效果,比如:CSS Animations、Transitions 和 Web Animation API。
  • 样式计算。此过程是根据匹配选择器(例如 .headline 或 .nav > .nav__item)计算出哪些元素应用哪些 CSS 规则的过程。从中知道规则之后,将应用规则并计算每个元素的最终样式。
  • 布局。在知道对一个元素应用哪些规则之后,浏览器即可开始计算它要占据的空间大小及其在屏幕的位置。网页的布局模式意味着一个元素可能影响其他元素,例如 <body> 元素的宽度一般会影响其子元素的宽度以及树中各处的节点,因此对于浏览器来说,布局过程是经常发生的。
  • 绘制。绘制是填充像素的过程。它涉及绘出文本、颜色、图像、边框和阴影,基本上包括元素的每个可视部分。绘制一般是在多个表面(通常称为层)上完成的。绘制实际上分为两个任务: 1) 创建绘图调用的列表,以及 2) 填充像素(常称为“栅格化”)。
  • 合成。由于页面的各部分可能被绘制到多层,因此它们需要按正确顺序绘制到屏幕上,以便正确渲染页面。对于与另一元素重叠的元素来说,这点特别重要,因为一个错误可能使一个元素错误地出现在另一个元素的上层。

管道的每个部分都有机会产生卡顿,因此需准确了解代码触发管道的哪些部分。

性能测试

性能需要被测量、监测和完善。

实验数据(Lab data)

在开发人员可控的环境中(使用指定的设备和网络等)收集的性能数据。

优点

  1. 利于 Debug 性能问题
  2. 开发人员可亲身感受到实际的体验
  3. 测试环境可复用,测试数据可作比对

缺点

  1. 无法体现实际用户的性能瓶颈
  2. 无法与实际页面 KPI 相关联

工具

现场数据(Field data)

也叫真实用户监测,RUM。是从用户的实际体验中捕获的性能数据。

优点

  1. 代表实际用户的体验结果
  2. 可反映与业务关键绩效指标的相关性
  3. 可监测到异常情况

缺点

  1. 可获取的指标数受限
  2. 调试受限

工具

性能评估

体验 反馈 指标
是否发生? 导航是否成功启动?服务器是否有响应? 首次绘制 (FP)/首次内容绘制 (FCP)
是否有用? 是否已渲染可以与用户互动的足够内容? 首次有效绘制 (FMP)/主角元素计时
是否可用? 用户可以与页面交互,还是页面仍在忙于加载? 可交互时间 (TTI)
是否令人愉快? 交互是否顺畅而自然,没有滞后和卡顿? 在技术上不存在耗时较长的任务

RAIL 模型

可使用 Google 的 RAIL 模型评估性能。这是一种以用户为中心的性能模型,最终目标不是让网站在任何特定设备上都能运行很快,而是使用户满意。

RAIL 步骤 关键指标 用户操作
响应 输入延迟时间(从点按到绘制)小于 100 毫秒。 用户点按按钮(例如打开导航)。
动画 每个帧的工作(从 JS 到绘制)完成时间小于 16.66 毫秒。 用户滚动页面,拖动手指(例如,打开菜单)或看到动画。 拖动时,应用的响应与手指位置有关(例如,拉动刷新、滑动轮播)。 此指标仅适用于拖动的持续阶段,不适用于开始阶段。
空闲 主线程 JS 工作分成不大于 50 毫秒的块。 用户没有与页面交互,但主线程应足够用于处理下一个用户输入。
加载 页面可以在 1000 毫秒内就绪。 用户加载页面并看到关键路径内容。
  1. 应用有 100 毫秒的时间响应用户输入。如果超过此时间,用户就会认为应用反应迟缓。
  2. 每一帧动画应该要在 16.66 毫秒内完成,从而达到 60 帧每秒(1秒 ÷ 60 ≈ 16.66 毫秒)。但因为浏览器需要花费时间将新帧绘制到屏幕上,所以只有 10 毫秒来执行代码。
  3. 有些资源不需要马上用到,但是希望尽早获取,这时候就可以使用预加载。但也需根据实际情况减少预加载数据,以便应用快速加载,并利用空闲时间加载剩余数据。推迟的工作应分成每个耗时约 50 毫秒的多个块(要实现小于 100 毫秒的响应,应用必须在每 50 毫秒内将控制返回给主线程,这样应用就可以执行其像素管道、对用户输入作出反应,等等)。如果用户开始交互,优先级最高的事项是响应用户。
  4. 在 1 秒钟内加载好网站。否则,用户的注意力会分散,他们处理任务的感觉会中断。无需在 1 秒内加载所有内容以产生完整加载的感觉。启用渐进式渲染和在后台执行一些工作。将非必需的加载推迟到空闲时间段。侧重于优化关键渲染路径以取消阻止渲染。

开发模式

PRPL 模式

PRPL 模式是一种用于结构化和提供 Progressive Web App (PWA) 的模式,该模式强调应用交付和启动的性能。 它代表:

推送(Push):为初始网址路由推送关键资源。 渲染(Render):渲染初始路由。 预缓存(Precache):预缓存剩余路由。 延迟加载(Lazy Load):延迟加载并按需创建剩余路由。

优化关键渲染路径

优化关键渲染路径是指优先显示与当前用户操作有关的内容。

监测计划

实验数据

开发完成后在各自的电脑上运行 Lighthouse 查看结果。

主要监测指标

  1. 首次内容绘制(FCP,First Contentful Paint)
  2. 首次有效绘制(FMP,First Meaningful Paint)
  3. 速度指标(Speed Index)
  4. 首次 CPU 闲置时间(First CPU Idle)
  5. 可交互时间(TTI,Time to Interactive)
  6. 潜在最久的首次交互延迟(Max Potential First Input Delay)

因测试结果受开发人员电脑配置等因素有关,换其他人的电脑可能会出现差异较大的结果,数据难以用作对照,因此主要用于监测明显不足的地方。

现场数据

上述提到收集现场数据的工具都需付费,也可考虑先投入开发简易的监测工具并发送数据到 Goolge Analytics 来做统计。


参考资料: