- 原文地址:Front-End Performance Checklist 2019 — 3
- 原文做者:Vitaly Friedman
- 译文出自:掘金翻译计划
- 本文永久连接:github.com/xitu/gold-m…
- 译者:Starrier
- 校对者:kikooo,Jingyuan0000
让 2019 来得更迅速吧~你正在阅读的是 2019 年前端性能优化年度总结,始于 2016。php
[译] 2019 前端性能优化年度总结 — 第一部分 [译] 2019 前端性能优化年度总结 — 第二部分 [译] 2019 前端性能优化年度总结 — 第三部分 [译] 2019 前端性能优化年度总结 — 第四部分 [译] 2019 前端性能优化年度总结 — 第五部分 [译] 2019 前端性能优化年度总结 — 第六部分css
2015 年,Google 推出了 Brotli,一种新开源的无损数据格式,现已被全部现代浏览器所支持。实际上,Brotli 比 Gzip 和 Deflate 有效得多。由于它比较依赖配置,因此这种压缩可能会(很是)慢,但较慢的压缩意味着更高的压缩率。不过它解压速度很快。因此你能够考虑 Brotli 为你的网站所节省的成本。html
只有用户经过 HTTPS 访问站点时,浏览器才会接受这种格式。那代价是什么呢?Brotli 并无预安装在一些服务器上,因此若是没有自编译 Nginx,那么配置就会相对困难。尽管如此,它也并不是是不可攻破的难题,好比,Apache 自 2.4.26 版本起,开始逐步对它进行支持。得益于 Brotli 被众多厂商支持,许多 CDN 也开始支持它(Akamai、AWS、KeyCDN、Fastly、Cloudlare、CDN77),你甚至(结合 service worker 一块儿使用)能够在不支持它的 CDN 上,启用 Brotli。前端
在最高级别压缩时,Brotli 会很是缓慢,以致于服务器在开始发送响应前等待动态压缩资源所花费的时间,可能会抵消文件大小(被压缩后)的潜在增益。但对于静态压缩,应该首选更高级别的压缩。android
或者,你能够考虑使用将数据编码为 Deflate、Gzip 和 Zlib 格式的 Zopfli 的压缩算法。任何普通的 Gzip 压缩资源均可以经过 Zopfli 改进的 Deflate 编码达到比 Zlib 的最大压缩率小 3% 到 8%的文件大小。问题是压缩文件大约须要耗费 80 倍的时间。这就是为何在资源上使用 Zopfli 是个好主意,由于这些资源不会发生太大的变化,它们被设计成只压缩一次但能够下载屡次。ios
若是能够下降动态压缩静态资源的成本,那么这种付出是值得的。Brotli 和 Zopfli 均可以用于任意纯文本的有效负载 —— HTML、CSS、SVG、JavaScript 等。nginx
有何对策呢?使用最高级别的 Brotli + Gzip 来预压缩静态资源,使用 Brotli 在 1 — 4 级中动态压缩(动态)HTML。确保服务器正确处理 Brotli 或 Gzip 的协议内容。若是你在服务器上没法安装/维护 Brotli,请使用 Zopfli。git
尽可能使用带有 srcset
、sizes
属性的响应式图片和 <picture>
元素响应式图片。固然,你还能够经过在原生 <picture>
上使用 WebP图片以及回退到 JPEG 的机制或者使用协议内容的方式中使用 WebP 格式 (在 Chrome、Opera、Firefox 6五、Edge 18 中都被支持的格式)(参见 Andreas Bovens 的代码片断),或者使用协议内容(Accept
头部)。Ire Aderinokun 也有关于将图像转换为 WebP 图像的超详细教程。github
原生 Sketch 是支持 WebP 的,可使用 Phtotshop 的 WebP 插件从 Photoshop 中导出 WebP 图像。固然也存在其余可用的选项。若是你正在使用 WordPress 或 Joomla,也可使用一些扩展来帮助你本身轻松实现对 WebP 的支持,好比适用于 WordPress 的 Optimus 和 Cache Enabler,Joomla 固然也存在对应可提供支持的扩展 (经过使用 Cody Arsenault)。web
须要注意的是,尽管 WebP 图像文件大小等价于 Guetzli 和 Zopfli,但它并不支持像 JPEG 这样的渐进式渲染,这也是用户之前经过 JPEG 能够更快地看到实际图像的缘由,尽管 WebP 图像在网络中的传输速度更快。使用 JPEG,咱们能够将一半甚至四分之一的数据提供给用户,而后再加载剩余数据,而不是像 WebP 那样可能会致使有不完整的图像。你应该根据本身的需求来进行取舍:使用 WebP,你能够有效减小负载,使用 JPEG,你能够提升性能感知。
在 Smashing Magazine 中,咱们使用 -opt
后缀来为图像命名 —— 好比,brotli-compression-opt.png
;这样,当咱们发现图像包含该后缀时,团队成员就会明白这个图像已经被优化过了。—— 难以置信!—— Jeremy Wagner 出了一本关于 WebP 的书,写的很好。
响应式图片端点生成器会自动生成图像和标记。
当你在开发 landing page 时,特定图像的加载必须很快,要确保 JPEG 是渐进加载的而且通过了 [mozJPEG] 或者 Guetzli 的压缩(经过操做扫描级别来改进开始渲染的时间),Google 新开源的编码器专一于性能感知,并利用了从 Zopfli 和 WebP 中所学的优势。惟一的缺点是:处理时间慢(每百万像素须要一分钟的 CPU)。对于 PNG 来讲,咱们可使用 Pingo,对于 SVG 来讲,咱们可使用 SVGO 或 SVGOMG。若是你须要快速预览、复制或下载网站上的全部 SVG 资源,那么你能够尝试使用 svg-grabber 。
虽然每一篇图像优化文章都会说,可是我仍是要提醒应该保证矢量资源的干净和紧凑。要记得清理未使用的资源,删除没必要要的元数据以及图稿中的路径点数量(好比 SVG 这类代码)(感谢 Jeremy!)
还有更高级的选项,好比:
使用 Squoosh 以最佳压缩级别(有损或无损)压缩。调整和操做图像。
使用响应式图像断点生成器或 Cloudinary、Imgix 这样的服务来实现自动化图像优化。此外,在许多状况下,使用 srcset
和 sizes
能够得到最佳效果。
要检查响应标记的效率,你可使用 imaging-heap(一个命令行工具)来检测不一样视窗大小和设备像素比的效果。
使用 lazysizes 来延迟加载图像和 iframes,这是一个经过检测用户交互(或以后咱们将讨论的 IntersectionObserver)来触发任何可见性修改的库。
注意默认加载的图像,它们可能永远也用不到 —— 例如,在 carousels、accordions 和 image galleries。
考虑根据请求类型来指定的不一样图像显示以经过 Sizes 属性切换图像,好比,操做 sizes
来交换 magnifier 组件中的数据源。
为防止前景和背景图像的意外下载,请检查图像下载的不一致性。
为了从根本上优化存储,你可使用 Dropbox 的新格式(Lepton)来对 JPEG 执行平均值可达到 22% 的无损压缩。
注意 CSS 属性中的 aspect-ratio
属性 和 intrinsicsize
属性,它们容许为图像设置宽高和尺寸,所以浏览器为了避免样式错乱,能够在页面加载期间提早预留一个预约义的布局槽。
若是你喜欢冒险,为了更快地经过网络传输图像,可使用基于 CDN 的实时过滤器 Edge workers 来终止并重排 HTTP/2 流。Edge workers 使用你能够控制的 JavaScript 流模块(它们是运行在 CDN 上的,能够修改响应流),这样你就能够控制图像的传输。相对于 service worker 来讲,这个过程时间稍长,由于你没法控制传输过程,但它确实适用于 Edge workers。所以,你能够在针对特定登陆页面逐步保存的静态 JPEG 上使用它们。
imaging-heap(一个用于检测跨视窗大小及设备像素比的加载效率的命令行工具)的输出样例,(图像来源) (详细预览)
响应式图像的将来可能会随着采用客户端提示而发生巨变。客户端提示内容是 HTTP 的请求头字段,例如 DPR
、Viewport-Width
、Width
、Save-Data
、Accept
(指定图像格式首选项)等。它们应该告知服务器用户的浏览器、屏幕、链接等细节。所以,服务器能够决定如何用对应大小的图像来填充布局,并且只提供对应格式所需的图像。经过客户端提示,咱们将资源从 HTML 标记中,迁移到客户端和服务器之间的请求响应协议中。
就像 Ilya Grigorik 说的那样,客户端提示使图像处理更加完整 —— 它们不是响应式图像的替代品。<picture>
在 HTML 标记中提供了必要艺术方向的控制。客户端提示为请求的图像提供注释来实现资源选择的自动化。Service Worker 为客户端提供完整的请求和响应管理功能。好比,Service Worker 能够在请求中附加新的客户端提示 header 值,重写 URL 并将图像请求指向 CDN,根据连接调整响应,用户偏好等。它不只适用于图像资源,也适用于全部其余请求。
对于支持客户端提示的客户端,能够检测到在图像上已经节省了 42% 的字节和超过 70% 的 1MB+ 字节数。在 Smashing 杂志上,咱们一样能够检测到已经提升了 19-32% 的性能。不幸的是,客户端提示仍然须要获得浏览器的支持才行。Firefox 和 Edge 正在考虑对它的支持。但若是同时提供普通的响应图像标记和客户端提示的 <meta>
标记,浏览器将评估响应图像标记并使用客户端提示 HTTP header 请求相应的图像。
还不够?那么你可使用多种背景图像技术来提升图像的感知性能。请记住,处理对比以及模糊没必要要细节(或删除颜色)也能够减少文件大小。你想放大一张小照片而不至于损失质量的话,能够考虑使用 Letsenhance.io。
到目前为止,这些优化只涉及基本内容。Addy Osmani 出版了一份很是详细的关于基本图像优化的指南,这份指南对于图像压缩和颜色管理的细节有很深刻的讲解。例如,你能够模糊图像中没必要要的部分(经过应用高斯模糊过滤器)来减少文件大小,甚至能够移除颜色或将图像转换为黑白来进一步缩小文件。对于背景图像,从 Photoshop 中导出的照片质量只有 0 到 10% 是彻底能够接受的。不要在 web 上使用 JPEG-XR —— “在 CPU 上解码 JPEG-XRs 软件端这个过程会让节省字节大小这个潜在地积极影响失效,甚至更糟,尤为是在 SPAs 状况下”。
到目前为止,咱们的已经讨论完了图像的相关内容,但咱们避免了关于 GIF 优势的探讨。坦白说,与其加载影响渲染性能和带宽的重动画 GIF,不如选择动态 WebP(GIF 做为回退)或者用 HTML5 videos 循环来替换它们。是的,带有 <video>
的浏览器性能极差,并且与图像不一样的是,浏览器不会预加载 <video>
内容,但它们每每比 GIF 更轻量级、更小。别无他法了么?那么至少咱们能够经过 Lossy GIF、gifsicle 或 giflossy 来有损压缩 GIF。
早期测试代表带有 img
标签的内联视频相较与等效的 GIF,除了文件大小问题外,前者的显示的速度要快 20 倍,解码要快 7 倍。虽然在 Safari 技术预览中声明了对 <img src=".mp4">
的技术支持,可是这个特性还远未普及,所以它在近期内不会被采用。
Addy Osmani 推荐用循环内联视频来取代 GIF 动画。文件大小差别明显(节省了 80%)。(预览)
前端是不停进步的领域,多年来,视频格式一直在不停改革。很长一段时间里,咱们一直但愿 WebM 能够成为格式的统治者,而 WebP(基本上是 WebM 视频容器中的一个静止图像)将取代过期的图像格式。尽管这些年来 WebP 和 WebM 得到了支持,但咱们所但愿看到的突破并未发生。
在 2018,Alliance of Open Media 发布了一种名为 AV1 的视频格式。AV1 具备和 H.265(H.264 的改进版本)编码器相似的压缩,但与后者不一样的是,AV1 是免费的。H.265 的许可证价格迫使浏览器供应商采用性能相同的 AV1:AV1(与 H.265 同样)的压缩性能是 WebP 的两倍。
AV1 颇有可能成为网络视频的终极标准。(图像来源:Wikimedia.org) (详细预览)
事实上,目前 Apple 使用的是 HEIF 格式和 HEVC (H.265),最新的 IOS 中,全部的照片和视频都以这些格式保存,而不是纯 JPEG 格式。尽管 HEIF 和 HEVC (H.265) 并无在网上被公开使用,但被浏览器已经开始对慢慢支持 AV1 了。所以在你的 <video>
标签中能够添加 AV1
,由于全部的浏览器供应商都会慢慢加入对它的支持。
目前来讲,使用最普遍的是 H.264,由 MP4 文件提供服务,所以在提供文件以前,请确保你的 MP4 文件用 multipass-encoding 处理过,用 frei0r iirblur 进行了模糊处理(若是适用),moov atom metadata 也被移动到文件头部,而你的服务器接受字节服务。Boris Schapira 提供了 FFmpeg 的确切说明来最大限度地优化视频。固然,提供 WebM 格式做为替代方案也会有所帮助。
视频回放性能自己就有不少内容能够研究,若是你想深刻了解它的细节,能够参阅 Doug Sillar 关于当前视频现状和视频传输最佳实践的系列视频。包括视频传输指标、视频预加载、压缩和流媒体等详细信息。
Zach Leatherman 的字体加载策略综合指南为 web 字体传输提供了十几种选择。
值得提出的第一个问题就是,你是否能够首选 UI 系统字体。若是不是上述状况,那你所提供的 Web 字体颇有可能包括系统字体没有使用的字形或额外的特性或者字体粗细。你能够要求字体提供方将字体分组,或者若是你使用的是开源字体,你可使用 Glyphhanger 或 Fontsquirrel 自行对它们进行子集化。你甚至可使用 Peter Müller 的 subfont,一个能够自动化你整个流程的命令行工具,它能够静态分析你的页面,生成最佳 Web 字体子集,而后注入页面中。
WOFF2 的支持性是最好的,你可使用 WOFF 做为不支持 WOFF2 的浏览器的备用选项 —— 毕竟,系统字体对遗留的浏览器版本会更友好。Web 字体的加载有不少,不少,不少的选项。你能够从 Zach Leatherman 的 "字体加载策略综合指南"中选择一种策略(代码片断也能够在 Web 字体加载中找到)。
如今,更好的选项应该是使用 Critical FOFT 结合 preload
和 "The Compromise" 方法。它们都使用两阶段渲染来逐步提供 Web 字体 —— 首先是使用 Web 字体快速准确地渲染页面所需的小超集,而后再异步加载剩余部分,不一样的是 "The Compromise" 技术只在字体加载事件不受支持的的状况下才异步加载 polyfill,因此默认状况下不须要加载 polyfill。须要快速入门?Zach Leatherman 有一个 快速入门的 23 分钟教程和案例研究来帮助你使用字体。
通常而言,使用 preload
资源提示来预加载字体是个好主意,但须要在你的标记中包含 CSS 和 JavaScript 的连接。不然,字体加载会在第一次渲染时消耗时间。尽管如此,有选择性地选择重要文件是个好主意。好比,渲染相当重要的文件会有助于你避免可视化和具备破坏性的文本刷新文件。总之,Zach 建议预加载每一个系列的一到两个字体。若是这些字体不是很关键的话,延迟加载一些字体也是有意义的。
没有人喜欢等待内容的显示。使用 font-display
CSS 描述符,咱们能够控制字体加载行为并使内容可被当即读取(font-display: optional
),或者几乎是当即被读(font-display: swap
)。然而,若是你想避免文本被重排,咱们仍然须要使用字体加载 API,尤为是 group repaints,或者当你使用第三方主机时。除非你能够 用 Cloudflare workers 的 Google 字体。讨论 Google 字体:考虑使用 google-webfonts-helper,这是一种轻松自我托管 Google 字体的方式。若是能够,那么自行托管你的字体会赋予你对字体最大程度的控制。
通常而言,若是你选择 font-display: optional
,那么就须要放弃使用 preload
,由于它会提早触发对 Web 字体的请求(若是你有其余须要获取的关键路径资源,就会致使网络阻塞)。preconnect
能够更快地获取跨域字体请求,但要谨慎使用 preload
,由于来自不一样域的预加载字体会致使网络竞争。全部这些技术都包含在 Zach 的 Web 字体加载。
此外,若是用户在辅助功能首选项中启用了 Reduce Motion 或选择数据保护模式(详细内容可参阅 Save-Data
header),那么最好是选择不使用 Web 字体(至少是第二阶段的渲染中)。或者当用户碰巧连接速度较慢时(经过 网络信息 API)。
要检测 Web 字体的加载性能,能够考虑使用全部文本可视化的度量标准(字体加载的时,全部内容当即以 Web 字体显示),以及首次渲染后的 Web 字体重排计数。显然,这两种指标越低,性能越好。重要的是考虑到变量字体对性能的需求。它们为设计师提供了更大的字体选择空间,代价是单个串行请求与许多单独的文件请求相反。这个单一的请求可能会缓慢地阻止页面上的整个排版外观。不过,好的一面是,在使用可变字体的状况下,默认状况下咱们将获得一个从新的文件流,所以不须要 JavaScript 对从新绘制的内容进行分组。
有没有一种完美的 Web 字体加载策略? 子集字体为二阶段渲染作好准备,使用 font-display
描述符来声明它们,使用字体加载 API 对从新绘制的内容进行分组并将字体存储在持久化的 service worker 缓存中。若是有必要,你能够回到 Bram Stein 的 Font Face Observer。若是你有兴趣检测字体加载的性能,Andreas Marschke 研究了使用 字体 API 和 UserTiming API 的性能。
最后,不要忘记加入 unicode-range
,将一个大字体分解成更小的特定语言字体,使用 Monica Dinculescu 的 font-style-matcher 来最小化布局上的不和谐变化,这是由于回退和 Web 字体之间的大小会产生不一致。
[译] 2019 前端性能优化年度总结 — 第一部分 [译] 2019 前端性能优化年度总结 — 第二部分 [译] 2019 前端性能优化年度总结 — 第三部分 [译] 2019 前端性能优化年度总结 — 第四部分 [译] 2019 前端性能优化年度总结 — 第五部分 [译] 2019 前端性能优化年度总结 — 第六部分
若是发现译文存在错误或其余须要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可得到相应奖励积分。文章开头的 本文永久连接 即为本文在 GitHub 上的 MarkDown 连接。
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。