前端笔记——大数据量浏览器卡顿优化思路

news/2024/12/25 23:26:42/

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

任务分批次

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

  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({ length: 1000 }, (_, 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 通过消息传递的方式通信,使用 postMessageonmessage
  4. 安全隔离
    • Worker 线程运行在独立的作用域中,没有直接访问 DOM 或主线程变量的能力。
例子
  1. 创建一个 Worker 脚本文件

    • Worker 的代码需要放在一个单独的文件中。

    • 示例:worker.js

      // 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;
      }

  2. 主线程与 Worker 通信

    • 在主线程中加载 Worker 文件并与其交互。

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

      // 发送数据到 Worker
      worker.postMessage([1, 2, 3, 4, 5]);

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

      // 处理 Worker 的错误
      worker.onerror = function (error) {
      console.error(‘Worker error:’, error.message);
      };

  3. Worker 的终止

    • 如果 Worker 不再需要,可以终止它以释放资源。

      javascript

      复制代码
      worker.terminate();


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({ length: 1e7 }, (_, 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({ length: 1000 }, (_, 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);

http://www.ppmy.cn/news/1558109.html

相关文章

c++类型判断和获取原始类型

std::traits学习 类型判断和退化&#xff08;获取原始类型&#xff09;的原理就是利用模板的特例化。根据调用模板的特例化&#xff0c;在特例化模板中实现判断的逻辑或者退化的逻辑。 一、类型判断 判断整型数据的模板类 #include <iostream> namespace zk {templa…

Linux运维常见命令

vi/vim快捷键使用 1)拷贝当前行 yy ,拷贝当前行向下的5行 5yy&#xff0c;并粘贴&#xff08;输入p&#xff09;。 2)删除当前行 dd ,删除当前行向下的5行5dd 3)在文件中查找某个单词 [命令行下 /关键字&#xff0c;回车查找 ,输入n就是查找下一个 ] 4)设置文件的行号&…

Ubuntu 20.04 卸载和安装 MySQL8.0

卸载 首先&#xff0c;检查一下系统安装的软件包有哪些&#xff0c;使用dpkg -l | grep mysql命令&#xff1a; 为了将MySQL卸载干净&#xff0c;这些文件都需要被删除。 在Ubuntu20.04系统下&#xff0c;卸载干净MySQL8.0以确保下一次安装不会出错&#xff0c;可以按照以下…

微软的AI转型故事

在一次备受瞩目的深度访谈中&#xff0c;微软的CEO萨提亚纳德拉与著名投资人比尔格里和布拉德格斯特纳展开了一场关于微软十年转型与AI未来的深入探讨。这次对话不仅回顾了微软在纳德拉领导下的重大发展轨迹&#xff0c;也为AI时代的战略布局提供了洞见。 纳德拉的职业起点 故…

视频汇聚融合云平台Liveweb一站式解决视频资源管理痛点

随着5G技术的广泛应用&#xff0c;各领域都在通信技术加持下通过海量终端设备收集了大量视频、图像等物联网数据&#xff0c;并通过人工智能、大数据、视频监控等技术方式来让我们的世界更安全、更高效。然而&#xff0c;随着数字化建设和生产经营管理活动的长期开展&#xff0…

闯关leetcode——3158. Find the XOR of Numbers Which Appear Twice

大纲 题目地址内容 解题代码地址 题目 地址 https://leetcode.com/problems/find-the-xor-of-numbers-which-appear-twice/description/ 内容 You are given an array nums, where each number in the array appears either once or twice. Return the bitwise XOR of all …

JavaAgent技术应用和原理:JVM持久化监控

背景 字节码增强技术 字节码增强&#xff1a;Java Agent通过修改字节码来实现对应用程序的增强&#xff0c;例如添加日志、性能监控、事务管理等。工具&#xff1a;常用的字节码增强工具包括ASM、Javassist、Byte Buddy等。 JavaAgent技术基于JVM工具接口&#xff08;JVMTI&…

京准电钟解读,NTP网络授时服务器如何提升DCS系统效率

京准电钟解读&#xff0c;NTP网络授时服务器如何提升DCS系统效率 京准电钟解读&#xff0c;NTP网络授时服务器如何提升DCS系统效率 NTP 网络授时服务器为防火墙内的网络设备、终端、服务器提供准确、可靠和安全的高精度卫星时间参考&#xff0c;可为它支持数万台支持标准的网…