写点什么

Netflix 网页性能优化实践

2018 年 11 月 12 日

Netflix 网页性能优化实践

通过改进 Netflix.com 注册过程中所使用的 JavaScript 及预加载技术,Netflix 开发团队为移动用户和桌面用户提供了更好的用户体验。


关于 Web 性能,没有银弹,简单的静态页面包含极少的 JavaScript,可以从服务器渲染受益。库的谨慎使用可以为复杂的页面带来巨大的价值。


Netflix是最受欢迎的视频流服务之一。自 2016 年在全球推出以来,该公司发现,许多新用户不仅在移动设备上进行了注册,还使用了不太理想的连接。


通过改进 Netflix.com 注册过程中所使用的 JavaScript 及预加载技术,开发团队能够为移动用户和桌面用户提供更好的用户体验,主要改进如下。


  • 加载和交互时间减少了 50%(Netflix.com 桌面登录主页);

  • 在从 React 和其他客户端库切换到普通的 JavaScript 之后,JavaScript 包大小减少了 200KB。服务器端仍然使用 React。

  • HTML、CSS、JavaScript(React)预加载使后续页面的浏览交互时间减少了 30%。


减少 JavaScript 传输,缩短交互时间

Netflix 针对其登录主页的性能进行了优化,用户在这个页面上注册或登录到网站。



这个页面最初包含 300KB 的 JavaScript,其中一些是 React 和其他客户端代码(比如像 Lodash 这样的实用程序库),还有一些是补充 React 状态所需的上下文数据。


Netflix 的所有网页都由服务器端渲染的 React 提供,提供生成的 HTML,然后提供客户端应用程序,因此,新优化的主页要保持结构类似,为开发人员提供一致的体验,这很重要。



使用 Chrome 的开发工具和 Lighthouse 模拟在 3G 连接上加载登录主页,结果显示,登录主页需要 7 秒的加载时间,对于一个简单的登录页面来说太长了,因此需要研究改进的可能。通过一些性能审计,Netflix 发现他们客户端的 JS 开销很高。



Chrome 开发工具中 Netflix.com 优化前的网络节流


通过在浏览器中关闭 JavaScript 并观察站点的哪些元素仍起作用,开发团队可以确定登录主页是否真得需要 React。


由于页面上的大多数元素都是基本的 HTML,剩下的元素(如 JavaScript 单击处理和类添加)可以用普通的 JavaScript 替换,并且页面的语言切换器(最初使用 React 构建)用普通的 JavaScript 重新构建只用了不到 300 行代码。


移植到普通 JavaScript 的组件列表:


  • 基础交互(主页选项卡)

  • 语言切换器

  • “Cookie 横幅(Cookie banner)”(针对非美国用户)

  • 客户端日志分析

  • 性能度量和记录

  • 广告归属检测引导代码(出于安全考虑,放在沙箱式 iFrame 中)



尽管 React 最初占用的空间仅为 45KB,但将 React、几个库和相应的应用程序代码从客户端移除后,JavaScript 的总量减少了 200KB 以上,这使得 Netflix 在登录主页的交互时间减少了 50%以上。



删除客户端 React、Lodash 和其他库前后的负载比较。


实验室环境中,我们可以使用Lighthousetrace)验证,用户现在可以与 Netflix 主页快速交互。桌面 TTI 小于 3.5 秒。



交互时间优化后的 Lighthouse 报告


实际指标呢?使用Chrome用户体验报告,我们可以看到,首次输入延迟——从用户第一次与你的网站交互到浏览器真正响应那次交互的时间——对于 97%的 Netflix 桌面用户来说是非常快的。这很棒。



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


后续页面的 React 预加载

为了进一步提高浏览登录主页的性能,Netflix 利用用户在登录页面上花费的时间对于用户可能会登录的下一个页面进行预加载。


这是通过浏览器内置的 API 和 XHR 预加载这两项技术实现的。


浏览器内置 API 由页面头部标签内的一个简单链接标签组成。它建议预加载浏览器资源(例如 HTML、JS、CSS、图像),尽管它不能保证浏览器会预加载资源,而且它也没有得到其他浏览器的完全支持。



预加载技术比较


另一方面,XHR 预加载已经成为浏览器标准多年,当 Netflix 团队提示浏览器缓存资源时,其成功率达到 95%。虽然 XHR 预加载不能用于预加载 HTML 文档,但 Netflix 使用 XHR 预加载后续页面的 JavaScript 和 CSS 包。


注意:Netflix 的 HTTP 响应头配置为使用 XHR 防止缓存 HTML(它们确实不缓存第二个页面的 HTML)。不过,“链接预加载(Link Prefetch)”会按预期工作,因为它对 HTML 有效,即使设置了不缓存。


// 新建一个XHR请求const xhrRequest = new XMLHttpRequest();// 针对预加载的资源打开请求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。


小结

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


Netflix 的折中方案是,使用 React 在服务器端渲染登录页面,但同时也为注册过程的其他部分预取 React 代码。这不仅优化了首次加载性能,还优化了注册过程其余部分的加载时间,因为它是单页应用,所以有更大的 JS 包需要下载。


考虑一下,使用普通的 JavaScript 是否适合站点的流程。如果你确实需要使用库,那么尝试下只下传用户需要的代码。预加载技术可以帮助提高未来浏览页面的加载时间。


补充说明

  • Netflix 考虑过Preact,但是,对于一个交互性比较低的简单页面流,使用普通的 JavaScript 是一个更简单的选择。

  • Netflix 尝试使用Service Workers进行静态资源缓存。当时,Safari 不支持这个 API(现在支持了),但他们现在又在探索这个 API。Netflix 的注册过程需要比客户体验更多的遗留浏览器支持。许多用户会在旧的浏览器上注册,但会在他们本地的移动应用程序或电视设备上观看 Netflix。

  • Netflix 的登录页面极为动态。这是他们的注册过程中进行 A/B 测试最多的页面,机器学习模型用于根据位置、设备类型和许多其他因素定制消息和图像。支持近 200 个国家,每个派生页面都面对着不同的本地化、法律和价值信息挑战。有关 A/B 测试的更多信息,请参阅 Ryan Burgess 的“测试,只为更好的用户体验”。


查看英文原文:A Netflix Web Performance Case Study


相关推荐:


12 月 7 日北京 ArchSummit 全球架构师峰会上,来自 Netflix 的资深软件工程师 Susheel Aroskar,将分享“Netflix API 网关 Zuul 如何做到每秒处理两百万请求”内容,重点介绍重点介绍 Zuul 的核心架构,运维,以及未来的发展规划。详情点击 https://bj2018.archsummit.com/schedule


2018 年 11 月 12 日 18:301283
用户头像

发布了 1008 篇内容, 共 313.6 次阅读, 收获喜欢 282 次。

关注

评论

发布
暂无评论
发现更多内容

开源软件联盟PostgreSQL分会投稿指南

PostgreSQLChina

数据库 postgresql 软件 投稿

我是因为这个才选择当程序员的,那么你呢?

Java架构师迁哥

天啊!怎么会有人把Spring Cloud微服务架构讲得这么透彻?

Java成神之路

Java 程序员 架构 面试 编程语言

我把Github上最牛b的Java教程和实战项目整合成了一个PDF文档

Java成神之路

Java 程序员 架构 面试 编程语言

话题讨论 | 那些年奇葩的面试经历

三号无名指

话题讨论

【硬件篇之电源纹波噪声测试】

良知犹存

硬件

Gemini双子新约软件系统开发|Gemini双子新约APP开发

开發I852946OIIO

系统开发

从构建小系统到架构分布式大系统,Spring Boot2的精髓全在这里了

Java成神之路

Java 程序员 架构 面试 编程语言

第11周学习总结

饭桶

为什么说区块链完全去中心化做不到且没有意义

CECBC区块链专委会

区块链 去中心化

Java对IPv6的支持详解:支持情况、相关API、演示代码等

JackJiang

Java 网络编程 ipv6 ipv4

史上最优美的Android原生UI框架XUI使用指南

android UI 框架开发

架構師訓練營第 1 期 - 第 11 周作業

Panda

架構師訓練營第 1 期

移动端技术方案设计的经验总结

张明云

android 架构 移动应用 架构师 技术方案

详解TCP IP网络协议栈底层原理到徒手实现

赖猫

c++ Linux 编程 程序 网络协议栈

深入理解Git的实现原理

程序员小灰

c++ git Linux 项目管理 架构师

京东T8Java架构师总结整理的《15w字的Java面试手册》,涵盖了大厂所有主流技术面试题及答案!

Java成神之路

Java 程序员 架构 面试 编程语言

架构师训练营第 1 期 - 第十一周作业

Todd-Lee

极客大学架构师训练营

如何在高速发展中等一等老人 银行数字化服务显温度

CECBC区块链专委会

银行 养老服务

如何利用小熊派获取MPU6050六轴原始数据

华为云开发者社区

物联网 IoT 小熊派

通用软件快速开发平台对企业信息化的影响

雯雯写代码

软件 快速开发 企业信息化

Reactor线程模型浅析

赖猫

c++ Linux 编程 reactor 编程语言

第十一周课后练习

饭桶

腾讯云区块链总经理李力:产业区块链的四大发展趋势

CECBC区块链专委会

区块链 大数据

二本毕业、两年Javacrud经验,面试阿里侥幸通过成功拿到P6级offer,分享面经!

Java成神之路

Java 程序员 架构 面试 编程语言

一文搞懂RESTful API

bigsai

RESTful Rest

史上最全的开源项目创作指南

开源 经验分享

解析—MyBatis在SpringBoot中动态多数据源配置

比伯

Java 编程 程序员 架构 计算机

架构师训练营第 1 期 - 第十一周总结

Todd-Lee

极客大学架构师训练营

字节总监首发1121道LeetCode算法刷题笔记(含答案)

Crud的程序员

程序员 面试 算法 字节 面试刷题

追忆

刘旭东

回忆 情绪

2021年全国大学生计算机系统能力大赛操作系统设计赛 技术报告会

2021年全国大学生计算机系统能力大赛操作系统设计赛 技术报告会

Netflix 网页性能优化实践-InfoQ