前端性能优化实战

简介:引用彼得·德鲁克的一句话,“You can't manage what you can't measure。一件事如果你无法衡量它、你就无法管理它”,性能同样如此。如果没有一个准确的方案来对性能进行度量,那优化就无从谈起。那么对于我们来说,哪些指标是可以用来对页面性能、用户体验进行度量的呢?

作者 | 故梦
来源 | 阿里开发者公众号

You can't manage what you can't measure. —— Peter Drucker

度量

引语中提到了 彼得·德鲁克 的一句话,“一件事如果你无法衡量它、你就无法管理它”,性能同样如此。如果没有一个准确的方案来对性能进行度量,那优化就无从谈起。

那么对于我们来说,哪些指标是可以用来对页面性能、用户体验进行度量的呢?我会从如下几个角度逐一为大家讲解:

  • Performance API
  • 页面流畅度

    • FPS
    • raf(requestAnimationFrame)
  • 首屏性能

    • FP、FCP、FMP
    • CWV(Core Web Vitals)

Performance API

相信前端的同学对于 Performance API 应该都不陌生,通常我们将浏览器提供的可以进行测算和采集的 API 统称为 Performance API,该类型的对象可以通过调用只读属性 window.performance 来获得。

在日常的工作中,我们为了计算一个任务的耗时,通常会在任务执行前后利用 Date.now() 分别创建两个时间,最后取两者的差值作为任务执行耗时。但是 Date.now() 存在两个问题:

  • 返回的时间戳是从 1970 年 1 月 1 日 00:00:00 UTC 开始经过的毫秒数,依赖于系统时间
  • 精度仅到毫秒(ms)

为了对性能做精准的计算,我们可以选择 Performance API 提供的 performance.now() 来进行高精度计算,其特性为:

  • 时间戳基于页面打开的时间计算
  • 精度精确到微秒(us)

下图可以比较直观的看到两者的差异:



页面流畅度

FPS

帧率 FPS(Frames Per Second - 每秒传输帧数),一般对于网页而言,最优的帧率在 60 FPS,如果越接近这个值,页面就越流畅,帧率如果远低于这个值,用户可能会明显感觉到卡顿。

60 FPS 意味着页面每隔 16.5ms(1/60)就需要渲染一次,否则就会出现丢帧的现象,而浏览器中的 JavaScript 执行和页面渲染都是会相互阻塞的,如果在代码中有非常复杂的逻辑占用了大量的执行时长,就会导致页面出现卡顿。

在 Chrome 的 devtools 中我们可以执行 Cmd+Shift+P 输入 show fps 来快速打开 fps 面板,如下图所示:

通过观察 FPS 面板,我们可以很方便的对当前页面的流畅度进行监控

我们在代码中如果想对当前页面的 FPS 帧率进行监控,可以参考如下这段示例代码:

var lastTime = performance.now();
var frame = 0;
var lastFameTime = performance.now();
var loop = function(time) {var now = performance.now();var fs = (now - lastFameTime);lastFameTime = now;var fps = Math.round(1000/fs);frame++;if(now > 1000 + lastTime) {var fps = Math.round((frame * 1000) / (now - lastTime));frame = 0;lastTime = now;};window.requestAnimationFrame(loop);
}

requestAnimationFrame

window.requestAnimationFrame() 告诉浏览器你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。

这里借用 MDN 的描述,顾名思义就是传入一个函数,让浏览器在下一次渲染之前进行调用。那么基于这个特性,结合上面提供的 FPS 计算示例代码,我们可以发现,如果我们持续对 requestAnimationFrame 进行调用,那么每次调用的间隔应该在 16.7ms 左右,即满足我们对于页面流畅度 60 FPS 的要求,可以使用如下代码在控制台执行试试看:

let lastTime = 0;
const measure = () => {console.log(`${Date.now() - lastTime}ms`);lastTime = Date.now();requestAnimationFrame(measure);
};
measure();

首屏性能

首屏性能作为我们最关心的核心指标之一,在性能优化的场景中占据了相当大的比重,那么对于首屏的性能我们有哪些衡量指标呢?

针对这个问题,Google 曾经提出过一系列的以用户体验为中心的性能指标。

FP、FCP、FMP

FP(First Paint 译为“首次绘制”)代表浏览器第一次向屏幕传输像素的时间,仅表示当前已经开始绘制了,实际意义比较小。

FCP(First Contentful Paint 译为“首次内容绘制”)代表浏览器第一次向屏幕绘制 “内容”(只有首次绘制文本、图片(包含背景图)、非白色)。

相比之下,FCP 指的是浏览器首次绘制来自 DOM 的内容。例如:文本,图片,SVG,canvas元素等,这个时间点叫 FCP。

FMP(First Meaningful Paint 译为“首次有效绘制”)表示页面中有意义的内容开始出现在屏幕上的时间点。它也是我们来衡量用户加载体验的主要指标。

FMP 本质上是一个主观认知指标,是通过一个算法来猜测某个时间点可能是 FMP,但是计算方式过于复杂而且不准确,后来 Google 也放弃了 FMP 的探测算法,转而采用更加明确的客观指标 - LCP。

CWV(Core Web Vitals)

核心 Web 指标是适用于所有网页的 Web 指标子集,每位网站所有者都应该测量这些指标,并且这些指标还将显示在所有 Google 工具中。每项核心 Web 指标代表用户体验的一个不同方面,能够进行实际测量,并且反映出以用户为中心的关键结果的真实体验。

目前的 Web 核心指标由三个方面构成 — 页面加载性能、交互性、视觉稳定性,包含如下三个指标及阈值:

  • Largest Contentful Paint (LCP):最大内容绘制,测量加载性能。为了提供良好的用户体验,LCP 应在页面首次开始加载后的2.5 秒内发生。
  • First Input Delay (FID):首次输入延迟,测量交互性。为了提供良好的用户体验,页面的 FID 应为100 毫秒或更短。
  • Cumulative Layout Shift (CLS):累积布局偏移,测量视觉稳定性。为了提供良好的用户体验,页面的 CLS 应保持在 0.1. 或更少。

1)LCP

LCP 关注的是首屏中最大元素渲染渲染的时间,和 FCP 不同的是,FCP 更关注浏览器什么时候开始绘制内容,比如一个 loading 页面或者骨架屏,并没有实际价值,所以 LCP 相较于 FCP 更适合作为首屏指标。

拿 Detail 页举例,在 FCP 时,商品图片并未加载,此时对于用户而言,一个近乎白屏的页面是不具备可交互价值的,在 LCP 时,图片已经完成了加载,首屏主要元素也几乎加载完毕,此时的时间作为首屏时间,才是比较接近用户体感的。

既然 LCP 是根据页面上占据面积最大的元素渲染时间确定的,那么元素包含哪些呢?

  • 图片
  • 内嵌在 svg 中的 image 元素
  • 视频的封面
  • 通过 url() 加载的 background image
  • 文字

在 webpagetest 上可以很直观的看到当前 LCP 元素的详情信息

元素面积的计算规则有如下几点:

  • 在 viewport 内可见元素的大小,如果是超出可视区域或者被裁减、遮挡等,都不算入该元素大小
  • 对于图片元素来说,大小是取图片实际大小和原始大小的较小值,即Min(实际大小,原始大小)
  • 对于文字元素,只取能够覆盖文字的最小矩形面积
  • 对所有元素,margin、padding、border 等都不算

2)FID

FID 指标是指用户首次和网站进行交互到浏览器响应该事件的实际延时时间,可以想象一下,如果在你点击了一个 button 后,页面没有任何变化,2-3s 后才开始响应,可想而知体验是非常糟糕的。

FID 判定的交互行为有:

  • 点击、触摸、按键等(不包含滚动和缩放)
  • 有事件绑定的行为,比如注册在某个 dom 上的 click 事件

那么为什么会产生交互延迟呢?比如我在 button 上注册了一个 click 事件,例如:

btn.addEventListener('click', () => {// do something
})

按照预期,用户点击按钮的时候,回调函数会被直接触发,但是如果当前主线程被渲染、Long Tasks 占用,这个回调的执行就会被延后,就会导致 FID 时长增加。

但是 FID 作为一个“非客观值”,需要用户进行交互才能采集到,用户的交互时机,同样也会对指标的采集、统计造成影响。

3)CLS

CLS 是用来衡量视觉界面稳定性的一个指标,指的是页面产生的连续累计布局偏移分数。我们在日常业务中经常会用到懒加载、骨架屏等方式,用较低的成本先展示页面框架,再用动态渲染的方式,来对页面内容进行填充,如果此时布局发生变化,比如动态加载的元素和原本占位的元素大小不一致,可能就会导致用户误操作,影响用户体验,CLS 就是为了度量这类问题而存在。

当我们在说布局偏移的时候,指的是:页面中一个可见元素的起始位置发生改变,而元素的增删则并不会触发布局偏移。

那么如何定义偏移的连续累计呢?有如下几个要素:

  • CLS 计算的并非页面整个周期的偏移分数之和,而是累计值最高的连续布局偏移
  • 偏移相隔的时间少于 1s,且整个窗口的最大持续时间为 5s,则被计为连续偏移

分析工具

DevTools

DevTools 算是和前端同学打交道最多的工具之一了,主要用来查看日志、查看网络请求、debug 页面等等,我们同时还可以利用它对页面性能进行分析。

Network

如上图所示,这是我们很熟悉的 Network 界面,功能上我用红框大概做了一下划分:

  • 选项区:Preverse Log 可以在面板中保留网络请求,在页面重定向、当页跳转时可以保留之前页面的日志;Disable Cache可以屏蔽浏览器的 http 缓存机制;右侧的 No throtting 选择器可以对当前网络状态进行模拟(Fast 3G、Slow 3G 等等)
  • 请求列表、请求状态
  • 请求传输体积:默认展示 gzip/br 压缩后的大小
  • Waterfall:资源加载的时序和每一步的耗时

Performance

Performance 面板可以提供更加专业的性能信息

WebPageTest

WebPageTest是一个线上性能分析平台,除了常用的 cwv 性能数据外,还有 performance、lighthouse 报告、页面对比等功能。

输入 URL 后我们可以简单的选择一个 simple configuration 进行测试,默认会执行 3 次测试。这里我们可以看到页面的一些核心指标,可以点开对应的指标项进行更详细的分析,在 Waterfall 页面我们也可以很直观的看到当前页面的请求顺序、请求耗时、关键节点(FCP、LCP等等)

优化手段

网络传输优化

这里我们着重看三个时间指标:

  • Total Connection Time:整体的连接耗时
  • TTFB(Time to First Byte):首字节传输耗时
  • Content Download:内容传输耗时

Total Connection Time

导致连接耗时长的因素可能会有很多种:

  • 机器距离用户端的物理距离过长(美国 - 中国)
  • 重复建联,在页面中使用了多个不同域名,每次都需要重新建立连接
  • 用户端网络环境问题

那么为了解决这些问题我们可以采取哪些手段呢:

  • 利用 CDN 对主域名进行动态加速,对资源域名进行缓存,利用边缘节点的特性缩短用户请求距离
  • 利用 pre-connect 对域名进行预建联,同时对域名进行收拢,这样在 http2 的情况下可以减少建联耗时
  • 充分利用 http 缓存和 servicesworker 请求拦截的特性,对可缓存的资源进行本地缓存,减少发起网络请求次数

TTFB + Content Download

TTFB 是从发起请求到收到服务器请求第一个字节的时间,一般来说,如果首屏 html 请求的 TTFB 能达到 100ms 以内,就已经具备不错的体验了,如果超过了 500ms,那么用户就能明显的感受到白屏,精准的来说,TTFB 是在完成 DNS 查询、TCP 握手、SSL 握手后发起 HTTP 请求报文到接收到服务端第一个响应报文的时间差,大约等于 一个RTT(Round-Trip Time 即往返时延)+ ServerRT。

那么当 TTFB 耗时很长时,如何进行优化呢?可以参考如下几种方式:

  • 减少请求传输量,避免无用信息
  • 减少服务端处理时间(增加缓存、慢 SQL 治理等等)
  • 对首屏 HTML 内容做流式渲染,由于浏览器对 HTML 的解析并不依赖与下载完整的 HTML,而是解析一部分渲染一部分,所以服务端可以先将部分准备好的内容通过流式渲染的方式返回,而不是等全部内容就绪后再返回
  • 懒加载:优先返回必要内容,例如超长页面,可以先返回首屏看到的内容,剩下的通过异步加载的方式进行渲染,分多个接口进行请求

那么,是 TTFB 越短越好吗?

其实也不尽然,我们需要做好 TTFB 和 Content Download 的权衡,例如当我们开启 gzip/br 压缩的时候,TTFB 必然会呈上涨趋势,但是相对应的资源体积变小,就会加快传输耗时,减少 Content Download 时间,所以我们应该关注的用户真实的体验,而不是一味地盯着时间进行优化。

preload

preload 也就是预加载,关于预加载的方式有很多种,端内和端外也各自有不同的方案,比较常见的有:

  • preload 标签:
  • serviceworker 预加载:flasher、workbox-preload 等
  • zcache:在客户端端内通过资源离线包的方式进行预加载

相关链接

  • Lighthouse Scoring Calculator:Lighthouse Scoring calculator
  • WebPageTest:WebPageTest - Website Performance and Optimization Test
  • Web Vitals:Web Vitals
  • web-vitals - Github:GitHub - GoogleChrome/web-vitals: Essential metrics for a healthy site.

原文链接

本文为阿里云原创内容,未经允许不得转载。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/510882.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Elastic与阿里云助力汽车及出行产业数字化转型

简介:目前,阿里云和Elastic在全国已经有很多的项目正在开展合作,而在移动出行领域与享道出行的合作案例,则是代表性的。 在汽车产业变革逐步深入的当下,云计算、大数据等信息技术成为了汽车企业经历数字化转型时的“刚…

企业版Spark Databricks + 企业版Kafka Confluent 联合高效挖掘数据价值

简介:本文介绍了如何使用阿里云的Confluent Cloud和Databricks构建数据流和LakeHouse,并介绍了如何使用Databricks提供的能力来挖掘数据价值,使用Spark MLlib构建您的机器学习模型。 前提条件 已注册阿里云账号,详情请参见阿里云…

解决微服务架构下流量有损问题的实践和探索

简介:绝⼤多数的软件应⽤⽣产安全事故发⽣在应⽤上下线发布阶段,尽管通过遵守业界约定俗成的可灰度、可观测和可滚回的安全⽣产三板斧,可以最⼤限度的规避发布过程中由于应⽤⾃身代码问题对⽤户造成的影响。但对于⾼并发⼤流量情况下的短时间…

5月25日,阿里云开源 PolarDB-X 将迎来升级发布

简介:2022年5月25日,阿里云开源 PolarDB-X 将升级发布新版本!PolarDB-X 从 2009 年开始服务于阿里巴巴电商核心系统, 2015 年开始对外提供商业化服务,并于 2021 年正式开源。本次发布会将重磅推出在稳定性、生态融合以…

技术分享丨云企业网CEN2.技术揭晓

简介:随着企业数字化转型的加速,越来越多的企业选择了将业务部署在云上,这其中有超过20%的企业有全球组网的需求,这就使得云上网络的规模越来越大,复杂度也越来越高,为了应对这些变化,阿里云推出…

MAE 自监督算法介绍和基于 EasyCV 的复现

简介:自监督学习(Self-Supervised Learning)能利用大量无标注的数据进行表征学习,然后在特定下游任务上对参数进行微调。通过这样的方式,能够在较少有标注数据上取得优于有监督学习方法的精度。近年来,自监…

企业实践|分布式系统可观测性之应用业务指标监控

简介:本文主要讲述如何建立应用业务指标Metrics监控和如何实现精准告警。Metrics 可以翻译为度量或者指标,指的是对于一些关键信息以可聚合的、数值的形式做定期统计,并绘制出各种趋势图表。透过它,我们可以观察系统的状态与趋势。…

1024 程序员节城市嘉年华,共话技术生涯的一万种可能!

更硬核的技术峰会,更多元的主题论坛,更丰富的科技元素……更热血的 1024 程序员节闪亮登场!由湖南湘江新区管委会主办,长沙工业与信息化局、长沙信息产业园管委会与 CSDN 联合承办的第三届 2022 1024 程序员节将于 10 月 22 - 24 …

作业帮在线业务 Kubernetes Serverless 虚拟节点大规模应用实践

简介:目前方案已经成熟,高峰期已有近万核规模的核心链路在线业务运行在基于阿里云 ACKECI 的 Kubernetes Serverless 虚拟节点。随着业务的放量,未来运行在 Serverless 虚拟节点上的服务规模会进一步扩大,将节省大量的资源成本。 …

浅析微服务全链路灰度解决方案

简介:帮助应用发布版本过程中更精细化,提高了发布过程中的稳定性。服务转移⾄请求链路上进行流量控制,有效保证了多个亲密关系的服务顺利安全发布以及服务多版本并⾏开发,进⼀步促进业务的快速发展。 作者: 十眠&…

译:零信任对 Kubernetes 意味着什么

这篇是 Buoyant 的创始人 William Morgan 文章《# What Does Zero Trust Mean for Kubernetes?》[1]的翻译,文章很好的解释了什么是零信任、为什么要实施零信任,以及服务网格如何以最小的代码实现零信任。零信任是营销炒作,还是新的机会&…

Serverless 应用中心:Serverless 应用全生命周期管理平台

简介:Serverless 应用中心,是阿里云 Serverless 应用全生命周期管理平台。通过 Serverless 应用中心,用户在部署应用之前无需进行额外的克隆、构建、打包和发布操作,即可快速部署和管理应用。Serverless 应用中心帮助用户快速联动…

云钉一体:EventBridge 联合钉钉连接器打通云钉生态

简介:今天,EventBridge 联合钉钉连接器,打通了钉钉生态和阿里云生态,钉钉的生态伙伴可以通过通道的能力驱动阿里云上海量的计算力。 作者:尘央 背景 “以事件集成阿里云,从 EventBridge 开始”是 EventB…

开源当道,群英荟萃!1024 程序员节北京峰会火热来袭

1024 程序员节,致敬每一位二进制世界的主角。由开放原子开源基金会主办,北京经开区国家信创园、CSDN 承办的 2022 1024 程序员节北京峰会将于 10 月 24 日精彩来袭。以“软件新时代 开源创未来”为主题,聚焦开源新潮流,诚邀广大程…

超全,一图了解 2022 长沙 · 中国 1024 程序员节!

超全版来啦!2022 长沙 中国 1024 程序员节重磅大咖再聚,共话中国技术新生态你想了解的全在这里收藏!收藏!收藏!

1024 程序员节技术英雄会鸣锣开场,问道中国技术新生态

战鼓鸣,英雄至。10 月 24 日,2022 长沙中国 1024 程序员节重磅环节“技术英雄会”鸣锣开场!中国工程院院士、开源掌门人领衔,各领域专家、精英云集,围绕本届大会主题“算力新时代,开源创未来”,…

无尽创想!CSDN 1024 大赛重磅发布

在构建科技世界的过程中,1024 这个数字被赋予了特殊的意义,它代表着广大的程序员群体,更蕴藏着无穷的想象力与价值。在 1024 程序员节发展为程序员的盛会之后,1024 大赛应运而生,并作为 1024 程序员节全新的板块重磅发…

小镇青年程序员的逆袭人生:从差点回老家到荔枝技术骨干

编者按: 1024 是 2 的十次方,是二进制计数的基本计量单位之一。在计算机的发展史中,在和 0/1 所代表的二进制世界里,有人用代码编织出了形形色色的数字、程序、互联网,创造出一个个神话。 ——他们就是一群可爱、低调…

1024统信举办首届技术开放日,硬核技术引领操作系统“大迁移”

10月24日程序员节之际,统信软件首届技术开放日在国家信创园区圆满落下帷幕。统信软件首届技术开放日囊括UP主直播互动、打卡探园、“大迁移”主题论坛、全系产品体验等精彩环节。来自统信软件研发部门负责人、行业专家、技术大咖以及专业媒体代表百余人莅临活动现场…

FFA 议程上线!实时化浪潮下,Apache Flink 还将在大数据领域掀起怎样的变革?...

Flink Forward Asia 2022 将于 11 月 26-27 日在线上举办,议程内容正式上线!今年是 Flink Forward Asia(下文简称 FFA)落地中国的第五个年头,也是 Flink 成为 Apache 软件基金会顶级项目的第八年。过去这几年&#xff…