2020前端性能优化清单(二)
- 原文地址:https://www.smashingmagazine.com/2020/01/front-end-performance-checklist-2020-pdf-pages[1]
- 翻译:陈隆德
- 本翻译仅做学习交流使用,转载请注明原处
- 本文是性能优化清单系列第二篇,可以先看看前面的文章:2020前端性能优化清单(一)
资源优化
17 使用 Brotli 进行纯文本压缩
2015 年,Google推出了[2]Brotli[3],这是一种全新的开源无损数据格式,并被现在所有现代浏览器支持[4]。实际上,Brotli 似乎比 Gzip 和 Deflate更有效[5]得多[6]。取决于您的设置,压缩可能会(非常)缓慢,但是这样慢的压缩速度最终也会带来较高的压缩率。不管怎样,它都能快速解压缩。这篇文章可以估算站点使用 Brotli 压缩可以节省的大小[7]。
问题在于,使用 Brotli 压缩所有资源非常耗费计算资源和时间。因此,仅由于其产生的成本开销,许多服务器就无法使用它。实际上,在最高压缩级别下,Brotli 是如此之慢,以至于服务器等待动态资源资产时,服务器开始发送响应所花费的时间会抵消文件大小减少带来的任何潜在收益。但是,对于静态资源压缩,应该首选更高压缩比的压缩设置[8]。
如果您可以避开动态压缩静态资产的成本,Brotli 就是值得的。Brotli 可用于任何纯文本的内容-HTML,CSS,SVG,JavaScript 等。
策略?使用最高压缩比配置的Brotli+Gzip 预压缩静态资源[9],并使用 Brotli 配置 3~5 级压缩比来快速压缩(动态)HTML。确保服务器正确处理 Brotli 或 gzip 的内容协商头。
04-compression-front-end-performance-checklist-2020无论是在桌面还是移动设备上,有大约 15%使用 Brotli 压缩。使用 gzip 压缩则大约是 65%。其余部分完全没有压缩。(图像来源: Web 年鉴:压缩[10])
18 使用响应式图像和 WebP
尽可能使用具有 srcset
,sizes
和 元素的响应式图像[11]。在使用它的同时,还可以通过
元素和 JPEG 兜底(请参阅 Andreas Bovens 的代码片段[12])来使用webP 格式[13](除 Safari 和 iOS Safari 外,所有现代浏览器均支持)。或使用内容协商(使用 Accept 标头)。Ire Aderinokun 有一个非常详细的教程[14],将图像转换为 WebP。
Sketch 内置支持 WebP,而 Photoshop 可以使用的WebP 插件[15]从 Photoshop 导出 WebP 图像。也有其他选项可用[16],如果您使用的是 WordPress 或 Joomla,也可以使用扩展来帮助您轻松实现对 WebP 的支持,例如 WordPress 的Optimus[17]和Cache Enabler[18]以及Joomla 自己支持的扩展[19](通过 Cody Arsenault)。
值得注意的是,虽然 WebP 图像文件大小与同等的 Guetzli 和 Zopfli 相比[20],该格式不支持像 JPEG 那样的渐进式渲染[21],这就是为什么用户使用好的 JPEG 可能会更快地看到实际图像,尽管 WebP 图像的网络加载速度可能会更快。使用 JPEG,我们可以用一半甚至四分之一的时间就提供给“像样的”用户体验,并在稍后加载其余的数据,而不是像 WebP 那样只有半空的图像。您的决定将取决于您想要的是什么:使用 WebP,您将减少图像大小,而使用 JPEG,您将提高图像的可感知性。
在 Smashing Magazine 上,我们使用后缀 -opt
作为图像名称-例如 brotli-compression-opt.png
;每当图像包含该后缀时,团队中的每个人都知道该图像已经过优化。并且-不需要再加后缀了!-Jeremy Wagner 甚至在Smashing book 上出版了一本《WebP》[22]。
响应式图像断点生成器[23]可自动执行图像适配和标记生成
19 图像是否经过适当优化?
当您在落地页上时,快速加载特定图像非常关键,请确保 JPEG 是渐进式渲染的,并使用mozJPEG[24]压缩(通过操纵扫描级别来缩短图像初始化渲染的时间),或者看看Guetzli[25],这是 Google 的新型开源编码器,专注于用户感知性能,并利用了 Zopfli 和 WebP 的经验。唯一的缺点[26]是:处理时间慢(每百万像素一分钟的 CPU)。对于 PNG,我们可以使用 Pingo,对于 SVG,我们可以使用SVGO[27]或SVGOMG[28]。而且,如果您需要从网站上快速预览和复制或下载所有 SVG 资源,svg-grabber[29]也可以为您做到这一点。
每一篇图像优化文章都会说的,但是有特别重要的一点:矢量资源整洁和紧密。确保清理未使用的资源,删除不必要的元数据,并减少图稿中路径点的数量(从而减少 SVG 代码)。(谢谢 Jeremy!)
但是,还有更多高级的方案。你可以:
- 使用Squoosh[30]压缩、调整大小和处理图像,以获得最佳的压缩级别(有损或无损)
- 使用响应式图像断点生成器[31]或Cloudinary[32]或Imgix[33]等服务来自动进行图像优化。同样,在大多数情况下,仅使用
srcset
和size
将会获得显着的好处 - 检查响应式标记的效率,可以使用Imaging-heap[34],这是一个命令行工具,可以测量视口大小和设备像素比率之间的效率
- 对图片和 Iframe 进行懒加载,可以使用混合懒加载[35]、本地懒加载,或懒加载[36]库,它检测通过用户交互触发的可见性更改来实现懒加载(使用 IntersectionObserver,我们将在后面进行探讨)
- 对于屏幕外图像,我们可以先显示一个占位符,然后当图像出现在视口中时,使用 IntersectionObserver 触发网络调用,以将图像下载到后台。然后,我们可以推迟渲染直到调用 img.decode()完成解码[37];如果Image Decode API[38]不可用,就直接下载图像。渲染图像时,我们可以使用淡入动画。Katie Hempenius 和 Addy Osmani 在他们的性能提升:网络性能优化建议和技巧[39]文章中分享了更多这方面的观点
- 您可以配置在“Pull Request”中自动图像压缩[40],因此任何图像都会在构建时完成压缩。这个 Github Actions 会对 PNG 和 JPG 使用 mozjpeg 和 libvips 进行压缩
- 请注意默认情况下加载但可能永远都不会渲染的图像,例如网页中的“轮播图”,“手风琴”和“图像画廊”
- 考虑使用“Sizes”属性更换请求的图像[41],通过根据媒体查询来确定不同的图像显示尺寸。例如在“放大镜”组件中,通过设置
sizes
来触发替换图像资源 - 每次上线前 Review页面中图像下载过程是否有不同[42],以防止意外下载不需要的前景和背景图像
- 有时仅靠优化图像并不能解决问题。为了缩短开始渲染关键图像所需[43]的时间,请延迟加载不太重要的图像,并在关键图像渲染完成后再加载任何异步脚本
- 如果要优化内部存储,可以使用 Dropbox 新的Lepton 格式[44],它的 JPEG 无损压缩率平均可以达到 22%
- 请注意 CSS 中的aspect-ratio 属性[45]和internalsize 属性[46],这将允许我们设置图像的纵横比和尺寸,因此浏览器可以提前保留预定义的布局槽,这样在页面加载期间就可以避免出现布局跳跃[47]
- 如果您在技术上喜欢冒险,则可以使用Edge worker[48](CDN 上的实时过滤器)对 HTTP/2 流进行切割和重排,以便更快地通过网络发送图像。Edge Worker 使用的 JavaScript 流使用可以控制的块(它们是在 CDN Edge 上运行的 JavaScript,可以修改流响应),因此您可以控制图像的传递。对于 service worker,这时间点太晚了,因为您无法控制线路上的内容,但可以与 Edge Worker 一起使用。因此在为特定的落地页中,您可以逐步在的静态 JPEG 上使用它们以节省传输大小
通过imaging-heap[49]输出的样本,这是一种命令行工具,可测量跨视口大小和设备像素比率的效率(图片来源[50])
随着客户提示的应用,响应式图像的未来可能会发生巨大变化。客户端提示指的是 HTTP 请求标头字段,例如 DPR
, Viewport-Width
, Width
, Save-Data
, Accept
(指定图像格式首选项)等。他们会将用户浏览器,屏幕,连接等的详细信息通知服务器。因此,服务器可以决定如何用适当大小的图像填充布局,并仅以所需格式提供这些图像。通过客户端提示,我们将资源选择从 HTML 标记移到了客户端和服务器之间的请求-响应协商中。
正如 Ilya Grigorik 所指出的那样,客户的提示令响应式图像的应用更加完整-它们不是响应式图像的替代方案。“ 元素在 HTML 标记中提供了必要的艺术方向控制。客户端提示在结果图像请求上提供注释,从而实现资源选择自动化。ServiceWorker 在客户端上提供完整的请求和响应管理功能。” 例如,服务人员可以向请求添加新的客户端提示标头值,重写 URL 并将图像请求指向 CDN,根据连接性和用户首选项调整响应,等等。它不仅适用于图像资源,而且适用几乎所有其他类型的请求。
对于支持客户端提示的客户端,测试结果可以为图像节省了 42%的字节[51],70%以上测试结果少了 1MB +的字节。在 Smashing Magazine 上,我们也可以测试得到19-32%的改善[52]。不幸的是,客户端提示还必须获得一些浏览器支持[53],比如Firefox[54]仍在考虑中。但是,如果同时为客户端提示提供正常的响应图像标记和 标签,则浏览器将评估响应图像标记,并使用客户端提示的 HTTP 标头返回适当的图像资源。
还不够好?另外,您还可以使用多背景图像技术[55]来提高图像的感知性能。请记住,调整对比度[56]和模糊不必要的细节(或消除颜色)也可以减小文件大小。嗯,如果您需要放大一张小照片而不损失画质吗?考虑使用Letsenhance.io[57]。
到目前为止,这些优化仅涉及基础知识。Addy Osmani 已发布了有关图像优化的非常详细的指南[58],该指南非常深入地介绍了图像压缩和颜色管理的细节。例如,您可以使图像的不必要部分模糊(通过应用高斯模糊滤镜)以减小文件大小,最终您甚至可以删除颜色或将图片变成黑白以进一步减小大小。对于背景图像,在 Photoshop 中以 0 到 10%的质量导出图片也是绝对可以接受的。此外,不要在 web 开发中使用 JPEG-XR[59]-“使用 CPU 上对 JPEG-XRs 进行解码的处理将影响渲染性能,增加的耗时可能使字节大小节省的优化无效,甚至超过其大小节省的积极影响,尤其是在 SPA 的 web 应用中”。
replace-animated-gifsAddy Osmani 建议用循环播放的内联视频替换动画 GIF,文件大小差异明显(节省 80%)
20 视频是否经过适当优化?
到目前为止,我们已经讨论完了图像,但是我们避开了有关优化 GIF 的事情。坦白说,与其加载会影响渲染性能和带宽的沉重动画 GIF,不如改用动画 WebP(将 GIF 用作兜底),或将其全部替换为循环的 HTML5 视频,这是一个好主意。是的,与图像不同,浏览器不会预加载 内容,但 HTML5 视频往往比 GIF 更轻,更小。没有选择吗?好吧,至少我们可以使用有损 GIF[60],gifsicle[61]或giflossy[62]对 gif 进行有损压缩以减小图像大小。
测试表明,与 gif 相比,使用 img
标签内联视频的显示速度快 20 倍,解码速度快 7 倍,而且文件大小非常小。
好消息是,视频格式多年来一直在不断发展。长期以来,我们一直希望 WebM 成为统一所有的格式,而 WebP(基本上是 WebM 视频容器内部的一个静止图像)将替代过时的图像格式。但是,尽管这些年 WebP 和 WebM 已经获得了不错的支持,但并没有实现重大突破。
2018 年,开源媒体联盟发布了一种新的有前途的视频格式,称为 AV1。AV1 的压缩与 H.265 编解码器(H.264 的演进)相似,但与后者不同,AV1 是免费的。H.265 许可证的价格迫使浏览器供应商改为使用性能相同的 AV1:(就像 H.265 一样)AV1 压缩的效果是 WebM 的两倍。
av1-logo-2018-fullAV1 很有可能成为网络视频的最终标准(图片来源:Wikimedia.org[63])
实际上,Apple 当前使用的是HEIF[64]和HEVC(H.265)[65],并且最新 iOS 上的所有照片和视频均以这些格式保存,而不是 JPEG。虽然 HEIF 和 HEVC(H.265)还不可以正确显示在 web 网页上(或许您读这篇文章的时候可能已经不是这样了?),但 AV1 已经可以 -- 并且正在不断获得浏览器支持[66]。因此,在所有 标签中添加
AV1
资源是合理的,因为似乎所有浏览器供应商都在使用。
目前,使用最广泛且受支持的编码是 H.264,由 MP4 文件提供,因此在提供文件之前,请确保您的 MP4 经过多遍编码处理[67],并用frei0r iirblur 效果[68]模糊处理(如果适用的话),并且在服务器接受字节服务[69]时,将atom 元数据移动[70]到文件的头部。Boris Schapira 提供了FFmpeg 的准确说明[71],以最大限度地优化视频。当然,提供 WebM 格式作为替代方案也会有所帮助。
是否需要开始更快地渲染视频,但是视频文件仍然太大?例如,当您在目标网页上有大型背景视频时如何优化?常用的技术是先将第一帧显示为静止图像,或显示经过优化的短循环段,将其作为为视频的一部分,然后等视频有足够的缓冲,再开始播放实际的视频。Doug Sillars 撰写的详细的背景视频性能优化指南[72],在这种情况下可能会有所帮助。(谢谢,Guy Podjarny!)。
视频播放性能本身就是一个很长很庞大的故事,如果您想深入了解它,请查看 Doug Sillars 另一系列文章,有关当前视频[73]和视频交付最佳做法[74]的内容,其中包括有关视频交付指标的详细信息,视频预加载,压缩和流式传输等等内容。
font-loading-strategies-optZach Leatherman 的字体加载策略综合指南[75]提供了十几种更好的 Web 字体交付方案
21 网络字体是否经过优化?
首先要问的一个问题是,您是否可以摆脱使用UI 系统的字体[76]的麻烦?再次检查它们在各种平台上的显示是否正确[77]。如果不是这种情况,您提供的网络字体很有可能会包含字形以及未使用的额外功能和粗细。您可以用字体代工厂将 Web 字体转换成较小的子集,或者如果您使用的是开源字体,则可以使用Glyphhanger[78]或Fontsquirrel[79]对它们进行子集化。您甚至可以使用 PeterMüller 的subfont[80]来自动完成整个字体子集化的工作流程,subfont 是一个命令行工具,可以静态分析您的页面以生成最佳的 Web 字体子集,然后将其注入到您的页面中。
WOFF2 的浏览器支持非常好,您可以将 WOFF 作为不支持 WOFF2 的浏览器的兜底字体 - 也可以用系统字体兜底,以便更好地支持旧版浏览器。Web 字体加载有很多很多的选择,您可以从 Zach Leatherman 的“字体加载策略综合指南”[81]中选择一种策略(这个代码片段也可以作为web 字体加载方法使用[82])。
目前可以使用的更好的选择是:预加载关键 FOFT[83]和“compromise”技术[84]。他们两个都分两阶段渲染来逐步交付 Web 字体-首先需要一个小的超级子集,以便使用 Web 字体快速准确地渲染页面,然后加载异步家族的其余部分。所不同的是,只有在不支持字体加载事件[85]的场景中,“compromise”技术才会异步加载 polyfill,因此默认情况下您无需加载 polyfill。需要快速达到目标吗?Zach Leatherman 提供了23 分钟的快速教程和案例研究[86],可以让您的字体的处理井井有条。
通常情况下,使用 preload
资源提示来预加载字体是一个好主意,但是在您的页面中标记中,predload 字体需要放在关键 CSS 和 JavaScript 的链接之后。对于 preload
,优先级经常令人困惑[87],因此请考虑在外部脚本阻塞之前将 rel=" preload"
元素注入到 DOM 中。根据 Andy Davies 的说法,“使用脚本注入的资源将在浏览器中隐藏,直到脚本执行为止,我们可以使用此行为来延迟浏览器发现 preload
元素。” 否则,字体加载将在第一次渲染时就耗费您的时间。
有选择性地[88]选择最重要的文件是一个好主意,例如,那些对渲染至关重要的文件,或者那些可以帮助页面提升可见性的和避免破坏性文本重排的文件。一般来说,Zach 建议预加载每个系列的一到两种字体-如果字体不那么关键,推迟一些字体加载时机也是有意义的。
在 @font-face
规则中定义 font family
时,使用 local()
值(按名称引用本地字体)已经是非常普遍的做法了:
/* Warning! Probably not a good idea! */
@font-face {
font-family: Open Sans;
src: local('Open Sans Regular'),
local('OpenSans-Regular'),
url('opensans.woff2') format ('woff2'),
url('opensans.woff') format('woff');
}
这个方案是合理的:因为一些流行的开源字体,如 Open Sans,会预装在一些驱动程序或应用程序中,所以如果字体是本地可用的,浏览器就可以立即显示本地字体,而不需要下载网页字体。但是,正如Bram Stein 所指出的[89],“尽管一种本地字体与一种网络字体的名称相同,但它很可能本质上不是同一种字体。许多网络字体与它们的‘桌面’版本不同。文本可能是不同的,一些字符也可能会退回到其他字体,Open-Type 特色可能会被遗漏,或者行高可能会有所不同。”
另外,随着字体随着时间的推移而发展,本地安装的版本也可能与网络字体大不相同,字符看起来也大不相同。因此,根据 Bram 的说法,最好不要在 @font-face
规则中混合本地安装的字体和网络字体。
没有人喜欢等待内容显示。因此我们可以使用 font-display 这个 CSS 描述符来控制字体的加载行为并使内容立即(font-display: optional
)或几乎立即(font-display: swap
)可读 但是,如果要避免文本重排[90],我们仍然需要使用字体加载 API,特别是在对文本重绘进行分组时或者在使用第三方代理的时候。除非您可以将 Google Fonts 与 Cloudflare Workers[91]一起使用,那就不用考虑使用字体加载 API 了。
论及 Google Fonts:尽管它最近增加了对字体显示的支持[92],但还是建议大家考虑使用google-webfonts-helper[93],这是一种轻松自如地托管 Google Fonts 的方案。如果可以的话,请始终自行托管字体[94]以实现对字体行为最大程度的控制。
通常,如果您使用 font-display: optional
,则同时使用 preload
可能不是一个好主意,因为它将提前触发该 Web 字体请求(如果此时您需要获取其他关键路径资源,则该字体加载会导致网络拥塞)。使用 preconnect
可以更快地进行跨域字体请求,但请谨慎使用预加载,因为从不同源预加载字体会引发网络争用。所有这些技术都在 Zach 的Web 字体加载食谱[95]中进行了介绍。
如果用户启用了辅助功能首选项中的减少动效[96]或省流量模式(请参阅Save-Data 头[97]),那么选择延迟 Web 字体加载(或至少第二阶段才渲染)可能是个好主意。或者当用户碰巧具有慢速连接时(通过Network_Information_API[98]检测)也是如此。最后,如果用户选择了省流量模式,我们还可以使用`Preferences-Reduced-Data`[99] CSS 媒体查询来清除字体声明。如果来自客户端 HTTP 扩展中的 Save-Data 请求标头是 on/off
,则省流量模式的媒体查询的结果在大多数情况下都是公开的,可以在 CSS 中使用。虽然还不完全是。
要测量 Web 字体加载性能,请考虑所有文本可见时间[100](所有字体均已加载且所有内容均以 Web 字体显示的时刻)、变为真实斜体的时间[101]以及首次渲染后的Web 字体回流数[102]。显然,这两个指标越低,性能就越好。需要注意的是,可变字体[103]可能需要更重视性能影响[104]。它们为设计者提供了更广阔的排版选择设计空间,但这是以一系列单个的串行请求为代价的,而不是将多个单独的文件并行请求。单个请求可能会很慢,从而阻塞页面上内容的渲染。因此,设置字体子集并将其拆分成字符集仍然很重要。不过,好的一面是,有了可变字体,默认情况下我们将只有一次回流,因此不需要 JavaScript 来对重绘进行分组。
那么,怎样才能制定一个防弹(安全)的网络字体加载策略呢?将字体子集化并在第二阶段渲染做好准备,使用 font-display
描述符声明它们,使用字体加载 API 对重绘进行分组,并将字体存储在持久的 service worker 缓存中。第一次访问时,在阻塞的外部脚本之前插入脚本预加载字体。如有必要,您可以退回到 Bram Stein 的Font Face Observer[105]。如果您对测量字体加载的性能感兴趣,Andreas Marschke 研究的文章可以看看:使用 Font API 和 UserTiming API 来跟踪性能[106]。
最后,不要忘了使用unicode range[107],它可以将大字体分解成小的语言专用字体,并使用 Monica Dinculescu 的font-style-matcher[108]来最小化布局中由于兜底字体和 Web 字体之间的大小差异而造成的不和谐变化。
网页字体处理的未来如何?随着渐进式字体的发展,我们最终或许能够实现:“在任何给定的页面上只下载所需的字体部分,并且对于对该字体的后续请求,根据后续页面查看所需的附加字形集来动态地‘修补’原始下载”,就像 Jason Pamental 所说的。这里有个类似这种增量传输方案的演示[109],并且正在不断完善中。
参考资料
[1]https://www.smashingmagazine.com/2020/01/front-end-performance-checklist-2020-pdf-pages: https://www.smashingmagazine.com/2020/01/front-end-performance-checklist-2020-pdf-pages
[2]推出了: https://opensource.googleblog.com/2015/09/introducing-brotli-new-compression.html
[3]Brotli: https://github.com/google/brotli
[4]并被现在所有现代浏览器支持: http://caniuse.com/#search=brotli
[5]更有效: https://quixdb.github.io/squash-benchmark/#results-table
[6]得多: https://paulcalvano.com/index.php/2018/07/25/brotli-compression-how-much-will-it-reduce-your-content/
[7]估算站点使用 Brotli 压缩可以节省的大小: https://tools.paulcalvano.com/compression.php
[8]首选更高压缩比的压缩设置: https://css-tricks.com/brotli-static-compression/
[9]Brotli+Gzip 预压缩静态资源: https://css-tricks.com/brotli-static-compression/
[10]Web 年鉴:压缩: https://almanac.httparchive.org/en/2019/compression
[11]响应式图像: https://www.smashingmagazine.com/2014/05/responsive-images-done-right-guide-picture-srcset/
[12]代码片段: https://dev.opera.com/articles/responsive-images/#different-image-types-use-case
[13]webP 格式: https://www.smashingmagazine.com/2015/10/webp-images-and-performance/
[14]教程: https://bitsofco.de/why-and-how-to-use-webp-images-today/
[15]WebP 插件: http://telegraphics.com.au/sw/product/WebPFormat#webpformat
[16]也有其他选项可用: https://developers.google.com/speed/webp/docs/using
[17]Optimus: https://wordpress.org/plugins/optimus/
[18]Cache Enabler: https://wordpress.org/plugins/cache-enabler/
[19]Joomla 自己支持的扩展: https://extensions.joomla.org/extension/webp/
[20]同等的 Guetzli 和 Zopfli 相比: https://www.ctrl.blog/entry/webp-vs-guetzli-zopfli
[21]像 JPEG 那样的渐进式渲染: https://youtu.be/jTXhYj2aCDU?t=630
[22]Smashing book 上出版了一本《WebP》: https://www.smashingmagazine.com/ebooks/the-webp-manual/
[23]响应式图像断点生成器: http://www.responsivebreakpoints.com/
[24]mozJPEG: https://github.com/mozilla/mozjpeg
[25]Guetzli: https://github.com/google/guetzli
[26]唯一的缺点: https://medium.com/@fox/talk-the-state-of-the-web-3e12f8e413b3
[27]SVGO: https://www.npmjs.com/package/svgo
[28]SVGOMG: https://jakearchibald.github.io/svgomg/
[29]svg-grabber: https://chrome.google.com/webstore/detail/svg-grabber-get-all-the-s/ndakggdliegnegeclmfgodmgemdokdmg
[30]Squoosh: https://squoosh.app/
[31]响应式图像断点生成器: http://www.responsivebreakpoints.com/
[32]Cloudinary: Cloudinary
[33]Imgix: https://www.imgix.com/
[34]Imaging-heap: https://github.com/filamentgroup/imaging-heap
[35]混合懒Z加载: https://www.smashingmagazine.com/2019/05/hybrid-lazy-loading-progressive-migration-native/
[36]懒加载: https://github.com/verlok/lazyload
[37]推迟渲染直到调用 img.decode()完成解码: https://youtu.be/YJGCZCaIZkQ?t=570
[38]Image Decode API: https://medium.com/dailyjs/image-loading-with-image-decode-b03652e7d2d2
[39]性能提升:网络性能优化建议和技巧: https://youtu.be/YJGCZCaIZkQ?t=436
[40]配置在“Pull Request”中自动图像压缩: https://github.com/marketplace/actions/image-actions
[41]考虑使用“Sizes”属性更换请求的图像: https://www.filamentgroup.com/lab/sizes-swap/
[42]页面中图像下载过程是否有不同: https://csswizardry.com/2018/06/image-inconsistencies-how-and-when-browsers-download-images/
[43]渲染关键图像所需: https://calendar.perfplanet.com/2019/the-ugly-truth-about-optimising-beautiful-images/
[44]Lepton 格式: https://github.com/dropbox/lepton
[45]aspect-ratio 属性: https://drafts.csswg.org/css-sizing-4/#ratios
[46]internalsize 属性: https://github.com/ojanvafai/intrinsicsize-attribute
[47]避免出现布局跳跃: https://24ways.org/2018/jank-free-image-loads/
[48]Edge worker: https://youtu.be/jTXhYj2aCDU?t=854
[49]imaging-heap: https://github.com/filamentgroup/imaging-heap
[50]图片来源: https://pbs.twimg.com/media/DY1XZ28VwAAwjd8.jpg
[51]为图像节省了 42%的字节: https://twitter.com/igrigorik/status/1032657105998700544
[52]19-32%的改善: https://www.smashingmagazine.com/2016/01/leaner-responsive-images-client-hints/
[53]获得一些浏览器支持: http://caniuse.com/#search=client-hints
[54]Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=935216
[55]多背景图像技术: http://csswizardry.com/2016/10/improving-perceived-performance-with-multiple-background-images/
[56]调整对比度: https://css-tricks.com/contrast-swap-technique-improved-image-performance-css-filters/
[57]Letsenhance.io: https://letsenhance.io/
[58]有关图像优化的非常详细的指南: https://images.guide/
[59]不要在 web 开发中使用 JPEG-XR: https://calendar.perfplanet.com/2018/dont-use-jpeg-xr-on-the-web/
[60]有损 GIF: https://kornel.ski/lossygif
[61]gifsicle: https://github.com/kohler/gifsicle
[62]giflossy: https://github.com/pornel/giflossy
[63]Wikimedia.org: https://upload.wikimedia.org/wikipedia/commons/thumb/8/84/AV1_logo_2018.svg/2560px-AV1_logo_2018.svg.png
[64]HEIF: https://caniuse.com/#search=heif
[65]HEVC(H.265): https://caniuse.com/#search=hevc
[66]正在不断获得浏览器支持: https://caniuse.com/#feat=av1
[67]多遍编码处理: https://medium.com/@borisschapira/optimize-your-mp4-video-for-better-performance-dareboost-blog-fb2f3f3dce77
[68]frei0r iirblur 效果: https://yalantis.com/blog/experiments-with-ffmpeg-filters-and-frei0r-plugin-effects/
[69]接受字节服务: https://medium.com/@borisschapira/optimize-your-mp4-video-for-better-performance-dareboost-blog-fb2f3f3dce77
[70]atom 元数据移动: http://www.adobe.com/devnet/video/articles/mp4_movie_atom.html
[71]FFmpeg 的准确说明: https://medium.com/@borisschapira/optimize-your-mp4-video-for-better-performance-dareboost-blog-fb2f3f3dce77
[72]详细的背景视频性能优化指南: https://calendar.perfplanet.com/2019/performance-tips-for-background-video/
[73]有关当前视频: https://www.smashingmagazine.com/2018/10/video-playback-on-the-web-part-1/
[74]视频交付最佳做法: https://www.smashingmagazine.com/2018/10/video-playback-on-the-web-part-2/
[75]字体加载策略综合指南: https://www.zachleat.com/web/comprehensive-webfonts/
[76]UI 系统的字体: https://www.smashingmagazine.com/2015/11/using-system-ui-fonts-practical-guide/
[77]再次检查它们在各种平台上的显示是否正确: http://fontfamily.io/Roboto,Segoe_UI,TImes,Helvetica,sans-serif
[78]Glyphhanger: https://www.afasterweb.com/2018/03/09/subsetting-fonts-with-glyphhanger/
[79]Fontsquirrel: https://www.fontsquirrel.com/tools/webfont-generator
[80]subfont: https://github.com/Munter/subfont#readme
[81]“字体加载策略综合指南”: https://www.zachleat.com/web/comprehensive-webfonts/
[82]web 字体加载方法使用: https://github.com/zachleat/web-font-loading-recipes
[83]预加载关键 FOFT: https://www.zachleat.com/web/comprehensive-webfonts/#critical-foft-preload
[84]“compromise”技术: https://www.zachleat.com/web/the-compromise/
[85]字体加载事件: https://www.igvita.com/2014/01/31/optimizing-web-font-rendering-performance/#font-load-events
[86]23 分钟的快速教程和案例研究: https://www.zachleat.com/web/23-minutes/
[87]优先级经常令人困惑: https://andydavies.me/blog/2019/02/12/preloading-fonts-and-the-puzzle-of-priorities/
[88]有选择性地: https://youtu.be/FbguhX3n3Uc?t=1637
[89]Bram Stein 所指出的: https://www.bramstein.com/writing/web-font-anti-patterns-local-fonts.html
[90]避免文本重排: https://www.zachleat.com/web/font-display-reflow/
[91]将 Google Fonts 与 Cloudflare Workers: https://blog.cloudflare.com/fast-google-fonts-with-cloudflare-workers/
[92]最近增加了对字体显示的支持: https://css-tricks.com/google-fonts-and-font-display/
[93]google-webfonts-helper: https://google-webfonts-helper.herokuapp.com/fonts
[94]自行托管字体: https://speakerdeck.com/addyosmani/web-performance-made-easy?slide=55
[95]Web 字体加载食谱: https://github.com/zachleat/web-font-loading-recipes
[96]减少动效: https://webkit.org/blog/7551/responsive-design-for-motion/
[97]Save-Data 头: https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/save-data/
[98]Network_Information_API: https://developer.mozilla.org/en-US/docs/Web/API/Network_Information_API
[99]Preferences-Reduced-Data
: https://github.com/w3c/csswg-drafts/issues/2370
所有文本可见时间: https://noti.st/zachleat/KNaZEg/the-five-whys-of-web-font-loading-performance#s5IYiho
[101]变为真实斜体的时间: https://vimeo.com/336091879#t=1550s
[102]Web 字体回流数: https://noti.st/zachleat/KNaZEg/the-five-whys-of-web-font-loading-performance#sJw0KSc
[103]可变字体: https://alistapart.com/blog/post/variable-fonts-for-responsive-design
[104]更重视性能影响: https://youtu.be/FbguhX3n3Uc?t=2161
[105]Font Face Observer: https://github.com/bramstein/fontfaceobserver
[106]使用 Font API 和 UserTiming API 来跟踪性能: https://www.andreas-marschke.name/posts/2017/12/29/Fonts-API-UserTiming-Boomerang.html
[107]unicode range: https://www.nccgroup.trust/uk/about-us/newsroom-and-events/blogs/2015/august/how-to-subset-fonts-with-unicode-range/
[108]font-style-matcher: https://meowni.ca/font-style-matcher/
[109]增量传输方案的演示: https://fonts.gstatic.com/experimental/incxfer_demo
推荐阅读
我的公众号能带来什么价值?(文末有送书规则,一定要看)
每个前端工程师都应该了解的图片知识(长文建议收藏)
为什么现在面试总是面试造火箭?