浏览器空闲api性能优化---动态插入dom

一、概念

requestIdleCallback 是一个Web API,它安排在浏览器的空闲期间运行 JavaScript 函数。 requestAnimationFrame: 这个API通常用于动画,但也可以用来执行需要在下一次屏幕刷新之前完成的计算。

requestIdleCallback不同,它在每帧都会运行,所以你需要注意不要执行过于耗时的操作,以免影响到动画性能。

这使得开发人员能够在主事件循环空闲时执行背景和低优先级工作,而不会影响到关键的事件,如动画和输入响应。简单来说,这个 API 为你提供了一个优化网页性能的方法,通过把非紧急任务安排在浏览器有额外空闲时间时才去执行。

这个API的基础用法是:

scss 复制代码
requestIdleCallback(myNonEssentialWork);

Deadline 对象包含两个重要的属性:

  1. timeRemaining(): 这是一个函数,返回一个 DOMHighResTimeStamp,表示当前帧中剩余的空闲时间(以毫秒为单位)。当这个值大于 0 时,表示还有时间可以进行不打断用户操作的后台工作。
  2. didTimeout: 这是一个布尔值,指示回调是否已超过指定的超时时间。如果您在调用 requestIdleCallback 时没有设置超时,那么 didTimeout 将始终为 false。如果你设置了超时时间,当任务最终执行时(即使当前不是空闲时期),didTimeout 将会是 true

那么在使用场景下,渲染一个excel表格会有大量数据时,我们通过xlsx.js库进行一个文件上传读取会等待几秒,页面才会出现,这给用户的感觉就是卡顿,我们可以借助浏览器的这个api来解决

这个是解析对应excel表格,并通过自己封装的高阶函数去分块渲染对应的数据

通过xlsx在前端上传excel获取到数据,然后封装函数去动态给table赋值

ini 复制代码
import * as XLSX from 'xlsx';
function uploadChange(file) {
  tableData.value = [];
  // 将上传的excel文件转成js对象
  const reader = new FileReader();
  // 拿到字符串分隔

  fileName.value = file.name.split('-')[0];

  reader.onload = async e => {
    const data = e.target?.result;
    const workbook = XLSX.read(data, { type: 'binary' });
    const sheetNames = workbook.SheetNames;
    const sheet1 = workbook.Sheets[sheetNames[0]];
    const jsonData = XLSX.utils.sheet_to_json(sheet1);

    // 调用batchProcess开始分批处理
    batchProcess(jsonData, updateTableData);
    
    lazyLoading();
    jsonData.forEach((item, index) => {
      translateList.value.push(item.en);
    });
  };
  reader.readAsBinaryString(file.raw);
}

options = { batchSize: 20, idleDeadline: 50 }每次20条,超过50s就会强制更新,保证会有数据展示

arduino 复制代码
/**
 * 这个函数将在浏览器空闲时分批处理数据
 * @param {Array} data - 要渲染到table中的数据数组
 * @param {Function} updateFunc - 用于更新tableData的函数
 * @param {object} options - 可选项,包含batchSize和idleDeadline
 */
export function batchProcess(data: any[], updateFunc: Function, options = { batchSize: 20, idleDeadline: 50 }) {
  let position = 0;

  function processNextBatch(deadline: { timeRemaining: () => number; didTimeout: any }) {
    // 根据空闲时间和指定的批处理大小来更新数据
    while ((deadline.timeRemaining() > 0 || deadline.didTimeout) && position < data.length) {
      const end = Math.min(position + options.batchSize, data.length);
      const batch = data.slice(position, end);
      // 更新tableData
      updateFunc(batch);
      position = end;
    }
    if (position < data.length) {
      // 如果还有数据,继续请求下一批处理
      requestIdleCallback(processNextBatch, { timeout: options.idleDeadline });
    }
  }
  // 首次调用处理函数
  requestIdleCallback(processNextBatch);
}

认识一个web api还是得去看浏览器的兼容性,老旧的浏览器还是得考虑好使用其他来实现

相关推荐
LaughingZhu5 小时前
Product Hunt 每日热榜 | 2026-05-21
前端·人工智能·经验分享·chatgpt·html
怕浪猫5 小时前
Electron 开发实战(一):从零入门核心基础与环境搭建
前端·electron·ai编程
小鹏linux5 小时前
Ubuntu 22.04 部署开源免费具有精美现代web页面的Casdoor账号管理系统
linux·前端·ubuntu·开源·堡垒机
前端若水6 小时前
会话管理:创建、切换、删除对话历史
前端·人工智能·python·react.js
Bigger6 小时前
mini-cc:一个轻量级 AI 编程助手的诞生
前端·ai编程·claude
涵涵(互关)7 小时前
Naive-ui树型选择器只显示根节点
前端·ui·vue
BY组态7 小时前
Ricon组态系统最佳实践:从零开始构建物联网监控平台
前端·物联网·iot·web组态·组态
BY组态7 小时前
Ricon组态系统vs传统组态软件:为什么选择新一代Web组态平台
前端·物联网·iot·web组态·组态
SoaringHeart7 小时前
Flutter进阶:OverlayEntry 插入图层管理器 NOverlayZIndexManager
前端·flutter
放下华子我只抽RuiKe57 小时前
React 从入门到生产(四):自定义 Hook
前端·javascript·人工智能·深度学习·react.js·自然语言处理·前端框架