与桌面浏览器相比,在智能电视和机顶盒设备上改进交互到下次绘制 (INP) 提出了更多挑战,这归因于有限的 API 支持和适度的系统规格。在本案例研究中,您将了解 Disney+ Hotstar 如何成功克服这些障碍,并因此获得了显著的业务优势。
随着客厅设备采用率的提高,Disney+ Hotstar 意识到,在其智能电视和机顶盒应用程序中提供无缝浏览体验是一项关键的业务需求。然而,使修复此类设备的 INP 变得更加困难的原因在于,任何给定的电视型号都可能使用非常旧的浏览器版本——例如,2020 年 LG 电视使用 2018 年发布的 Chrome 68。其中一些设备也可以归类为低端设备,这意味着它们无法像旗舰平板电脑和笔记本电脑设备那样快速地响应交互。
下图比较了在 Chrome DevTools 中应用 CPU 减速 6 倍的笔记本电脑和智能电视之间加载页面所需的时间。可以看出,笔记本电脑仍然比最近制造的智能电视快得多。


虽然这些测试产生了实验室数据,但 Disney+ Hotstar 开始使用 web-vitals 库从其应用程序的实际用户那里收集现场数据,以用于交互到下次绘制 (INP),并观察到 75% 的应用程序用户在现场体验到的 INP 为 675 毫秒,根据 INP 阈值,这被认为是“差”的用户体验。
本案例研究涵盖了 Disney+ Hotstar 如何提高其流媒体应用程序的响应速度,尤其是在低端设备上。他们通过将 INP 值降低至 272 毫秒实现了 61% 的改进——仍然高于建议的 200 毫秒“良好”阈值,但朝着该目标迈出了实质性的一步。
调查结果
Disney+ Hotstar 使用 onINP
方法从 web-vitals 库的归因构建版本中检测了该应用程序。在初始阶段,遇到了各种挑战,尤其是在识别精确的目标元素方面。出现此问题的原因是,由于第三方空间导航库,所有引用都指向 body,该库在 Disney+ Hotstar 应用程序中进行了一些自定义。该库仅侦听文档 body 上的事件,然后确定实际聚焦的元素,并根据遥控器按键预测下一个焦点。
Disney+ Hotstar 首先解决了归因问题,以便可以正确识别导致高 INP 值的交互。为此,Disney+ Hotstar 记录了 focusKey
属性,该属性已存在于空间导航库中,用于当前聚焦的元素以及页面上所有可聚焦元素的映射,这类似于 web-vitals 归因构建版本中提供的交互目标。

focusKey
,以及指向触发它的元素的路径。现在,通过适当的测量和归因,现场数据中的发现报告了以下交互是 INP 最成问题的地方
- 水平轮播托盘导航。
- 垂直轮播托盘导航。
- 初始页面加载期间的交互。

通过使用 Chrome 开发者工具中的性能面板分析这些交互,人们意识到空间导航库读取所有可聚焦元素的位置并构建一个新的树。这是一个昂贵的操作,会在每次交互(例如,从一个元素移动到另一个元素)时触发布局抖动。
对于主页,空间导航库生成的树如下所示

这意味着,如果应用程序显示 10 个托盘,并且每个托盘有 7 张卡片,则托盘容器将有 70 个可聚焦元素,包括导航项。这是一个大量的交互元素。还使用了第三方轮播库,该库在水平导航期间读取每张卡片的尺寸以转换容器,从而增加了更多的交互延迟。
解决问题
为了解决整个应用程序的响应速度问题,必须分别解决几个不同的问题。
水平托盘导航改进
Disney+ Hotstar 构建了自己的内部轮播库,该库通过使用合成动画并为每个托盘读取一次尺寸(而不是为每张卡片读取一次尺寸)来避免触发布局抖动。
空间导航仅关注轮播的根,对于进一步的水平导航,我们的自定义轮播开始发挥作用。通过这种方法,Disney+ Hotstar 消除了对空间导航和旧轮播库的依赖,旧轮播库在每次导航时都会读取尺寸。
这是经过这些优化后空间导航树的外观。

以下图像是在 Chrome 开发者工具的性能面板中测量的轮播实现之前和之后的性能比较。


由于这项工作,Disney+ Hotstar 发现其应用程序的 INP 在现场显著降低。他们还通过删除第三方库设法节省了大约 35 KB(压缩后)。作为奖励,这些改进还使 Disney+ Hotstar 能够缩短他们用于衡量主页总渲染时间的自定义指标的持续时间,因为由于空间导航节点减少,布局触发的次数减少了。

垂直托盘导航改进
Disney+ Hotstar 还通过延迟加载托盘而不是预先加载所有托盘来改进垂直托盘导航性能。因此,在页面加载时,应用程序不是加载 10 个托盘实例(每个托盘实例内部都有一个轮播组件和一堆图像),而是仅加载视口中可见的两个托盘,以及上方和下方的附加托盘。渲染也被拆分为多个任务,使用 setTimeout()
屈服策略,以便主线程有更多机会处理用户交互。


初始页面加载期间的交互
对于在应用程序启动期间处理大量脚本的应用程序,INP 将会很高。这是因为浏览器必须下载、解析和评估这些脚本。当这一切发生时,主线程将被占用很长时间,并且无法快速响应用户交互。
Disney+ Hotstar 意识到,他们在应用程序启动期间(启动画面时间)处理的脚本多于实际需要的脚本,以使未来的页面加载更快。这导致了额外的脚本评估任务,这也可能对 INP 产生负面影响。
为了解决这个问题,Disney+ Hotstar 考虑动态加载大多数资源,以便他们在应用程序启动期间节省时间。但是,这样做会增加导航到未来页面的加载时间,因为 JavaScript 将不再通过此更改预先加载。为了解决这个问题,Disney+ Hotstar 开发了一个内部资源预加载器库,该库确定用户旅程中接下来可能出现的页面,并将预加载该页面的资源。例如
- 当用户在登录页面上时,资源预加载器库将预加载配置文件选择页面的资源。
- 在配置文件选择页面上,加载主页资源。
- 在主页上,加载详细信息页面的资源。
- 最后,在详细信息页面上加载观看页面的资源。
优化资源加载帮助 Disney+ Hotstar 实现了两件事:降低了应用程序的 INP(因为现在主线程相对空闲,可以执行用户交互),并减少了低端设备上的内存使用量。
如下面的屏幕截图所示,这些更改导致现场报告的 INP 数字下降了 32%。

其他改进
Disney+ Hotstar 还发现,在一些用户事件中存在长时间运行的任务,可以通过经常屈服于主线程来拆分这些任务,并更进一步,创建了一个任务生成器实用程序,该实用程序允许用户在任务执行过程中取消任务。
例如,当用户在托盘上浏览多个卡片时,会发生以下情况
- 下一个卡片被聚焦。
- 如果需要,卡片会被翻译。
- 聚光灯被更新。
- 预告片(如果存在)被获取,并且播放被启动。
- 分析事件被触发以进行操作。
如果在该过程中,用户聚焦于下一个卡片,则其余步骤将不需要执行。例如,如果用户已移动到下一个卡片,则不再需要为特定标题获取预告片和初始化播放器。因此,可以中止这些任务以释放主线程。
Disney+ Hotstar 的任务生成器实用程序接受一个函数(即任务),当中间出现另一个任务时,上一个任务将被中止,从而节省了不必要的任务执行,并可以快速对必要的任务采取行动。
结果
总的来说,Disney+ Hotstar 应用程序的 INP 从 675 毫秒降至 272 毫秒,代表着 近 60% 的改进! 此外,托盘交互延迟特别从大约 400 毫秒减少到大约 100 毫秒。

业务影响:每周卡片浏览量从每用户 111 次增加到 226 次!这是一个 100% 的增长,表明更快、响应更灵敏的界面更有可能让用户长时间参与。

这仅仅是开始,Disney+ Hotstar 仅触及了以 INP 指标为指导改进渲染和交互性能的表面。他们的团队很高兴在不久的将来让 Disney+ Hotstar 为他们的客户带来如黄油般顺滑的体验。
感谢 Disney+ Hotstar 的 Ayush、Ajay、Kiran、Milan 和 Richa 为扭转局面所做的努力。
特别感谢 Disney+ Hotstar 工程主管 Ankeet Maini 和 Disney+ Hotstar 客户体验主管 Rahul Krishnan P 对这项创新工作的支持,以及 Google 的 Jeremy Wagner、Gilberto、Barry Pollard 和 Brendan Kenny 对本案例研究的审查和发布提供的帮助。