LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

WEB开发前端调优——大数据量浏览器卡顿优化思路

admin
2024年12月26日 10:36 本文热度 106

多任务数据量处理卡顿问题

任务分批次

为避免阻塞,可以将 长时间的单一任务 拆分成多个小任务并分批执行。这样可以在两次任务之间让浏览器有时间处理渲染、用户输入等操作。两种常见方法:

  1. setTimeout 方法

    • 使用 setTimeout 将任务分段,每段任务执行完毕后,通过定时器在稍后执行下一段。
    • 例如:计算一个大型数组的和时,将数组分块,每次计算一部分,延迟剩余部分。
  2. requestAnimationFrame 方法

    • 更适合与页面绘制相关的任务。
    • 它会在每次浏览器刷新帧(通常是 16.67 毫秒,60 FPS)时调用指定的回调函数。
    • 确保在每次任务之间,浏览器有机会完成页面渲染。

例子

// 用 setTimeout 拆分长任务
function performTaskInChunks(task, chunkSize{
  let index = 0;
  function processChunk({
    const end = Math.min(index + chunkSize, task.length);
    for (; index < end; index++) {
      // 执行任务的每一小部分
      console.log(`Processing: ${task[index]}`);
    }
    if (index < task.length) {
      setTimeout(processChunk, 0); // 等待主线程空闲后继续
    }
  }
  processChunk();
}

// 用 requestAnimationFrame 分布任务
function performTaskWithRAF(task{
  let index = 0;
  function processFrame({
    if (index < task.length) {
      console.log(`Processing: ${task[index]}`);
      index++;
      requestAnimationFrame(processFrame); // 下一帧继续任务
    }
  }
  processFrame();
}

// 示例数据
const largeTask = Array.from({ length1000 }, (_, i) => i);
performTaskInChunks(largeTask, 50);  // 用 setTimeout 分块执行
performTaskWithRAF(largeTask);       // 用 requestAnimationFrame 分块执行

Web Workers后台执行

Web Workers 是解决大数据量运算导致页面卡顿问题的强大工具。通过将计算任务移到后台线程,主线程可以专注于 UI 渲染和用户交互,显著提升页面的流畅度和用户体验。

Web Workers 的优势

  1. 多线程支持

    • JavaScript 主线程与 Web Worker 是两个独立的线程。
    • 主线程主要负责页面的 UI 渲染与事件处理,而 Web Worker 执行后台计算任务。
  2. 无阻塞主线程

    • Web Workers 的计算任务不会阻塞主线程,页面可以继续响应用户操作。
  3. 与主线程通信

    • 主线程和 Web Worker 通过消息传递的方式通信,使用 postMessage 和 onmessage
  4. 安全隔离

    • Worker 线程运行在独立的作用域中,没有直接访问 DOM 或主线程变量的能力。

例子

  1. 创建一个 Worker 脚本文件

    // worker.js
    self.onmessage = function (e{
        console.log('Worker received data:', e.data);
        const result = heavyComputation(e.data);
        self.postMessage(result);
    };

    function heavyComputation(data{
        // 模拟耗时计算
        let sum = 0;
        for (let i = 0; i < data.length; i++) {
            sum += data[i];
        }
        return sum;
    }
    • Worker 的代码需要放在一个单独的文件中。
    • 示例:worker.js
  2. 主线程与 Worker 通信

    // main.js
    const worker = new Worker('worker.js');

    // 发送数据到 Worker
    worker.postMessage([12345]);

    // 接收 Worker 的处理结果
    worker.onmessage = function (e{
        console.log('Result from worker:', e.data);
    };

    // 处理 Worker 的错误
    worker.onerror = function (error{
        console.error('Worker error:', error.message);
    };
    • 在主线程中加载 Worker 文件并与其交互。
  3. Worker 的终止

    worker.terminate();
    • 如果 Worker 不再需要,可以终止它以释放资源。

Web Workers 的类型

  1. Dedicated Workers(专用 Worker) :

    • 最常用的 Worker 类型。
    • 一个 Worker 仅供一个主线程使用。
  2. Shared Workers(共享 Worker) :

    • 可被多个主线程共享。
    • 不同页面的同源脚本可以共享同一个 Worker。
  3. Service Workers

    • 主要用于控制网络请求和缓存,常见于 PWA 应用。
    • 不直接用于数据计算。

Web Workers 的局限性

  1. 无法访问 DOM

    • Worker 线程不能直接操作页面的 DOM。
    • 需要通过消息传递将结果交回主线程,由主线程更新 UI。
  2. 通信开销

    • 主线程和 Worker 之间的通信需要序列化和反序列化,处理复杂数据时可能会增加延迟。
  3. 浏览器支持

    • 大多数现代浏览器支持 Web Workers,但较老版本浏览器可能不支持。
  4. 额外的资源开销

    • Worker 是独立线程,占用额外的内存和计算资源。

优化示例:使用 Web Worker 处理大数据计算

以下是一个计算大数据数组总和的例子:

// worker.js
self.onmessage = function (e{
    const data = e.data;
    let sum = 0;
    for (let i = 0; i < data.length; i++) {
        sum += data[i];
    }
    self.postMessage(sum);
};

// main.js
const worker = new Worker('worker.js');
const largeData = Array.from({ length1e7 }, (_, i) => i); // 大量数据

console.log('Sending data to worker...');
worker.postMessage(largeData);

worker.onmessage = function (e{
    console.log('Result from worker:', e.data); // 显示总和
};

worker.onerror = function (error{
    console.error('Worker error:', error);
};

利用空闲时间执行

requestIdleCallback 是一种浏览器 API,它允许开发者在浏览器的空闲时间执行非紧急的后台任务,而不会影响关键的渲染和用户交互操作。

这个 API 的主要目的是提高页面的流畅度和响应性,尤其是在需要执行较轻量的后台任务时,比如日志记录、数据预加载等。

优势

利用浏览器空闲时间

  • 只有在浏览器完成关键任务(如页面布局、渲染和事件处理)并且有空闲时间时,才会调用 requestIdleCallback 提供的回调函数。

带有超时机制

  • 如果任务不能在空闲时间内执行(如因为任务队列繁忙),可以通过超时设置确保任务最终被执行。

低优先级任务的好帮手

  • 专为非紧急任务设计,比如分析用户行为、缓存数据、预取资源等。

例子

// 定义任务队列
const tasks = Array.from({ length1000 }, (_, i) => () => console.log(`Task ${i}`));

// 使用 requestIdleCallback 处理任务
function processTasks(deadline{
    while (deadline.timeRemaining() > 0 && tasks.length > 0) {
        const task = tasks.shift(); // 从队列中取出任务
        task(); // 执行任务
    }

    // 如果还有剩余任务,继续请求空闲回调
    if (tasks.length > 0) {
        requestIdleCallback(processTasks);
    }
}

// 开始处理任务
requestIdleCallback(processTasks);

该文章在 2024/12/26 10:36:24 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved