JavaScript 中处理 100 万数据时确保性能和流畅度的几种方法

news/2025/1/4 14:00:01/文章来源:https://www.cnblogs.com/zsnhweb/p/18646202

以下是在 JavaScript 中处理 100 万数据时确保性能和流畅度的几种方法:

1. 使用 Web Workers

  • 思路
    • 将数据处理任务转移到 Web Workers,它可以在后台线程中执行代码,避免阻塞主线程,从而保证页面的流畅性。
  • 代码示例
    <!DOCTYPE html>
    <html lang="en">
    <head><meta charset="UTF-8"><title>Web Workers Example</title>
    </head>
    <body><script>const worker = new Worker('worker.js');const data = Array.from({ length: 1000000 }, (_, i) => i);worker.postMessage(data);worker.onmessage = function(event) {console.log(event.data);};</script>
    </body>
    </html>
    
    worker.js 文件中:
    onmessage = function(event) {const data = event.data;// 处理数据,例如计算每个元素的平方const result = data.map(item => item * item);postMessage(result);
    };
    
  • 解释
    • 在主线程中创建 Web Workers,将数据发送给它。
    • worker.js 文件会在后台线程中接收数据并进行处理,处理完成后将结果发送回主线程。
    • 这种方式可以避免长时间的计算阻塞主线程,保证页面交互的流畅性。

2. 分块处理

  • 思路
    • 将大数据集分成多个较小的块,然后分批处理,使用 setTimeoutsetInterval 来调度处理过程,避免长时间阻塞主线程。
  • 代码示例
    function processDataInChunks(data, chunkSize, processFn, callback) {let index = 0;function processChunk() {const endIndex = Math.min(index + chunkSize, data.length);const chunk = data.slice(index, endIndex);processFn(chunk);index = endIndex;if (index < data.length) {setTimeout(processChunk, 0);} else {callback();}}processChunk();
    }const data = Array.from({ length: 1000000 }, (_, i) => i);
    processDataInChunks(data, 1000, (chunk) => {// 处理数据,例如计算每个元素的平方const result = chunk.map(item => item * item);console.log(result);
    }, () => {console.log('数据处理完成');
    });
    
  • 解释
    • processDataInChunks 函数将数据分成大小为 chunkSize 的块。
    • 每次处理完一个块后,使用 setTimeout 调度下一个块的处理,将控制权交还给主线程,避免长时间阻塞。

3. 使用异步函数和 Promise

  • 思路
    • 结合异步函数和 Promise,将数据处理任务分解为多个异步操作,利用事件循环的特性,避免阻塞主线程。
  • 代码示例
    async function processDataAsync(data) {const chunkSize = 1000;const promises = [];for (let i = 0; i < data.length; i += chunkSize) {const chunk = data.slice(i, i + chunkSize);promises.push(processChunk(chunk));}await Promise.all(promises);console.log('数据处理完成');
    }async function processChunk(chunk) {return new Promise((resolve) => {// 处理数据,例如计算每个元素的平方const result = chunk.map(item => item * item);console.log(result);resolve();});
    }const data = Array.from({ length: 1000000 }, (_, i) => i);
    processDataAsync(data);
    
  • 解释
    • processDataAsync 函数将数据分成多个块,并为每个块创建一个 Promise
    • 使用 Promise.all 等待所有块的处理完成,在处理每个块时使用异步函数,避免阻塞主线程。

4. 使用性能优化的库

  • 思路
    • 利用一些专门为大数据处理优化的库,如 lodash_.chunk 方法来分块处理,或 RxJS 进行数据流处理。
  • 代码示例(使用 Lodash)
    const _ = require('lodash');
    const data = Array.from({ length: 1000000 }, (_, i) => i);
    const chunks = _.chunk(data, 1000);
    chunks.forEach(chunk => {// 处理数据,例如计算每个元素的平方const result = chunk.map(item => item * item);console.log(result);
    });
    
  • 解释
    • 使用 lodash_.chunk 方法将数据分成多个块。
    • 对每个块进行单独处理,避免一次处理大量数据导致的性能问题。

5. 优化算法和数据结构

  • 思路
    • 对于数据处理的算法和使用的数据结构进行优化,减少不必要的计算和操作。
  • 示例
    const data = Array.from({ length: 1000000 }, (_, i) => i);
    const result = [];
    for (let i = 0; i < data.length; i++) {// 更高效的计算,例如计算平方result.push((i * i));
    }
    console.log(result);
    
  • 解释
    • 避免使用高复杂度的算法,如嵌套循环、递归等,尽量使用简单高效的算法。
    • 选择合适的数据结构,例如使用 Set 而不是 Array 来存储唯一值。

总结

  • 使用 Web Workers 可以将数据处理任务放到后台线程,不影响主线程的运行。
  • 分块处理和使用异步函数可以将长时间的处理任务分解,避免阻塞主线程。
  • 利用性能优化的库可以简化处理过程,提高性能。
  • 优化算法和数据结构可以从根本上提高数据处理的效率。

根据具体的需求和场景,可以选择一种或多种方法来确保在处理 100 万数据时不会阻塞页面,保证页面的流畅性和性能。同时,在实际应用中,需要根据数据处理的具体类型和计算复杂度进行适当的调整和优化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/862389.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

13. 滑块控件

一、抽象滑块QScrollBar、QSlider 和 QDail 都是从 QAbstractSlider 类继承而来的,因此它们的多数方法是相同的。我们可以在终端中使用 pip 安装 pyside6 模块。 pip install pyside6QAbstractSlider 类的常用方法如下: # 实例方法 orientation() -> Qt.Orientation …

3.数据类型

3.1字符串1.正常字符串使用 或 "" 包裹起来2.注意转义字符 \ \ 显示’ \n 换行 \t tab \u4e2d \u### Unicode字符3.多行字符串编写 4.模板字符串5.字符串长度 str(变量名).length6.字符串的可变性,不可变String Buffer和StringBuilder都是可变的,String…

h5如何解决移动端适配问题

使用响应式布局(Responsive Layout)原理:通过CSS媒体查询(Media Queries)根据设备的屏幕尺寸、分辨率等属性来动态调整页面的布局和样式。媒体查询允许您针对不同的媒体类型(如屏幕、打印等)和条件(如屏幕宽度、高度、设备方向等)应用不同的CSS规则。 示例代码:例如,…

第15章 流与IO

第15章 流与IO 15.1 .NET 流的架构 .NET 流的架构主要包含三个概念:** 后台存储 、 装饰器 以及 流适配器 **,如图所示: C7.0 核心技术指南 第7版.pdf - p655 - C7.0 核心技术指南 第 7 版-P655-20240216192328 ​​ 其中** 后台存储 和 装饰器 **为流。后台存储流:负责处理…

超全性能调优标准制定指南,你一定不能错过!

0 前言 我有个朋友说他们国企的系统从未性能调优,功能测试完就上线,线上也没性能问题,何必还做性能调优? 本文搞清:为什么要做性能调优? 啥时开始做? 做性能调优是不是有标准?1 为啥做性能调优?有些性能问题是慢慢产生,到了时间就自爆 更多性能问题是由访问量波动导致…

第16章 网络

第16章 网络 纲要 .NET Framework 在 System.Net.*命名空间中包含了支持各种网络标准的类,支持的标准包括 HTTP、TCP/IP 以及 FTP 等。以下列出了其中的主要组件:​Webclient​ 类 支持通过 HTTP 或者 FTP 执行简单的下载/上传操作。​WebRequest​ 和 WebResponse​ 类 可以…

第13章 诊断

第13章 诊断 13.1 条件编译 预编译的指令见 4.16 预处理指令,我们这里的条件编译用到的指令有:​#if​​、#else​​、#endif​​、#elif​​ 条件编译指令可以进行 与 ​&&​ ​、 或 ​||​ ​、 非 ​!​ 运算。预定义指令可以通过三种方式定义:在文件中通…

第14章 并发与异步

第14章 并发与异步 14.2 线程 进 程提供了程序执行的独立环境, 进 程持有 线 程,且至少持有一个 线 程。这些 线 程共享 进 程提供的执行环境。 14.2.1 创建线程 创建线程的步骤为:实例化 ​Thread​ ​ 对象,通过构造函数传入 ​ThreadStart​ ​ 委托。 调用 ​Thread…

Sqlserver With as 实现循环递归

一、脚本示例declare @Separator varchar(10), @str varchar(100) declare @l int, @i int select @Separator=,,@str=111,22,777,99,666 select @i = len(@Separator), @l = len(@str); with cte7 as ( select 0 a, 1 b union all select b, charindex(@Separator, @str, b)+@…

JAVA 分布式锁

分布式锁 JVM 自带的 synchronized 及 ReentrantLock 锁都是单进程内的,不能跨进程,如下,同时来个两个请求被分配到不同的tomcat,这种锁将失效:REDIS 实现分布式锁 可以借助 REDIS 的setnx 命令实现: https://blog.csdn.net/T_Y_F_/article/details/144238022 注:redis …

java8--类Scanner--文件内容输入--windows路径分隔符转义

try { Scanner in = new Scanner(Paths.get("C:\Users\Administrator\IdeaProjects\untitled2\src\test\myfile.txt"),"UTF-8"); } catch (IOException ioException) { ioException.printStackTrace(); }ps: 1.打印当前工…

[Windows] 启动 Windows Update 服务失败,报:Windows 无法启动 Windows Update 服务(位于 本地计算机 上) 错误 126:找不到指定的模块

1 问题描述现象1:Windows 10 家庭版-服务(services.msc)-启动 Windows Update 服务失败,报:"Windows 无法启动 Windows Update 服务(位于 本地计算机 上) 错误 126:找不到指定的模块"注: C:\Windows\System32\wuaueng.dll 文件存在注:注册表regedit:计算机\HKEY_L…