浏览器loooo...ng任务

浏览器长任务

首先,在你的想象中,多长的任务呢算是长任务呢?1000毫秒? 还是 500毫秒,no no,都不是,超过50毫秒的就算长任务

在了解更多前,我们先看一下 RAIL 模型 的基本概念。

RAIL 是一种以用户为中心的性能模型,它提供了一种考虑性能的结构。该模型将用户体验分解到按键操作(例如,点击、滚动、加载)中,帮助您为每个操作定义性能目标。

RAIL 代表 Web 应用生命周期的四个不同方面:响应、动画、空闲和加载。

RAIL

从用户角度出发,对于感知页面加载性能分以下几个阶段:

  • 0 至 16 毫秒
    • 用户非常关注轨迹运动,他们不喜欢不流畅的动画。如果每秒渲染 60 个新帧,他们就认为动画很流畅。也就是说,每一帧只有 16 毫秒时间,这包括浏览器将新帧绘制到屏幕所需的时间,因而应用约有 10 毫秒的时间来生成一个帧。
  • 0 到 100 毫秒
    • 在此时间窗口内响应用户操作会让用户觉得结果是即时呈现的。如果时间更长,操作与用户反应之间的联系就会中断。
  • 100 到 1000 毫秒
    • 在此时间窗口内,用户会觉得任务进展基本上是自然连续的。对 Web 上的大多数用户来说,加载页面或更改视图是一项任务。
  • 1000 毫秒或更长
    • 超过 1000 毫秒(1 秒),用户的注意力就会从正在执行的任务上转移。
  • 10000 毫秒或更长
    • 超过 10000 毫秒(10 秒),用户会感到失望,并且可能放弃任务。他们以后可能会回来,也可能不会再回来。

为什么是50毫秒

根据 RAIL ,良好的网页性能需要在 100 毫秒内响应用户输入,让用户感觉交互是即时的。

那么,为什么超过50毫秒就算长任务呢?这一界限主要是根据浏览器的事件队列机制决定的,如果任意一次任务的耗时超过50ms,那么下一次用户输入发生时,浏览器首先要等待上一个任务执行完成再进行下一个任务,为了能够在100ms内响应用户操作,留给这一次操作响应的时间就不到50毫秒了,所以应用必须在每 50 毫秒内将控制返回给主线程。

如下图所示,红框部分即为长任务

long_task

点击长任务,我们可以在下方的详情中查看具体原因
long_task_detail

如何优化

长任务产生的原因

  • js文件过大,加载、执行慢
  • js逻辑较多,累计执行慢

对应的解决方案

  • js文件拆分,可以使用wepack插件 SplitChunksPlugin
  • 使用动态导入,比如 import()
  • 将不重要的逻辑滞后处理
    • 使用setTimeout或者
    • 使用 window.requestIdleCallback() 将不重要的任务延迟到空闲时再处理
  • 优先级高的文件,预加载
    • webpack中,通过在 import()中使用magic comments(魔法注释)支持预加载,参考链接: Prefetching/Preloading modules
      COPY
      1
      import(_/* webpackPreload: true */_ "CriticalChunk")
作者: 果汁
文章链接: https://guozhigq.github.io/post/bc650c39.html
版权声明: All posts on this blog are licensed under the CC BY-NC-SA 4.0 license unless otherwise stated. Please cite 果汁来一杯 !