[译] 2018 前端性能优化清单 - 第 4 部分

下面是前端性能问题的概述,您可能须要考虑以确保您的响应时间是快速和平滑的。php


  1. 你是否激活了链接以加快传输?

使用 资源提示 来节约时间,如 dns-prefetch (在后台执行 DNS 查询),preconnect (告诉浏览器在后台进行链接握手(DNS, TCP, TLS)),prefetch (告诉浏览器请求一个资源) and preload (预先获取资源而不执行他们)。css

大部分时间,咱们至少会使用 preconnectdns-prefetch,咱们会当心使用 prefetchpreload;前者只能在你很是肯定用户后续须要什么资源的状况下使用(相似于采购渠道)。注意,prerender 已被弃用,再也不被支持。html

Note that even with preconnect and dns-prefetch, the browser has a limit on the number of hosts it will look up/connect to in parallel, so it's a safe bet to order them based on priority (thanks Philip!).前端

请注意,即便使用 preconnectdns-prefetch,浏览器也会对它将并行查找或链接的主机数量进行限制,所以最好是将它们根据优先级进行排序(感谢 Philip!)。android

事实上,使用资源提示多是最简单的提升性能的方法,它确实颇有效。何时该使用什么?Addy Osmani 已经作了解释,咱们应该预加载肯定将在当前页面中使用的资源。预获取可能用于将来页面的资源,例如用户还没有访问的页面所需的 Webpack 包。ios

Addy 的关于 Chrome 中加载优先级的文章展现了 Chrome 是如何精确地解析资源提示的,所以一旦你决定哪些资源对页面渲染比较重要,你就能够给它们赋予比较高的优先级。你能够在 Chrome DevTools 网络请求表格(或者 Safari Technology Preview)中启动“priority”列来查看你的请求的优先级。git

the priority column in DevTools

DevTools 中的 "Priority" 列。图片来源于:Ben Schwarz,重要的请求github

例如,因为字体一般是页面上的重要资源,因此使用 preload 请求浏览器下载字体老是一个好主意。你也能够动态加载 JavaScript ,从而有效的执行延迟加载。一样的,由于 <link rel="preload"> 接收一个 media 的属性,你能够基于 @media 查询规则来有选择性地优先加载资源。web

一些必须牢记于心的陷阱:preload 适用于将资源的下载时间移到请求开始时,可是这些缓存在内存中的预先加载的资源是绑定在所发送请求的页面上,也就意味着预先加载的请求不能被页面所共享。再者,preload 与 HTTP 缓存配合得也很好:若是缓存命中则不会发送网络请求。chrome

所以,它对后发现的资源也很是有用,如:经过 background-image 加载的一幅 hero image,内联关键 CSS (或 JavaScript),并预先加载其余 CSS (或 JavaScript)。此外,只有当浏览器从服务器接收 HTML,而且前面的解析器找到了 preload 标签后,preload 标签才能够启动预加载。因为咱们不等待浏览器解析 HTML 以启动请求,因此经过 HTTP 头进行预加载要快一些。早期提示将有助于进一步,在发送 HTML 响应标头以前启动预加载。

请注意:若是你正在使用 preloadas 必须定义不然什么都不会加载,还有,预加载字体时若是没有 crossorigin 属性将会获取两次

  1. 你优化渲染性能了吗?

使用 CSS containment 隔离昂贵的组件 - 例如,限制浏览器样式、隐藏导航栏的布局和绘制,第三方组件的范围。确保在滚动页面时没有延迟,或者当一个元素进行动画时,持续地达到每秒 60 帧。若是这是不可能的,那么至少要使每秒帧数持续保持在 60 到 15 的范围。使用 CSS 的 will-change 通知浏览器哪一个元素的哪一个属性将要发生变化。

此外,评估运行时渲染性能(例如,使用 DevTools)。能够经过学习 Paul Lewis 免费的关于浏览器渲染优化的 Udacity 课程和 Emily Hayman 的文章优化网页动画和交互来入门。

一样,咱们有 Sergey Chikuyonok 这篇文章关于如何正确使用 GPU 动画。注意:对 GPU-composited 层的更改是代价最小的,若是你能经过“不透明”和“变形”来触发合成,那么你就是在正确的道路上。

  1. 你优化过渲染体验吗?

组件以何种顺序显示在页面上以及咱们如何给浏览器提供资源当然重要,可是咱们一样也不能低估了感知性能的角色。这一律念涉及到等待的心理学,主要是让顾客在其余事情发生时保持忙碌。这就涉及到了感知管理优先开始提早完成宽容管理

这一切意味着什么?在加载资源时,咱们能够尝试始终领先于客户一步,因此将不少处理放置到后台,相应会很迅速。让客户参与进来,咱们能够用骨架屏幕实例演示),而不是当没有更多优化可作时、用加载指示,添加一些动画/过渡欺骗用户体验

HTTP/2

  1. 迁移到 HTTPS,而后打开 HTTP/2.

在谷歌提出向更安全的网页进军以及认为 Chrome 中全部的 HTTP 网页都是“不安全”的后,迁移到[HTTP/2]((https://http2.github.io/faq/)是不可避免的。HTTP/2[支持得很是好]it isn't going anywhere; and, in most cases, you're better off with it.(不知道啥意思,求助)。一旦运行在 HTTPS 上,你至少可以在 service workers 和 server push 方面得到显著的性能提高

HTTP/2

最终,谷歌计划将全部 HTTP 页面标记为不安全的,并将有问题的 HTTPS 的 HTTP 安全指示器更改成红色三角形。(图片来源

最耗时的任务将是迁移到 HTTPS,取决于你的 HTTP/1.1 用户基础有多大(即便用旧版操做系统或浏览器的用户),你将不得不为旧版的浏览器性能优化发送不一样的构建版本,这须要你采用不一样的构建流程。注意:开始迁移和新的构建过程可能会很棘手,并且耗费时间。对于本文的其他部分,我假设您将要么切换到 HTTP/2,要么已经切换到 HTTP/2。

  1. 正确地部署 HTTP/2.

再次,经过 HTTP/2 提供资源须要对现阶段正如何提供资源服务进行局部检查。您须要在打包模块和并行加载多个小模块之间找到一个良好的平衡。最终,仍然是最好的请求就是没有请求,然而咱们的目标是在快速传输资源和缓存之间找到一个好的平衡点。

一方面,你可能想要避免合并全部资源,而不是把整个界面分解成许多小模块,压缩他们(做为构建过程的一部分),经过“侦察”的方法引用和并行加载它们。一个文件的更改不须要从新下载整个样式表或 JavaScript。这样还能够[最小化解析时间](https://css- s.com/musings-on-http2-and-bundling/),并将单个页面的负荷保持在较低的水平。

另外一方面,打包仍然很重要。首先,压缩将获益。大包的压缩将从字典重用中获益,而小的单独的包则不会。有标准的工做来解决这个问题,但如今还远远不够。其次,浏览器还没有为这种工做流优化。例如,Chrome 将触发进程间通讯(IPCs),与资源的数量成线性关系,所以页面中若是包含数以百计的资源将会形成浏览器性能损失。

Progressive CSS loading

为了得到使用 HTTP/2 最好的效果,能够考虑使用渐进地加载 CSS,正如 Chrome 的 Jake Archibald 所推荐的。

你能够尝试渐进地加载 CSS。显然,经过这样作,您会伤害 HTTP/1.1 用户,所以您可能须要为不一样的浏览器生成和提供不一样的构建流程,做为部署过程的一部分,这是事情变得稍微复杂的地方。你可使用 HTTP/2 链接合并,它容许您使用 HTTP/2 提供的域分片,但在实践中实现这一目标是很困难的。

怎么作呢?若是你运行在 HTTP/2 之上,发送 6-10 个包是个理想的折中(对旧版浏览器也不会太差)。对于你本身的网站,你能够经过实验和测量来找到最佳的折中。

  1. 你的服务和 CDNs 支持 HTTP/2 吗?

不一样的服务和 CDNs 可能对 HTTP/2 的支持状况不同。使用TLS 够快了吗?来查看你的可选服务,或者快速的查看你的服务的性能以及你想要其支持的特性。

Is TLS Fast Yet?

Is TLS Fast Yet? allows you to check your options for servers and CDNs when switching to HTTP/2.

当你想迁移到 HTTP/2 时 TLS 够快了吗?可让你查看你的可选服务和 CDNs。

  1. 是否启动了 OCSP stapling?

经过在你的服务上启动 OCSP stapling,你能够加速 TLS 握手。在线证书状态协议(OCSP)的提出是为了替代证书注销列表(CRL)协议。两个协议都是用于检查一个 SSL 证书是否已被撤回。可是,OCSP 协议不须要浏览器花时间下载而后在列表中搜索认证信息,所以减小了握手时间。

  1. 你是否已采用了 IPv6?

由于 IPv4 即将用完以及主要的移动网络正在迅速采用 IPv6(美国已经达到50% 的 IPv6 使用阈值),[将你的 DNS 更新到 IPv6]((https://www.paessler.com/blog/2016/04/08/monitoring-news/ask-the-expert-current-status-on-ipv6) 以应对将来是一个好的想法。只要确保在网络上提供双栈支持,就可让 IPv6 和 IPv4 同时运行。毕竟,IPv6 不是向后兼容的。研究显示,多亏了“邻居”发现(NDP)和路由优化,IPv6 使得这些网站快了 10% 到 15%。

  1. 使用了 HPACK 压缩吗?

若是你使用 HTTP/2,请再次检查,确保您的服务针对 HTTP 响应头部实现 HPACK 压缩以减小没必要要的开销。因为 HTTP/2 服务相对较新,它们可能不彻底支持该规范,HPACK 就是一个例子。可使用 H2spec 这个伟大的(若是技术上很详细)工具来检查。HPACK做品

h2spec

H2spec (View large version) (Image source)

H2spec (超大图) (图片来源)

  1. 确保你的服务安全性是“防弹”的

全部实现了 HTTP/2 的浏览器都在 TLS 上运行,所以您可能但愿避免安全警告或页面上的某些元素不起做用。仔细检查你的安全头部被正确设置消除已知的漏洞检查你的证书。同时,确保全部外部插件和跟踪脚本经过 HTTPS 加载,不容许跨站点脚本,HTTP 严格传输安全头内容安全策略头是正确的设置。

  1. 是否使用了 service workers 来缓存以及用做网络回退?

没有什么网络性能优化能快过用户机器上的本地缓存。若是你的网站运行在 HTTPS 上,使用 “Service Workers 的实用指南” 在一个 service worker 中缓存静态资源并存储离线回退(甚至脱机页面)并从用户的机器中检索它们,而不是访问网络。同时,参考 Jake 的 Offline Cookbook 和 Udacity 免费课程“离线 Web 应用程序”。浏览器支持?如上所述,它获得了普遍支持 (Chrome、Firefox、Safari TP、Samsung Internet、Edge 17+),但无论怎么说,它都是网络。它有助于提升性能吗?是的,它确实作到了

测试和监控

  1. 你是否在代理浏览器和旧版浏览器中测试过?

在 Chrome 和 Firefox 中进行测试是不够的。看看你的网站在代理浏览器和旧版浏览器中是如何工做的。例如,UC 浏览器和 Opera Mini,在亚洲有大量的市场份额 (达到 35%)。在你感兴趣的国家测量平均网络速度从而避免在将来发现“大惊喜”。测试网络节流,并仿真一个高 DPI 设备。BrowserStack 很不错,但也要在实际设备上测试。

k6 可让你像写单元测试同样编写性能测试用例。

  1. 是否启用了持续监控?

有一个WebPagetest私人的实例老是有利于快速和无限的测试。可是,一个带有自动警报的连续监视工具将会给您提供更详细的性能描述。设置您本身的用户计时标记来度量和监视特定的业务指标。同时,考虑添加自动化性能回归警报来监控随着时间而发生的变化。

使用 RUM 解决方案来监视性能随时间的变化。对于自动化的类单元测试的负载测试工具,您可使用 k6 脚本 API。此外,能够了解下 SpeedTrackerLighthouseCalibre

速效方案

这个列表很是全面,完成全部的优化可能须要很长时间。因此,若是你只有一个小时的时间来进行重大的改进,你会怎么作?让咱们把这一切归结为10个低挂的水果。显然,在你开始以前和完成以后,测量结果,包括开始渲染时间以及在 3G 和电缆链接下的速度指数。

  1. 测量实际环境的体验并设定适当的目标。一个好的目标是:第一次有意义的绘制 < 1 s,速度指数 < 1250,在慢速的 3G 网络上的交互 < 5s,对于重复访问,TTI < 2s。优化渲染开始时间和交互时间。

  2. 为您的主模板准备关键的 CSS,并将其包含在页面的 <head> 中。(你的预算是 14 KB)。对于 CSS/JS,文件大小不超过 170 KB gzipped(解压后 0.8-1 MB)。

  3. 延迟加载尽量多的脚本,包括您本身的和第三方的脚本——特别是社交媒体按钮、视频播放器和耗时的 JavaScript 脚本。

  4. 添加资源提示,使用 dns-lookuppreconnectprefetchpreload 加速传输。

  5. 分离 web 字体,并以异步方式加载它们(或切换到系统字体)。

  6. 优化图像,并在重要页面(例如登陆页面)中考虑使用 WebP。

  7. 检查 HTTP 缓存头和安全头是否设置正确。

  8. 在服务器上启用 Brotli 或 Zopfli 压缩。(若是作不到,不要忘记启用 Gzip 压缩。)

  9. 若是 HTTP/2 可用,启用 HPACK 压缩并开启混合内容警告监控。若是您正在运行 LTS,也能够启用 OCSP stapling。

  10. 在 service worker 缓存中尽量多的缓存资产,如字体、样式、JavaScript 和图像。

清单下载(PDF, Apple Pages)

记住了这个清单,您就已经为任何类型的前端性能项目作好了准备。请随意下载该清单的打印版PDF,以及一个可编辑的苹果页面文档,以定制您须要的清单:

若是你须要其余选择,你也能够参考 Rublic 的前端清单和 Jon Yablonski 的“设计师的 Web 性能清单”。

动身吧

一些优化可能超出了您的工做或预算范围,或者因为须要处理遗留代码而显得过分滥用。没问题!使用这个清单做为一个通用(而且但愿是全面的)指南,并建立适用于你的环境的你本身的问题清单。但最重要的是,测试和权衡您本身的项目,以在优化前肯定问题。祝你们 2018 年的性能大涨!

**很是感谢 Guy Podjarny, Yoav Weiss, Addy Osmani, Artem Denysov, Denys Mishunov, Ilya Pukhalski, Jeremy Wagner, Colin Bendell, Mark Zeman, Patrick Meenan, Leonardo Losoviz, Andy Davies, Rachel Andrew, Anselm Hannemann, Patrick Hamann, Andy Davies, Tim Kadlec, Rey Bango, Matthias Ott, Mariana Peralta, Philipp Tellis, Ryan Townsend, Mohamed Hussain S H, Jacob Groß, Tim Swalling, Bob Visser, Kev Adamson, Aleksey Kulikov and Rodney Rehm 对这篇文章的校对,一样也感谢咱们出色的社区,分享了他们在性能优化工做中学习到的技术和经验,供你们使用。大家真正的很是了不得! **


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOS前端后端区块链产品设计人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏

相关文章
相关标签/搜索