时间切片是一种将长时间运行的任务分解为可中断块的技术。
优势
- 提高应用程序的响应性和用户交互性
- 保证任务间的相对优先级
- 支持任务取消和暂停,提高应用程序的灵活性和可控性
- 可以从任务失败中恢复,并从中间继续执行
- 等
浏览器
因为浏览器环境的 渲染
和 JavaScript
是互斥
的,所以长时间的 Javascript
任务,导致页面 卡顿
或者失去响应
,会给用户带来极差的用户体验。
使用 时间切片
技术可以将长时间运行的任务分解为 小块
,在块之间运行其他任务,从而提高应用程序的响应性
,让用户获得更加流畅的交互体验。
API
浏览器为开发者提供以下几个 API 来避免长任务带来的阻塞效果。
- Scheduler.postTask 添加根据优先级安排的任务。(依赖requestIdleCallback)
- requestAnimationFrame 浏览器在下次重绘之前调用指定的回调函数
- Web Workers API 可以在独立于主线程的后台线程中,运行一个脚本
案例
React
当组件渲染过程中遇到复杂的计算
、大量的数据加载
或者耗时的操作
时,会导致渲染线程被阻塞
,从而导致页面卡顿、用户体验变差。
为了优化大型应用程序的性能和用户体验,React 引入了时间切片(Time Slicing)
。
源码中使用 MessageChannel 这个API来实现任务切片。详细可以看它的源码。
拓展
为什么不优先使用 setTimeout
React 任务调度器中优先使用 MessageChannel
而不是 setTimeout
的原因是因为 MessageChannel
具有更好的性能和精度,可以达到纳秒级别。
setTimeout
的最小延迟时间为 4 毫秒,每个任务都使用 setTimeout
,则会导致整个过程更多延迟。
oss
当文件过大
、网络环境较差
和文件大小不确定
时,为了更快,更稳定的提高上传能力。
OSS提供分片上传功能,可以将待上传的文件分成多个碎片(Part)分别上传,上传完成之后再调用,最终将每一部分组合成一个大的文件。
示例
下面是一个以渲染长列表
为例的 DEMO 在线
我们可以明显看到长任务渲染
有渲染的延迟,时间切片渲染
则可以直接看到渲染结果。
<!DOCTYPE html>
<html>
<head>
<title>时间切片</title>
<meta charset="UTF-8" />
<style>
#container div {
height: 20px;
margin-bottom: 6px;
background-color: aquamarine;
}
</style>
</head>
<body>
<button onclick="syncRender()">长任务渲染</button>
<button onclick="timeSliceRender()">时间切片渲染</button>
<button onclick="reset()">重置</button>
<div id="container"></div>
<script type="text/javascript">
let i = 0;
let rendering = false;
const max = 200000;
const stepMax = max / 20;
const container = document.getElementById("container");
function syncRender() {
while (i < max) {
const div = document.createElement("div");
container.append(div);
i++;
}
}
function timeSliceRender() {
rendering = true;
setTimeout(() => {
let j = 0;
while (j < stepMax && i < max) {
const div = document.createElement("div");
container.append(div);
i++;
j++;
}
if (i < max) {
timeSliceRender();
} else {
rendering = false;
}
});
}
function reset() {
if (rendering) {
alert("渲染中,稍等下");
}
i = 0;
container.innerHTML = "";
}
</script>
</body>
</html>
总结
时间切片是一种编程技术,它允许我们将大型、复杂的任务拆分成更小的片段
,并在这些片段之间插入其他任务
,以使我们的程序能够更加响应
和高效
。