Fork me on GitHub
tc9011's

【译】2018前端性能优化清单

20180211151835140623794.png

本文翻译了2018前端性能优化清单PDF简化版本,详细版本原文及其掘金翻译版可以自己去查看。

本文你将找到你可能需要考虑的前端性能问题的概述,它会确保你的响应时间快速顺畅。

准备就绪:计划和指标

  • 建立性能文化

只要团队之间没有达成一致,性能就很难长久维持。研究客户常见的投诉,看看如何改进性能来缓解这些问题。用真实数据建立一个公司量身定制的案例研究。在设计过程中就计划好项目的加载顺序和加载过程中的取舍。

  • 选择正确的指标

不是每个指标都一样重要。 研究哪些指标最重要:通常这将与您开始渲染最重要像素点的速度以及如何快速地为这些渲染的像素点提供输入响应有关。 优先处理客户所感知的页面加载。 交互时间,英雄渲染时间(Hero Rendering Times),首次有效绘制(First Meaningful Paint),速度指标通常也很重要。

  • 比最快的竞争对手快20%

在能代表你的受众的设备上收集数据。 用真实的设备代替模拟,可以选择一台Moto G4,一台中档的三星设备或一台像Nexus 5X这样的中档设备。或者通过在受限制的CPU(5倍降速)和受限制的网络(例如,150ms 往返时延,1.5 Mbps下行速度,0.7 Mbps上行速度)下来在桌面上模拟移动端体验。 最后切换到普通的3G,4G和Wi-Fi下测试。 收集这些数据,建立一个电子表格,把这些数据削减20%,并设定你的目标(性能预算)。

  • 与同事分享清单

确保你的团队的每个成员对清单都是熟悉的。 每个决策都对性能有影响,而且你的项目将极大地受益于前端开发人员正确地将性能价值传达给整个团队。 根据性能预算制定相关的设计决策。

设定切实的目标

  • 100毫秒的响应时间,每秒60帧

每帧动画应该在不到16毫秒的时间内完成 - 最好是10毫秒,从而达到每秒60帧(1秒÷60 = 16.6毫秒)的效果。保持乐观的心态并聪明地使用空闲时间。 对于动画这样的高压点,在允许的情况下不要使用它,如果不允许,尽量减少使用它。预计输入延迟时间应该低于50ms。

  • 速度指标<1250,3G网络下的交互时间<5s

目标是首次有效绘制时间在1秒(快速连接)以下,速度指标在1250毫秒以下。 将在3G网络下200美元Android手机作为基准线,可以在400ms 往返延时和400kbps传输速度下模拟,目标是交互时间<5s,重复访问时间低于2s。 尽力去把这些值降到尽可能低。

  • 关键负载切块= 15Kb,最大关键文件大小<170Kb

HTML中前14〜15Kb是最关键的负载切块,也是第一次往返(这是在400 ms 往返延时下 1秒内所得到的)预算中唯一可以交付的部分。 为达到上述目标,我们必须在关键的文件大小内进行操作。 在一般的手机上,压缩过后170Kb(解压缩后0.8-1Mb)大小的文件,解析和编译需要1秒。

确定环境

  • 选择并配置你的构建工具

不要太在意什么是很酷的。 只要能很快得到结果,并且在构建过程中没有任何问题就可以了。

  • 渐进增强

首先设计和构建核心体验,然后对支持高级特性的浏览器增强体验,创造弹性体验。 如果你的网站是在一个网络不佳的并且有个糟糕的显示屏上糟糕的浏览器上运行,速度还很快的话,那么,当它运行在一个快速网络下快速的浏览器的机器上,它只会运行得更快。

  • 选择一个强劲的性能基准线

JavaScript 的代价是最大的。 在 170kb 的预算中,已经包括了关键路径的 HTML/CSS/JavaScript、路由器、状态管理、实用程序、框架和应用程序逻辑,我们必须彻底检查网络传输成本,分析/编译时间和我们选择的框架的运行时的成本

  • 选择明智的战斗:Angular,React,Ember等。

并不是每个项目都需要一个框架,但是如果你需要一个框架的话,可以使用一个支持服务器端渲染的框架。在建立框架之前,务必在移动设备上分别测试服务器渲染和客户端渲染模式下的启动时间。你必须清楚地了解你所依赖的框架的所有细节。PRPL 模式应用程序 shell 体系结构

  • 你会使用AMP还是Instant Articles?

如果没有他们,你可以获得良好的表现,但AMP确实提供了一个免费的内容分发网络(CDN)的性能框架,而Instant Articles将提高你在Facebook上的知名度和表现。 你也可以通过把 AMP 作为你的 PWA 数据源来构建渐进增强的 Web 体验

  • 明智地选择你的CDN

根据你拥有多少动态数据,你可以将部分内容外包给静态站点生成器,将其放到CDN并从中提供静态版本,从而避免数据请求。 仔细检查您的CDN是否进行内容压缩和转换,智能HTTP / 2传输和边侧包含。

构建优化

  • 确定你的优先顺序

运行所有资产的清单(JavaScript,图像,字体,第三方脚本,页面上的“昂贵”模块),并将它们分组。 定义基本的核心体验(为传统浏览器提供完全可访问的核心内容),增强的体验(对于功能强大的浏览器而言是丰富的,完整的体验)以及额外资源(不是绝对需要而且可以被延迟加载的资源,如字体 ,轮播脚本,视频播放器,社交媒体按钮)。

将核心体验带到传统浏览器,并增强对现代浏览器的体验。 严格要求加载的资源:优先加载核心,对DomContentLoaded进行增强,并对Load事件进行额外处理。 但是:廉价的安卓手机主要运行 Chrome,尽管他们的内存和 CPU 有限,所以考虑功能检测设备内存的JavaScript API,并回退到“符合标准”技术。

  • 解析JavaScript代价很高,所以应保持其较小

使用SPA,你可能需要一些时间来初始化应用程序,然后才能呈现页面。 寻找模块和技术来加速初始渲染时间(在低端移动设备上它可以轻松地提高2-5倍)。 彻底检查每一个JavaScript的依赖关系,看看你在哪里失去了初始启动时间。

  • 考虑微小优化和逐步引导

使用服务器端渲染来获得一个快速的首次有效绘制,而且还要包含一些最小必要的 JavaScript 来保持实时交互来接近第一次的绘排。 然后,无论是按需还是时间所允许的,启动应用程序的非必要部分。 显示应用骨架而不是加载指示器。

  • 使用 tree-shaking和code-splitting 来减少负载

tree-shaking是一种清理构建过程的方法,仅包含实际在生产中使用的代码。 code-splitting将您的代码分割为按需加载的“块”。 scope hoisting检测 import 链接并可以转换成一个内联函数,不影响代码。 可以通过WebPack使用它们。 使用提前编译器将一些客户端渲染卸载到服务器。

  • 异步加载JavaScript

作为开发人员,我们必须用HTML中的deferasync属性明确告诉浏览器不要等待并开始渲染页面。 如果不必兼容IE 9及更低版本,那么请优先考虑defer; 否则,使用async静态社交分享按钮静态链接 来代替交互式地图。

  • 你是否限制了第三方脚本的影响

通常一个第三方脚本通常会调用一长串脚本。 考虑通过间隔下载资源来使用service workers。 建立内容安全策略(CSP)以限制第三方脚本的影响,例如 不允许下载音频或视频。通过iframe嵌入脚本,因此脚本无法访问DOM。同时使用 sandbox 属性进一步限制。为了压测第三方,在 DevTools 上自底向上概要地检查页面的性能。

  • HTTP缓存标头是否设置正确

仔细检查 expirescache-controlmax-age 和其他HTTP cache 头设置正确。 一般来说,资源应该在很短的时间内(如果它们可能改变的话)或无限期地(如果它们是静态的)被缓存。 使用Cache-control: immutable,该头部针对被标记指纹的静态资源设计,以避免重新验证。

静态资源优化

  • 使用 Brotli 还是 Zopfli 进行纯文本压缩

所有现代浏览器现在都支持Brotli,一种新的无损数据格式。 它比Gzip和Deflate更有效,压缩速度非常慢,但是解压速度很快。 在最高级别使用Brotli + Gzip预压缩静态资产,用Brotli在1-4级(动态)压缩HTML。 检查CDN上的Brotli支持。 或者,你可以考虑使用 Zopfli 的压缩算法,将数据编码为 Deflate,Gzip 和 Zlib 格式,并且设计为压缩一次可以多次下载。

  • 图像是否正确优化

尽可能通过 srcsetsizes<picture> 元素使用 响应式图片。通过<picture> 使用WebP格式的图像,或者JPEG回退或使用内容协商(使用Accept标头)来提供WebP图像。 对于关键图像,请使用渐进式JPEG,并将不必要的部分模糊(使用高斯模糊滤镜)。

  • Web字体是否优化

有很大可能使用 Web 网络字体,会包含没有真正被使用的字形和额外的功能。 子集的字体。 优先使用WOFF2 并使用WOFF作为后备。 立即用后备字体显示内容,然后异步加载字体 (例如 loadCSS),再按顺序切换字体。 考虑本地安装的操作系统字体。 不要忘记包含font-display: optional。如果你无法从服务器拿到字体,请务必使用 字体加载事件

交付优化

  • 是否优先加载关键的 CSS

收集开始渲染页面的第一个可见部分所需的所有CSS(称为 “关键CSS” 或 “上一层CSS”),并将其内联添加到页面的<head>中。 考虑 条件内联方法。 或者,使用HTTP/2服务器推送,但是可能需要创建 缓存监测 HTTP/2 服务器推送机制

  • 使用babel-preset-env转译ES2015 +特性

ES2015得到了很好的支持,可以考虑使用babel-preset-env来转译你所要支持的现代浏览器不支持的ES2015 +特性。 然后建立两个版本,一个在ES6和一个在ES5。 使用script type='module'让带有ES模块的浏览器支持加载文件,而旧版浏览器可以使用脚本模块加载旧版本。

  • 提高渲染性能

使用 CSS containment 隔离昂贵的组件。 确保在滚动页面或动画元素时没有延迟,并且每秒持续达到60帧。 如果这是不可能的,那么至少要使每秒帧数持续保持在 60 到 15 的范围。使用 CSS 的 will-change 通知浏览器哪个元素的哪个属性将要发生变化。

  • 是否懒加载了开销很大并使用 Intersection Observer 的代码

Intersection Observer API提供了一种异步观察目标元素与祖先元素或顶层文档的视口的变化的方式。 Chrome,Firefox,Edge和 Samsung Internet都已经支持。 WebKit状态目前正在开发中。 如果不支持交叉点观察者,仍然可以 延迟加载 一个 polyfill

  • 是否优化了渲染体验

不要低估感知性能的作用。 在加载资产的同时,尽量始终领先于客户,所以将很多处理放置到后台,响应会很迅速。 让客户参与进来,我们可以用骨架屏幕而不是加载指示器并添加转场/动画。

HTTP/2

  • 准备好HTTP/2

HTTP/2得到很好的支持,并提供了性能提升。在大多数案例中,HTTP/2会让你境况更好。缺点是你必须迁移到HTTPS,并且取决于您的HTTP/1.1用户群(用户在传统操作系统或旧版浏览器上)的大小,你可能需要发送不同的版本,这需要需要你采用不同的构建流程

  • 正确部署HTTP/2

你需要在打包模块和并行加载许多小模块之间找到一个很好的平衡点。 将你的整个界面分解成许多小模块; 然后分组,压缩和打包它们。 发送 6-10 个包是个理想的折中(对旧版浏览器也不会太差)。 通过实验和测量来为您的网站找到合适的平衡点。

  • 您是否使用Save-Data保存数据

Save-Data客户端提示请求头允许我们将应用程序和有效载荷为成本和性能受限的用户定制。 例如,你可以将高DPI图像请求重写为低DPI图像,删除网页字体和花哨的特效,关闭视频自动播放,服务器推送,甚至更改提供标记的方式。

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

仔细检查你的安全头部被正确设置消除已知的漏洞检查你的证书。 确保所有外部插件和跟踪脚本都通过HTTPS加载,不允许跨站点脚本,HTTP 严格传输安全头内容安全策略头是正确的设置。

  • 你的服务和CDN是否支持HTTP/2

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

  • 是否启动了OCSP stapling

通过在你的服务上启动 OCSP stapling,你可以加速 TLS 握手。 OCSP协议不要求浏览器花时间下载然后在列表中搜索证书信息,因此缩短握手所需的时间。

  • 你是否已采用了 IPv6

研究表明,由于“邻居”发现(NDP)和路由优化,IPv6使网站速度提高了10%到15%。 更新IPv6的DNS,以维持未来的防火墙。 只要确保在整个网络上提供双栈支持 - 它允许IPv6和IPv4同时并行运行。 毕竟,IPv6不是向后兼容的。

  • 使用了 HPACK 压缩吗

如果你使用的是HTTP / 2,请仔细检查您的服务器是否对HTTP响应头实现 HPACK 压缩,以减少不必要的开销。 由于HTTP / 2服务器相对较新,因此可能不完全支持该规范,HPACK 就是一个例子。 可以使用 H2spec 这个伟大的(如果技术上很详细)工具来检查。

  • 是否使用了 service workers 来缓存以及用作网络回退

网络上的性能优化不会比用户计算机上本地存储的缓存更快。 如果您的网站通过HTTPS运行,然后将静态资源缓存到service workers缓存中,并存储离线回退(甚至脱机页面),并从用户的计算机检索它们,而不是访问网络。

测试和监控

  • 监控混合内容警告

如果你最近已经从HTTP迁移到HTTPS,请确保使用Report-URI.io等工具来监控主动和被动混合内容警告。 您还可以使用 Mixed Content Scan扫描启用HTTPS的网站以查看混合内容。

  • DevTools中的开发工作流程是否经过优化

选择一个调试工具,然后单击每个按钮。 确保您了解如何分析渲染性能、控制台输出以及如何调试JavaScript和编辑CSS样式。

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

在Chrome和Firefox中测试是不够的。 看看你的网站如何在代理浏览器和旧版浏览器(包括UC Browser和Opera Mini)。 在你感兴趣的国家测量互联网速度平均值,在未来发现“大惊喜”。 测试网络节流,并仿真一个高 DPI 设备。BrowserStack 很不错,但也要在实际设备上测试。

  • 是否启用了持续监控

良好的性能指标是被动和主动监控工具的组合。 拥有一个WebPagetest的私有实例并使用Lighthouse总是有利于快速测试,而且还可以使用RUM工具(如Calibre,SpeedCurve等)建立持续监控。 设置你自己的用户计时标记来度量和监控特定的业务指标。

速效方案

这个列表非常全面,完成所有的优化可能需要一段时间。 所以如果你只有1个小时来进行重大的改进,你会怎么做? 让我们把这一切归结为10个低挂的水果。 显然,在你开始之前和完成之后,测量结果,包括开始渲染时间以及在 3G 和电缆连接下的speed Index。

  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 和图像。
汤诚 wechat
欢迎订阅我的微信公众号
坚持原创技术分享,您的支持将鼓励我继续创作!
------ 本文结束 ------

版权声明

tc9011's Notes by Cheng Tang is licensed under a Creative Commons BY-NC-ND 4.0 International License.
汤诚创作并维护的tc9011's Notes博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证
本文首发于tc9011's Notes 博客( http://tc9011.com ),版权所有,侵权必究。