跳转到内容
返回

时间分片

写在前面

昨天(2020-9-19)看2019vueconf的时候,尤大在分享vue3的特点的时候,提到了vue和react在底层针对模板编译和jsx优化的一些不同的时候提到了一个词,时间分片;然后就做了一点功课,写个笔记。

正文

解决了什么?

  • js会阻塞ui的渲染,所以当一个操作耗时非常长时,就会造成页面内容显示滞后,带来很不好的用户体验
  • 通过将操作划分为一个个小的阶段,来执行

怎么做的?

实例

实例描述:通过js插入10000个li到ul中

使用最普通的循环插入

<ul class="list"></ul>
<script>
  "use strict";
  let list = document.querySelector(".list");
  let total = 100000;
  for (let i = 0; i < total; ++i) {
    let item = document.createElement("li");
    item.innerText = `我是${i}`;
    list.appendChild(item);
  }
</script>

使用定时器

<ul class="list"></ul>
<script>
  "use strict";
  let list = document.querySelector(".list");
  let total = 100000;
  const render = (start, end) => {
    if (end < total) {
      setTimeout(() => {
        let frag = document.createDocumentFragment();
        for (let i = start; i < end; ++i) {
          let item = document.createElement("li");
          item.innerText = `我是${i}`;
          frag.appendChild(item);
        }
        list.appendChild(frag);
        render(end + 1, end + 20);
      }, 10);
    }
  };
  render(0, 20);
</script>

使用requestAnimationFrame

<ul class="list"></ul>
<script>
  "use strict";
  let list = document.querySelector(".list");
  let total = 100000;
  let size = 20;
  let index = 0;
  const render = (total, index) => {
    if (total <= 0) {
      return;
    }
    let curPage = Math.min(total, size);
    window.requestAnimationFrame(() => {
      let fragment = document.createDocumentFragment();
      for (let i = 0; i < curPage; ++i) {
        let item = document.createElement("li");
        item.innerText = `我是${index + i}`;
        fragment.appendChild(item);
      }
      list.appendChild(fragment);
      render(total - curPage, index + curPage);
    });
  };
  render(total, index);
</script>

总结

其他

关于requestAnimationFrame和setInterval处理动画的区别

  • 帧率和循环的事件交由浏览器控制,可以更好的控制的帧率
  • 性能流畅度更优秀
  • 新api,兼容性会有些问题


上一篇
关于毕业生图像采集
下一篇
软件著作权申请