优化启动性能

提高启动性能通常是性能优化中最具价值的方面之一。您的应用程序启动需要多长时间?在应用程序加载时,它是否会锁定设备或用户的浏览器?这会让用户担心您的应用程序崩溃或其他问题。良好的用户体验包括确保应用程序快速加载。本文提供了有关编写新应用程序和将应用程序从其他平台移植到 Web 的性能提示和建议。

快速异步加载

无论平台如何,尽快启动始终是一个好主意。由于这是一个普遍问题,因此我们在这里不会过多关注它。相反,我们将关注构建 Web 应用程序时一个更重要的问题:尽可能异步启动。这意味着不要在应用程序主线程上的单个事件处理程序中运行所有启动代码。

相反,创建一个 Web 工作线程,在后台线程中尽可能多地执行操作(例如,获取和处理数据)。将任务委派给 Web 工作线程可以释放主线程来执行需要它的任务,例如用户事件和渲染 UI。反过来,主线程事件应包含许多小型任务,也称为 微任务,而不是更大的、更耗时的任务。

异步加载有助于防止页面和用户界面看起来(或实际变得)无响应。通过最大程度地减少单个加载任务所需的时间,应用程序的 事件循环 将在启动时继续循环。这将防止应用程序、浏览器和/或设备看起来冻结。

在最坏的情况下,阻塞主线程会导致用户卸载您的应用程序;例如,如果某人错误地启动了您的应用程序,并且他们无法阻止关闭应用程序,他们可能会采取措施以防止这种情况再次发生。

有志者事竟成…

第一次就用“正确”的方式编写所有内容比事后为了性能(和无障碍性)而进行改造要容易得多。从头开始时,使适当的代码块异步意味着不需要改造。所有纯启动计算都应在后台线程中执行,同时尽可能缩短主线程事件的运行时间。不要包含进度指示器以让用户知道正在发生什么以及他们需要等待多长时间,而是让进度条变得不必要。

另一方面,将现有应用程序移植到 Web 可能具有挑战性。原生应用程序不需要以异步方式编写,因为操作系统通常会为您处理加载。源应用程序可能有一个主循环,可以轻松地使其异步运行(通过分别运行每个主循环迭代);启动通常只是一个连续的、单块的过程,它可能会定期更新进度计。

虽然您可以使用 Web 工作线程 异步运行非常大、持续时间长的 JavaScript 代码块,但有一个很大的警告:Web 工作线程无法直接操作 DOM,并且对 window 对象的方法和属性的访问有限,包括对 WebGL 的访问。这意味着,除非您能够轻松地将启动过程中的“纯计算”块提取到工作线程中,否则您最终将不得不将大部分或全部启动代码运行在主线程上。

但是,即使像这样的代码也可以通过一些工作来实现异步。

实现异步

以下是一些关于如何构建启动过程以使其尽可能异步(无论是新应用程序还是移植应用程序)的建议。

  • 在 Web 应用程序需要的脚本标记上使用 deferasync 属性。这允许 HTML 解析器继续处理文档,而不是必须等到脚本下载并执行完毕才能继续。
  • 如果您需要解码资产文件(例如,解码 JPEG 文件并将其转换为 WebGL 稍后使用的原始纹理数据),那么在工作线程中进行解码非常有用。
  • 在处理浏览器支持的数据(例如,解码图像数据)时,请使用浏览器或设备内置的解码器,而不是自己编写或使用原始代码库中的解码器。提供的解码器几乎肯定快得多,并且可以减少应用程序的大小。此外,浏览器可能会自动并行化这些解码器。
  • 任何可以并行执行的数据处理都应该并行执行。不要依次处理一批数据;尽可能同时处理所有数据!
  • 不要在启动 HTML 文件中包含不参与 关键渲染路径 的脚本或样式表。仅在需要时加载它们。
  • 减小 JavaScript 文件的大小。尝试将文件的缩小版本发送到浏览器,并使用 Gzip 或 Brotli 等压缩方式。
  • 尽可能利用资源提示(如预连接或预加载)来指示浏览器哪些文件对您的应用程序更重要。

您能够异步执行的操作越多,您的应用程序就能更好地利用多核处理器。

移植问题

完成初始加载后,应用程序的主代码开始运行,您的应用程序可能必须是单线程的,尤其是如果它是一个移植应用程序。为了帮助主代码的启动过程,最重要的是将代码重构为小块。然后可以将这些小块在多个对应用程序主循环的调用中交错执行(以便主线程能够处理输入等)。

Emscripten 提供了一个 API 来帮助进行这种重构;例如,您可以使用 emscripten_push_main_loop_blocker() 来建立一个函数,该函数将在允许主线程继续之前执行。通过建立一个要按顺序调用的函数队列,您可以更容易地管理运行代码块而不阻塞主线程。

但是,这仍然存在一个问题,即必须重构现有的代码才能以这种方式工作。这可能需要一些时间。

我应该多异步?

您的网站越快变得可用,响应用户输入的速度越快,它看起来就会越好。一个在内容首次出现之前需要 1 或 2 秒的网站通常被认为是快速的;如果您习惯于网站需要 3 或 4 秒,那么 7 或 8 秒就会感觉很长。

在响应能力方面,用户不会注意到 50 毫秒或更短的延迟。任何超过 200 毫秒的延迟,用户都会感觉到您的网站很迟钝。在努力提高应用程序的加载速度和响应能力时,请记住,许多用户可能拥有比您更旧、更慢的计算机,他们可能会遇到比您更长的延迟!

其他建议

除了异步之外,还有其他一些事情可以帮助您提高应用程序的启动时间。以下是一些方法。

下载时间

请记住用户下载应用程序数据需要多长时间。如果您的应用程序非常受欢迎,或者必须频繁地重新下载内容,那么您应该尝试使用尽可能快的托管服务器。始终 压缩 您的数据以使其尽可能小。

数据大小

尽力优化数据的大小;更小级别文件比更大的文件下载速度更快,处理速度也更快。

主观因素

在启动过程中,您能做任何事情来帮助用户保持参与度,这将有助于使时间看起来过得更快。显示一个模拟启动画面可以提高 感知性能。对于大型网站,您能做任何事情来帮助用户感觉您的应用程序正在做些什么,而不是静静地停在那里,这将有所帮助。

另请参阅