[译] Netflix 的 Web 性能案例研究

提纲:Web 性能优化没有银弹。简单的静态网页得益于使用极少 JavaScript 代码的服务端渲染。库的谨慎使用能够为复杂的页面带来巨大的价值。

Netflix 是最受欢迎的视频流服务之一。自 2016 年在全球推出以来,公司发现许多新用户不只经过移动设备完成注册,并且还使用了不太理想的网络链接。浏览器

经过改进用于Netflix.com 注册过程 JavaScript 代码和使用预加载技术,开发人员团队能够为移动和桌面用户提供更好的用户体验,并提供多项改进。缓存

  • 减小 50% 的加载和可交互时间(适用于Netflix.com 桌面端未登陆的主页)
  • 经过把 React 和其余客户端库改成原生的 JavaScript 使打包大小减小 200 KB。React 仍在服务端使用
  • 为未来的操做预获取 HTML,CSS 和 JavaScript(React)使可交互时间减小 30%

经过嵌入更少的代码来减小可交互时间

Netflix 开发者优化性能的地方是未登陆主页,用户在此页面注册并登陆站点。安全

新用户和已登出用户的Netflix.com 主页性能优化

此页面初始包含 300KB 的 JavaScript 代码,其中一些是 React 和其余客户端代码(例如像 Lodash 的工具库),并且还有一些是必要的上下文数据用来给 React 的状态注水(hydrate)。服务器

全部 Netflix 的网页都由服务端 React 渲染,这些页面为生成的 HTML 和客户端应用提供服务,所以维持新优化的主页结构不变和保持开发人员体验的一致性一样重要。网络

Homepage 选项卡是最初使用 React 编写的组件的示例工具

使用 Chrome 的 DevTools 和 Lighthouse 来模拟 3G 网络下加载未登陆主页,结果显示未登陆主页须要 7 秒时间来加载,这段时间对于一个简单的入口页面来讲实在是过久了,因此咱们开始调查改进的可能性。经过一些性能审查,Netflix 发现他们的客户端 JS 有太高的开销。性能

经过 Chrome DevTools 的网络限速功能,查看未优化的Netflix.com 的表现。开发工具

经过关闭浏览器中的 JavaScript 来观察站点中仍在起做用的元素,开发者团队能够决定 React 在未登陆主页是否真正必要。fetch

因为页面中的多数元素是基本的 HTML,剩下的元素好比 JavaScript 点击处理和添加类能够用原生 JavaScript 来替换,而页面原来使用 React 实现的语言切换器则使用不到 300 行的原生 JavaScript 代码重构。

移植到原生 JavaScript 的组件彻底列表:

  • 基础交互(主页中的选项卡)
  • 语言切换器
  • Cookie 横幅(针对非美国访问者)
  • 分析用的客户端日志
  • 性能评估和记录
  • 广告来源引导代码(出于安全考虑,沙盒化放在 iframe 里)

虽然 React 的初始代码仅仅 45 KB,在客户端移除 React、一些库和相应的 App 代码 减小的 JavaScript 代码总量超多 200 KB ,由此在 Netflix 的未登陆主页下降了超过 50% 的可交互时间。

移除客户端 React、Lodash 和其余一些库先后的负载比较。

在实验环境下,咱们可使用Lighthouse(trace)快速测验用户是否能与 Netflix 主页交互。结果桌面端的 TTI 少于 3.5s。

可交互时间优化后的 Lighthouse 报告。

那么这个领域的度量标准呢?使用Chrome 用户体验报告咱们能够看到首次输入延迟 —— 从用户首次与你的站点交互时间到浏览器真正响应那次交互的时间 —— 对于 97% 的 Netflix 桌面用户来讲很快。结果很是棒。

首先输入延迟(FID)度量用户在与页面交互时的延迟体验。

为后续页面预加载 React

为了进一步提升浏览登陆主页的性能,Netflix 利用用户在入口页面上花费的时间针对可能会登陆的下一个页面进行资源 预加载 。

经过两项技术完成 —— 内置的 <link rel=prefetch> 浏览器 API 和 XHR 预加载。

内置的浏览器 API 包含页面头部标签内的简单连接标签。它会建议浏览器资源(例如 HTML、JS、CSS、图片)能够被预加载,虽然它并不保证浏览器真的  预加载资源,而且它缺乏其余浏览器的全面支持。

预加载技术对比

另外一方面,XHR 预加载已经成为浏览器标准不少年了,当 Netflix 团队提示浏览器缓存资源时,其成功率达到 95%。可是 XHR 预加载不能预加载 HTML 文档,Netflix 用它来为后续页面预加载 JavaScript 和 CSS 打包文件。

注意:Netflix 配置的 HTTP 响应头禁止使用 XHR 缓存 HTML(它们确实不缓存(no-cache)第二个页面的 HTML)。连接预加载会按预期工做,由于它对 HTML 有效,即便设置了不缓存(no-cache)。

// 建立新的 XHR 请求
const xhrRequest = new XMLHttpRequest();

// open the request for the resource to "prefetch"
// 打开请求来“预加载”资源
xhrRequest.open('GET', '../bundle.js', true);

// 发送!
xhrRequest.send();

经过使用浏览器内置 API 和 XHR 预加载 HTML、CSS 和 JS,可交互时间减小了 30%。这个实现不须要重写 JavaScript,也不会对未登陆主页的性能形成负面影响,并且今后之后,能以极低的风险为提高页面性能提供了很是有价值的工具。

预加载实现以后,Netflix 开发者能够经过分析页面减小的可交互时间数据来观察性能提高效果,一样使用 Chrome 开发工具直接度量资源缓存的命中状况。

Netflix 未登陆主页 —— 优化总结

经过预加载 Netflix 未登陆主页资源和优化客户端代码,Netflix 能够在注册过程当中出色地提高可交互时间指标。经过使用浏览器内置 API 和 XHR 预加载来预获取将来页面,Netflix 能够把可交互时间下降 30%。这是针对下一页面的加载,其中包含单页应用注册过程的引导代码。

Netflix 团队进行的代码优化代表,React 是一个十分有用的库,不过它可能没法为每一个问题提供足够的解决方案。经过从第一个用于注册的入口页面的客户端代码中删除 React,可交互时间减小了 50% 以上。缩短客户端上的可交互时间还可让用户以更快地速度单击注册按钮,这代表代码优化彻底能够带来更好的用户体验。

虽然 Netflix 没有在主页中使用 React,但他们为后续的页面预加载。这使得他们整个页面应用程序流程中的其余部分能够利用客户端 React。

更多关于这些优化的细节,请观看 Tony Edwards 的出色演讲:

  • YouTube 视频连接:youtu.be/V8oTJ8OZ5S0

总结

经过密切关注 JavaScript 的开销,Netflix 发现了改善可交互时间的机会。若想发现你的站点是否有机会在这点上作得更好,能够借助你的性能工具。

Netflix 决定作出的权衡是使用 React 对入口页面进行服务器渲染,同时也在其上预先获取 React 和其他注册流程的代码。这样能够优化首次加载性能,同时还能够优化其他注册流的加载时间,由于它是一个单页应用程序,所以须要下载更大的 JS 打包文件。

考虑一下是否使用原生 JavaScript 是否适合你的站点的流程。若是你确实须要使用库,那么尝试只嵌入你的用户须要的代码。预加载技术能够帮助优化将来浏览页面的加载时间。

原文连接:https://www.jianshu.com/p/83c...

相关文章
相关标签/搜索