众里寻他千百度

JavaScript的成本– Dev Channel – Medium

原文链接: medium.com

JavaScript的成本

随着我们网页开发越来越依赖JavaScript,有时我们会在不经意之前为此付出代价。本文中,我会介绍为什么简单的规则会帮助你的网站在移动设备上快速加载和交互。

较少的代码=较少的解析/编译+较少的传输+较少的解压缩

网络

当大多数开发人员考虑JavaScript的成本时,他们会考虑下载和执行成本。发送更多字节的JavaScript需要的时间越长,用户的连接越慢。 即使在第一世界国家,这也是一个问题,因为用户有效的网络连接类型实际上可能不是3G,4G或WiFi。 你可能在咖啡店Wifi,但连接到2G速度的蜂窝热点。

您可以减少JavaScript的网络传输成本:

减少您向用户发送的JavaScript的最佳实践。

解析/编译

下载完成后, JavaScript最昂贵的消耗之一是 JS引擎解析/编译代码.在 Chrome DevTools的Performance 面板,解析和编译是黄色的“Scripting” 的一部分。

下拉框可以让你查看解析/编译时间。

Chrome DevTools“性能”面板>的下拉菜单。 通过启用V8的运行时调用统计,我们可以看到分析和编译等阶段花费的时间。 这有什么用呢?

**花费很长时间解析/编译代码会严重延迟用户与您的网站进行交互的时间。 您发送的JavaScript越多,在网站交互之前解析和编译的时间就越长。 .

逐字节地, 浏览器处理JavaScript比同等大小的图像或Web字体更耗费时间 — Tom Dale 与JavaScript相比,在处理等效大小的图片时(涉及到大量的图片仍然需要解码!),涉及到大量的成本,但是在大多数移动硬件上,JS更容易影响页面的交互。

JavaScript和图像有不同的消耗。 图像通常不会阻塞主线程,也不会阻止界面在解码和编码时进行交互。 然而JS由于解析,编译和执行会阻塞页面交互。

当我们谈论解析和编译变慢的时候, 背景是重要的 - 我们在这里谈论的平均手机。 **平均用户可能是使用CPU和GPU速度较慢的,无L2 / L3缓存的手机,甚至可能会受到内存限制。

网络速度和设备功能并不总是匹配。 具有惊人的光纤连接的用户不一定有最好的CPU来解析和运行发送到他们的设备的JavaScript。 这反过来也是如此。一个糟糕的网络连接,但拥有一个快速的CPU。 - Kristofer Baxter,LinkedIn

JavaScript Start-up Performance,我注意到在低端和高端硬件上解析〜1MB解压(简单)JavaScript的成本。 在市场上最快的手机和普通手机之间,解析/编译代码的时间相差2-5倍。

在不同类别的桌面和移动设备上,解析1MB的JavaScript包(约250KB gzip)。 在查看解析的代价时,就是解压的数字,例如〜250KB gzip压缩到〜1MB的代码。

现实中的网站是怎样的, 比如CNN.com?

在高端的iPhone 8上,解析/编译CNN的JS只需要4秒,而普通手机(Moto G4)只需要13秒左右。 这可以显着影响用户与本网站进行完全交互的速度。

比较苹果公司的A11仿生芯片和更大众的Android硬件中枭龙617的解析时间。

这突出了在平均硬件(如Moto G4),而不仅仅是你口袋里的手机上测试的重要性。 但是,上下文很重要:针对你的用户的设备和网络条件进行优化

分析数据可以让您真正了解访问您的网站的用户的 移动设备类别

我们真的发送了太多的JavaScript吗? 可能是错误的:) 使用 HTTP Archive (top ~500K sites) 分析 移动设备上的JavaScript,我们可以看到50% 的网站需要14s才能进行交互。他们需要四秒去解析和编译JS。

在获取和处理JS和其他资源所花费的时候,用户可能会等待一段时间,也许并不奇怪。 我们一定可以在这方面做得更好。

从网页中删除不重要的JavaScript可以减少传输时间,CPU密集型解析和编译以及潜在的内存开销。 这也有助于让您的网页更快地交互。

执行时间

不仅仅是解析和编译需要消耗时间。 JavaScript执行(分析/编译代码后就运行)是主线程上必须发生的操作之一。很长的执行时间也会影响网站的交互。 如果脚本执行时间超过50ms,则交互时间被延迟了下载,编译和执行JS总共所花费的时间 - Alex Russell

为了解决这个问题,JavaScript受益于小块,以避免锁定主线程。 探索是否可以减少执行过程中正在进行的工作。

降低JavaScript交付成本的模式

当您试图保持JavaScript的解析/编译和网络传输时间较慢时,有一些模式可以帮助像基于路由的分块或 PRPL. PRPL是一种通过积极的代码分割和缓存优化交互性的模式:

让我们看看它可以产生的影响。

我们使用V8的运行时调用统计来分析流行移动网站和PWA的加载时间。 正如我们所看到的,解析时间(以橙色显示)是许多这些站点花费时间的重要部分: Wego,一个使用PRPL的站点,设法保持较低的路线解析时间,交互速度非常快。 上面的许多其他站点都采用代码分解和性能预算来降低JS的成本。

其他成本

JavaScript可以通过其他方式影响页面性能:

  • 记忆。 由于GC(垃圾收集),页面可能会出现突然暂停。 当浏览器回收内存时,JS执行被暂停,所以经常收集垃圾的浏览器可能比我们想要的更频繁地暂停执行。 避免内存泄漏和频繁的gc暂停,以保持页面运行流畅。

  • 在运行时,长时间运行的JavaScript可以阻止主线程导致无响应的页面。 将工程分成更小的部分(使用requestAnimationFrame()或requestIdleCallback()进行调度)可以最大限度地减少响应性问题。

渐进Bootstrapping

许多网站将内容可视性作为交互性的代价来优化。 为了在你有大的JavaScript包时获得一个快速的首屏,开发者有时会使用服务器端渲染; 然后在JavaScript最终获取时将其“升级”以附加事件处理程序。

小心 - 这有它自己的成本。 您1)通常发送一个比较大的HTML响应,这可以优化交互,2)可能将用户置于一个不可思议的山谷中,直到JavaScript完成处理之前,首屏外的页面不能交互。

渐进Bootstrapping可能是一个更好的方法。 发送一个最小功能的页面(由当前路由所需的HTML / JS / CSS组成)。 随着更多的资源到达,该应用程序可以延迟加载和解锁更多的功能。

Progressive Bootstrapping visual by Paul Lewis

正确的加载代码是圣杯。 PRPL和Progressive Bootstrapping是可以帮助实现这一点的模式。

结论

传输大小对于低端网络至关重要。 解析时间对于CPU绑定的设备很重要。让这些消耗比较少是很重要的。

团队发现成功采用严格的性能预算来保持其JavaScript传输和解析/编译时间较低。 见Alex Russell的Can You Afford It?: Real-world Web Performance Budgets” 有关移动预算的指导。

考虑一下我们制作的架构决策可以为应用程序逻辑留下多少JS“空间”。

如果您正在构建针对移动设备的网站,请尽可能在代表性硬件上开发,保持较低的JavaScript分析/编译时间,并采用性能预算,以确保您的团队能够关注其JavaScript性能消耗。