首页 > web前端 > js教程 > 正文

处理大型数组时如何确保 UI 响应灵敏?

Mary-Kate Olsen
发布: 2024-11-04 10:59:30
原创
813 人浏览过

How to Ensure a Responsive UI When Processing Large Arrays?

无响应 UI 操作的异步迭代

当迭代大型数组并执行可能妨碍用户交互的冗长操作时,采用异步迭代变得至关重要保持用户界面响应能力的策略。本指南探讨了两种实现此目的的方法,无论有没有 Web Worker。

非 WebWorker 解决方案

对于涉及 DOM 操作或其他状态相关任务的操作,使用网络工作者是不切实际的。推荐的方法是将工作分解为更小的块并使用计时器异步执行它们。这允许浏览器处理事件并更新每个块之间的 UI,从而防止用户输入和显示更新中断。

下面的代码演示了此技术:

<code class="javascript">function processLargeArray(array) {
    // Process 100 items per chunk
    var chunkSize = 100;
    var index = 0;
    function doChunk() {
        for (var i = 0; i < chunkSize && index < array.length; i++) {
            // Process array[index] here
            ++index;
        }
        if (index < array.length) {
            // Schedule next async chunk
            setTimeout(doChunk, 1);
        }
    }    
    doChunk();    
}

processLargeArray(veryLargeArray);</code>
登录后复制

您可以扩展将上面的代码转换为接受回调的通用函数,类似于 forEach() 方法:

<code class="javascript">function processLargeArrayAsync(array, fn, chunkSize, context) {
    context = context || window;
    chunkSize = chunkSize || 100;
    var index = 0;
    function doChunk() {
        for (var i = 0; i < chunkSize && index < array.length; i++) {
            // Callback called with args (value, index, array)
            fn.call(context, array[index], index, array);
            ++index;
        }
        if (index < array.length) {
            // Schedule next async chunk
            setTimeout(doChunk, 1);
        }
    }    
    doChunk();    
}

processLargeArrayAsync(veryLargeArray, myCallback, 100);</code>
登录后复制

为了更好地控制异步执行,您可以指定每个块的最大时间限制,而不是固定块size:

<code class="javascript">function processLargeArrayAsync(array, fn, maxTimePerChunk, context) {
    context = context || window;
    maxTimePerChunk = maxTimePerChunk || 200;
    var index = 0;

    function now() {
        return new Date().getTime();
    }

    function doChunk() {
        var startTime = now();
        while (index < array.length && (now() - startTime) <= maxTimePerChunk) {
            // Callback called with args (value, index, array)
            fn.call(context, array[index], index, array);
            ++index;
        }
        if (index < array.length) {
            // Schedule next async chunk
            setTimeout(doChunk, 1);
        }
    }    
    doChunk();    
}

processLargeArrayAsync(veryLargeArray, myCallback);</code>
登录后复制

WebWorker 解决方案

如果您的循环代码不与 DOM 或其他浏览器状态交互,您可以利用 Web Worker 来执行操作在一个单独的线程中。 Web Worker 独立运行并通过 postMessage 将结果传达回主线程。这种方法可确保 UI 线程在后台进行大量计算时保持响应。但是,请注意,您需要将 Web Worker 中运行的代码移至单独的脚本文件中。

以上是处理大型数组时如何确保 UI 响应灵敏?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板