浏览器长任务
首先,在你的想象中,多长的任务呢算是长任务呢?1000毫秒? 还是 500毫秒,no no,都不是,超过50毫秒的就算长任务。
在了解更多前,我们先看一下 RAIL 模型
的基本概念。
RAIL 是一种以用户为中心的性能模型,它提供了一种考虑性能的结构。该模型将用户体验分解到按键操作(例如,点击、滚动、加载)中,帮助您为每个操作定义性能目标。
RAIL 代表 Web 应用生命周期的四个不同方面:响应、动画、空闲和加载。
从用户角度出发,对于感知页面加载性能分以下几个阶段:
- 0 至 16 毫秒
- 用户非常关注轨迹运动,他们不喜欢不流畅的动画。如果每秒渲染 60 个新帧,他们就认为动画很流畅。也就是说,每一帧只有 16 毫秒时间,这包括浏览器将新帧绘制到屏幕所需的时间,因而应用约有 10 毫秒的时间来生成一个帧。
- 0 到 100 毫秒
- 在此时间窗口内响应用户操作会让用户觉得结果是即时呈现的。如果时间更长,操作与用户反应之间的联系就会中断。
- 100 到 1000 毫秒
- 在此时间窗口内,用户会觉得任务进展基本上是自然连续的。对 Web 上的大多数用户来说,加载页面或更改视图是一项任务。
- 1000 毫秒或更长
- 超过 1000 毫秒(1 秒),用户的注意力就会从正在执行的任务上转移。
- 10000 毫秒或更长
- 超过 10000 毫秒(10 秒),用户会感到失望,并且可能放弃任务。他们以后可能会回来,也可能不会再回来。
为什么是50毫秒
根据 RAIL ,良好的网页性能需要在 100 毫秒内响应用户输入,让用户感觉交互是即时的。
那么,为什么超过50毫秒就算长任务呢?这一界限主要是根据浏览器的事件队列机制决定的,如果任意一次任务的耗时超过50ms,那么下一次用户输入发生时,浏览器首先要等待上一个任务执行完成再进行下一个任务,为了能够在100ms内响应用户操作,留给这一次操作响应的时间就不到50毫秒了,所以应用必须在每 50 毫秒内将控制返回给主线程。
如下图所示,红框部分即为长任务
点击长任务,我们可以在下方的详情中查看具体原因
如何优化
长任务产生的原因
- js文件过大,加载、执行慢
- js逻辑较多,累计执行慢
对应的解决方案
- js文件拆分,可以使用wepack插件
SplitChunksPlugin
- 使用动态导入,比如
import()
- 将不重要的逻辑滞后处理
- 使用
setTimeout
或者 - 使用
window.requestIdleCallback()
将不重要的任务延迟到空闲时再处理
- 使用
- 优先级高的文件,预加载
- 在
webpack
中,通过在import()
中使用magic comments(魔法注释)支持预加载,参考链接: Prefetching/Preloading modulesCOPY1
import(_/* webpackPreload: true */_ "CriticalChunk")
- 在