本文永久链接:
译者: https://github.com/Starriers
校对者: https://github.com/kikooo , https://github.com/Jingyuan0000
让 2019 来得更迅速吧~ 你正在阅读的是 2019 年前端性能优化年度总结, 始于 2016.
[译] 2019 前端性能优化年度总结 - 第一部分 [译] 2019 前端性能优化年度总结 - 第二部分 [译] 2019 前端性能优化年度总结 - 第三部分 [译] 2019 前端性能优化年度总结 - 第四部分 [译] 2019 前端性能优化年度总结 - 第五部分 [译] 2019 前端性能优化年度总结 - 第六部分
目录
资源优化
17. 使用 Brotli 或 Zopfli 来对纯文本内容进行压缩
18. 使用响应式图像和 webP
19. 图像是否已经被适当优化?
20. 视频是否已经被适当优化?
21. 网页字体是否已经优化?
资源优化
17. 使用 Brotli 或 Zopfli 来对纯文本进行压缩
2015 年, Google 推出了 Brotli https://github.com/google/brotli , 一种新开源的无损数据格式, 现已被所有现代浏览器所支持 http://caniuse.com/#search=brotli . 实际上, Brotli 比 Gzip 和 Deflate 有效得多. 因为它比较依赖配置, 所以这种压缩可能会 (非常) 慢, 但较慢的压缩意味着更高的压缩率. 不过它解压速度很快. 所以你可以考虑 Brotli 为你的网站所节省的成本 https://tools.paulcalvano.com/compression.php .
只有用户通过 HTTPS 访问站点时, 浏览器才会接受这种格式. 那代价是什么呢? Brotli 并没有预安装在一些服务器上, 所以如果没有自编译 Nginx, 那么配置就会相对困难. 尽管如此, 它也并非是不可攻破的难题 https://www.tinywp.in/nginx-brotli/ , 比如, Apache 自 2.4.26 版本起, 开始逐步对它进行支持. 得益于 Brotli 被众多厂商支持, 许多 CDN 也开始支持它 (Akamai,AWS,KeyCDN https://www.keycdn.com/blog/keycdn-brotli-support ,Fastly,Cloudlare,CDN77 https://www.cdn77.com/brotli ), 你甚至(结合 service worker 一起使用) 可以在不支持它的 CDN 上, 启用 Brotli.
在最高级别压缩时, Brotli 会非常缓慢, 以至于服务器在开始发送响应前等待动态压缩资源所花费的时间, 可能会抵消文件大小 (被压缩后) 的潜在增益. 但对于静态压缩, 应该首选更高级别的压缩 https://CSS-tricks.com/brotli-static-compression/ .
或者, 你可以考虑使用将数据编码为 Deflate,Gzip 和 Zlib 格式的 Zopfli 的压缩算法. 任何普通的 Gzip 压缩资源都可以通过 Zopfli 改进的 Deflate 编码达到比 Zlib 的最大压缩率小 3% 到 8% 的文件大小. 问题是压缩文件大约需要耗费 80 倍的时间. 这就是为什么在资源上使用 Zopfli 是个好主意, 因为这些资源不会发生太大的变化, 它们被设计成只压缩一次但可以下载多次.
如果可以降低动态压缩静态资源的成本, 那么这种付出是值得的. Brotli 和 Zopfli 都可以用于任意纯文本的有效负载 -- html,CSS,SVG,JavaScript 等.
有何对策呢? 使用最高级别的 Brotli + Gzip 来预压缩静态资源 https://css-tricks.com/brotli-static-compression/ , 使用 Brotli 在 1 - 4 级中动态压缩(动态)HTML. 确保服务器正确处理 Brotli 或 Gzip 的协议内容. 如果你在服务器上无法安装 / 维护 Brotli, 请使用 Zopfli.
18. 使用响应图像和 WebP
尽量使用带有 srcset,sizes 属性的响应式图片和 <picture> 元素响应式图片. 当然, 你还可以通过在原生 <picture> 上使用 WebP 图片以及回退到 JPEG 的机制或者使用协议内容的方式中使用 WebP 格式 (在 Chrome,Opera,Firefox 65,Edge 18 中都被支持的格式)(参见 Andreas Bovens 的代码片段), 或者使用协议内容(Accept 头部).Ire Aderinokun 也有关于将图像转换为 WebP 图像的超详细教程.
原生 Sketch 是支持 WebP 的, 可以使用 Phtotshop 的 WebP 插件从 Photoshop 中导出 WebP 图像. 当然也存在其他可用的选项. 如果你正在使用 WordPress 或 Joomla, 也可以使用一些扩展来帮助你自己轻松实现对 WebP 的支持, 比如适用于 WordPress 的 Optimus https://wordpress.org/plugins/optimus/ 和 Cache Enabler https://wordpress.org/plugins/cache-enabler/ ,Joomla 当然也存在对应可提供支持的扩展 https://extensions.joomla.org/extension/webp/ (通过使用 Cody Arsenault).
需要注意的是, 尽管 WebP 图像文件大小等价于 Guetzli 和 Zopfli https://www.ctrl.blog/entry/webp-vs-guetzli-zopfli , 但它并不支持像 JPEG 这样的渐进式渲染, 这也是用户以前通过 JPEG 可以更快地看到实际图像的原因, 尽管 WebP 图像在网络中的传输速度更快. 使用 JPEG, 我们可以将一半甚至四分之一的数据提供给用户, 然后再加载剩余数据, 而不是像 WebP 那样可能会导致有不完整的图像. 你应该根据自己的需求来进行取舍: 使用 WebP, 你可以有效减少负载, 使用 JPEG, 你可以提高性能感知.
在 Smashing Magazine 中, 我们使用 -opt 后缀来为图像命名 -- 比如, brotli-compression-opt.PNG; 这样, 当我们发现图像包含该后缀时, 团队成员就会明白这个图像已经被优化过了.-- 难以置信!-- Jeremy Wagner 出了一本关于 WebP 的书, 写的很好.
http://www.responsivebreakpoints.com/
响应式图片端点生成器 http://www.responsivebreakpoints.com/ 会自动生成图像和标记.
19. 图像的优化是否得当?
当你在开发 landing page 时, 特定图像的加载必须很快, 要确保 JPEG 是渐进加载的并且经过了 [mozJPEG] 或者 Guetzli https://github.com/google/guetzli 的压缩(通过操作扫描级别来改进开始渲染的时间),Google 新开源的编码器专注于性能感知, 并利用了从 Zopfli 和 WebP 中所学的优点. 唯一的缺点是: 处理时间慢(每百万像素需要一分钟的 CPU). 对于 PNG 来说, 我们可以使用 Pingo http://css-ig.net/pingo , 对于 SVG 来说, 我们可以使用 SVGO https://www.npmjs.com/package/svgo 或 SVGOMG https://jakearchibald.github.io/svgomg/ . 如果你需要快速预览, 复制或下载网站上的所有 SVG 资源, 那么你可以尝试使用 .
虽然每一篇图像优化文章都会说, 但是我还是要提醒应该保证矢量资源的干净和紧凑. 要记得清理未使用的资源, 删除不必要的元数据以及图稿中的路径点数量(比如 SVG 这类代码)(感谢 Jeremy!)
还有更高级的选项, 比如:
使用 Squoosh https://squoosh.app/ 以最佳压缩级别 (有损或无损) 压缩. 调整和操作图像.
使用响应式图像断点生成器 http://www.responsivebreakpoints.com/ 或 Cloudinary,Imgix https://www.imgix.com/ 这样的服务来实现自动化图像优化. 此外, 在许多情况下, 使用 srcset 和 sizes 可以获得最佳效果.
要检查响应标记的效率, 你可以使用 https://github.com/filamentgroup/imaging-heap (一个命令行工具)来检测不同视窗大小和设备像素比的效果.
使用 https://github.com/aFarkas/lazysizes 来延迟加载图像和 iframes, 这是一个通过检测用户交互 (或之后我们将讨论的 IntersectionObserver) 来触发任何可见性修改的库.
注意默认加载的图像, 它们可能永远也用不到 -- 例如, 在 carousels,accordions 和 image galleries.
考虑根据请求类型来指定的不同图像显示以通过 Sizes 属性切换图像 https://www.filamentgroup.com/lab/sizes-swap/ , 比如, 操作 sizes 来交换 magnifier 组件中的数据源.
为防止前景和背景图像的意外下载, 请检查图像下载的不一致性.
为了从根本上优化存储, 你可以使用 Dropbox 的新格式(Lepton) https://github.com/dropbox/lepton 来对 JPEG 执行平均值可达到 22% 的无损压缩.
注意 CSS 属性中的 aspect-ratio 属性 https://drafts.csswg.org/css-sizing-4/#ratios 和 intrinsicsize 属性, 它们允许为图像设置宽高和尺寸, 因此浏览器为了避免样式错乱 https://24ways.org/2018/jank-free-image-loads/ , 可以在页面加载期间提前预留一个预定义的布局槽.
如果你喜欢冒险, 为了更快地通过网络传输图像, 可以使用基于 CDN 的实时过滤器 Edge workers 来终止并重排 HTTP/2 流. Edge workers 使用你可以控制的 JavaScript 流模块(它们是运行在 CDN 上的, 可以修改响应流), 这样你就可以控制图像的传输. 相对于 service worker 来说, 这个过程时间稍长, 因为你无法控制传输过程, 但它确实适用于 Edge workers. 因此, 你可以在针对特定登录页面逐步保存的静态 JPEG 上使用它们.
https://pbs.twimg.com/media/DY1XZ28VwAAwjd8.jpg
https://github.com/filamentgroup/imaging-heap (一个用于检测跨视窗大小及设备像素比的加载效率的命令行工具)的输出样例,(图像来源 https://pbs.twimg.com/media/DY1XZ28VwAAwjd8.jpg ) (详细预览)
响应式图像的未来可能会随着采用客户端提示而发生巨变. 客户端提示内容是 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% 的性能. 不幸的是, 客户端提示仍然需要得到浏览器的支持才行 http://caniuse.com/#search=client-hints .Firefox 和 Edge 正在考虑对它的支持. 但如果同时提供普通的响应图像标记和客户端提示的 <meta> 标记, 浏览器将评估响应图像标记并使用客户端提示 HTTP header 请求相应的图像.
还不够? 那么你可以使用多种背景图像技术来提高图像的感知性能. 请记住, 处理对比以及模糊不必要细节 (或删除颜色) 也可以减小文件大小. 你想放大一张小照片而不至于损失质量的话, 可以考虑使用 Letsenhance.io https://letsenhance.io .
到目前为止, 这些优化只涉及基本内容. Addy Osmani 出版了一份非常详细的关于基本图像优化的指南 https://images.guide/ , 这份指南对于图像压缩和颜色管理的细节有很深入的讲解. 例如, 你可以模糊图像中不必要的部分 (通过应用高斯模糊过滤器) 来减小文件大小, 甚至可以移除颜色或将图像转换为黑白来进一步缩小文件. 对于背景图像, 从 Photoshop 中导出的照片质量只有 0 到 10% 是完全可以接受的. 不要在 Web 上使用 JPEG-XR -- "在 CPU 上解码 JPEG-XRs 软件端这个过程会让节省字节大小这个潜在地积极影响失效, 甚至更糟, 尤其是在 SPAs 情况下".
20. 视频优化是否得当?
到目前为止, 我们的已经讨论完了图像的相关内容, 但我们避免了关于 GIF 优点的探讨. 坦白说, 与其加载影响渲染性能和带宽的重动画 GIF, 不如选择动态 WebP(GIF 作为回退)或者用 HTML5 videos 循环来替换它们. 是的, 带有 <video> 的浏览器性能极差, 而且与图像不同的是, 浏览器不会预加载 <video> 内容, 但它们往往比 GIF 更轻量级, 更小. 别无他法了么? 那么至少我们可以通过 Lossy GIF https://kornel.ski/lossygif , https://github.com/kohler/gifsicle 或 https://github.com/pornel/giflossy 来有损压缩 GIF.
早期测试表明带有 img 标签的内联视频相较与等效的 GIF, 除了文件大小问题外, 前者的显示的速度要快 20 倍, 解码要快 7 倍. 虽然在 Safari 技术预览中声明了对 <img src=".mp4"> 的技术支持, 但是这个特性还远未普及, 因此它在近期内不会被采用.
Addy Osmani 推荐用循环内联视频来取代 GIF 动画. 文件大小差异明显(节省了 80%).(预览)
前端是不停进步的领域, 多年来, 视频格式一直在不停改革. 很长一段时间里, 我们一直希望 WebM 可以成为格式的统治者, 而 WebP(基本上是 WebM 视频容器中的一个静止图像)将取代过时的图像格式. 尽管这些年来 WebP 和 WebM 获得了 https://caniuse.com/webp 支持 https://caniuse.com/#feat=webm , 但我们所希望看到的突破并未发生.
在 2018,Alliance of Open Media 发布了一种名为 AV1 的视频格式. AV1 具有和 H.265(H.264 的改进版本)编码器类似的压缩, 但与后者不同的是, AV1 是免费的. H.265 的许可证价格迫使浏览器供应商采用性能相同的 AV1:AV1(与 H.265 一样)的压缩性能是 WebP 的两倍.
来源: https://juejin.im/post/5c5ccbefe51d457f95354a46