当前位置: 首页 > article >正文

前端如何优化页面中的大量任务

直奔主题,如果页面中有100万个任务需要执行,怎么保证页面不卡顿?

可以采取以下几种策略: 

  1. 任务分片执行

    • 利用requestIdleCallbackrequestAnimationFrame来分片执行任务。requestIdleCallback可以在浏览器空闲时执行任务,而requestAnimationFrame则可以在每次重绘前执行一个任务,这样可以保证在不影响页面渲染的情况下执行任务。
  2. Web Worker多线程处理

    • 使用Web Worker可以在独立线程中执行JavaScript代码,避免主线程阻塞,从而提高页面响应速度。
  3. 懒加载技术(Lazy Loading)

    • 对于不需要立即执行的任务,可以采用懒加载技术,即在需要时才加载和执行,减少初始加载的压力。
  4. 优化DOM操作

    • 减少DOM操作和重绘重排,例如通过缓存DOM属性值来减少回流和重绘。
  5. 简化DOM结构

    • 简化DOM结构可以减少渲染和操作的复杂度,提高性能。
  6. 函数式组件和变量本地化

    • 在Vue中,使用函数式组件可以减少渲染开销,同时将多次引用的变量保存起来,减少响应式对象的getter触发次数,提高性能。
  7. 子组件分割

    • 将耗时任务分割到子组件中,利用Vue的组件粒度更新机制,避免不必要的渲染和计算。
  8. 第三方插件按需引入

    • 按需引入第三方组件库,避免体积过大,减少不必要的加载和执行。
  9. 路由懒加载

    • 在单页应用中,使用路由懒加载可以减少首页加载时需要加载的内容,加快加载速度。
  10. 监控和定位卡顿

    • 使用Performance工具监控页面性能,定位耗时任务,并进行优化。

方案1:任务分片通常是指将一个大任务分解成多个小任务,并在浏览器的空闲时间里逐一执行这些小任务,以此来避免长时间的阻塞主线程。下面是一个使用requestIdleCallback实现任务分片的示例代码。这个例子中,我们将模拟一个需要处理100万个数字并将它们相加的任务。 

// 模拟一个包含100万个数字的数组
const numbers = new Array(1000000).fill(1).map((x, i) => i + 1);

// 用于累加的变量
let sum = 0;

// 任务分片执行的函数
function processNumbers(start, end, deadline) {
  // 检查是否还有剩余任务
  if (start < end) {
    // 计算当前空闲时间可以处理的任务数量
    const chunk = Math.min((end - start) / 2, 10000); // 每次处理10000个数字
    for (let i = start; i < start + chunk; i++) {
      sum += numbers[i];
    }

    // 递归调用,处理下一批任务
    requestIdleCallback((deadline) => {
      processNumbers(start + chunk, Math.min(start + chunk * 2, end), deadline);
    });
  }
}

// 开始执行任务分片
requestIdleCallback((deadline) => {
  processNumbers(0, numbers.length, deadline);
});

window.addEventListener('load', () => {
  console.log(`The sum of numbers is: ${sum}`);
});

这段代码首先创建了一个包含100万个数字的数组,然后定义了一个processNumbers函数,该函数接受三个参数:起始索引start、结束索引enddeadline对象。deadline对象包含了timeRemaining()方法,该方法返回浏览器在当前帧剩余的时间,单位为毫秒。

processNumbers函数中,计算出当前空闲时间可以处理的任务数量,并在数组的指定范围内进行累加操作。然后,我们递归地调用requestIdleCallback来处理下一批任务,直到所有任务都被处理完毕。

最后,在页面加载完成后在控制台输出累加的结果。

注意,这个代码只是一个示例,实际应用中可能需要根据具体任务进行调整。此外,由于requestIdleCallback是异步的,所以最终的累加结果sum可能不会立即可用,需要在所有任务完成后才能获取。

 方案2:使用Web Worker可以实现多线程处理任务,这样可以避免主线程阻塞。下面是一个使用Web Worker处理100万个数字求和的示例代码。

 主线程代码(HTML文件)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      const worker = new Worker("worker.js");
      //监听worker消息
      worker.onmessage = function (e) {
        console.log(e.data);
      };
      //启动worker任务
      worker.postMessage({
        type: "start",
        numbers: new Array(1000000).fill(1).map((x, i) => i + 1),
      });
    </script>
  </body>
</html>

Web Worker代码(worker.js)

//接收主线程消息
self.onmessage = function (e) {
  if (e.data.type === "start") {
    const numbers = e.data.numbers;
    const sum = calculateSum(numbers);
    postMessage(sum);
  }
};
//计算数组中所有数字的和
function calculateSum(numbers) {
  return numbers.reduce((acc, curr) => acc + curr, 0);
}

说明

  1. 主线程代码

    • 创建一个Web Worker实例,指向worker.js文件。
    • 监听Web Worker的消息,当收到消息时,在控制台输出结果。
    • 向Web Worker发送一个包含100万个数字的数组,并启动求和任务。
  2. Web Worker代码

    • 监听主线程发送的消息,当收到类型为start的消息时,开始处理任务。
    • 定义一个calculateSum函数,使用reduce方法计算数组中所有数字的和。
    • 将计算结果通过postMessage发送回主线程。

运行步骤

  1. 将主线程代码保存为index.html文件。
  2. 将Web Worker代码保存为worker.js文件,并确保与index.html文件在同一目录下。
  3. 在浏览器中打开index.html文件,查看控制台输出的结果。

通过这种方式,我们可以利用Web Worker在后台线程中处理耗时的任务,避免阻塞主线程,提高页面的响应性能。

其他方案就不一一举例了,有兴趣的可以自己了解一下!


http://www.kler.cn/a/377404.html

相关文章:

  • 飞牛OS在Docker中安装ODOO ERP系统
  • 框架学习01-Spring
  • Javascript属性遮蔽问题
  • 【JAVA】java 企业微信信息推送
  • 全面解析Flutter中的Stream用法及实际应用
  • 音视频入门基础:FLV专题(22)——FFmpeg源码中,获取FLV文件音频信息的实现(中)
  • vue2中的v-bind相当于原生js的什么
  • 3.1 大数据时代
  • 《Apache Cordova/PhoneGap 使用技巧分享》
  • 19.公益众筹捐赠系统(基于springboot和html的Java项目)
  • HTML 语法规范——代码注释、缩进与格式、标签与属性、字符编码等
  • 【力扣热题100】[Java版] 刷题笔记-121. 买卖股票的最佳时机
  • 【那些年踩过的坑-前端篇- Mac版本】Mac电脑如何升级node.js
  • 测试和实施面试题收集
  • Rust语言有哪些常用语句?
  • m6A-BERT——基于 BERT 的模型可用于预测具有遗传信息的 MRNA 的功能
  • 速通一些常见的神经网络
  • MYSQL-查看数据表拥有的索引语法(二十二)
  • [RoarCTF 2019]Easy Calc 1
  • 蓝桥杯介绍
  • GaussDB Ustore存储引擎解读
  • 基于卷积神经网络的柑桔病害识别与防治系统,resnet50,mobilenet模型【pytorch框架+python源码】
  • Qt/C++地图动态绘制折线多边形矩形圆形标注点/可编辑拖动调整大小和位置
  • 【复盘笔记】25国考一期_套题5
  • 5G无线帧基本架构
  • Chromium 中监听browser 添加/删除等事件c++