防止浏览器冻结和崩溃以进行长时间计算 [英] Prevent browser freezing and crashing for long time calculation

查看:107
本文介绍了防止浏览器冻结和崩溃以进行长时间计算的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要检入重复的数据库名称,并更改此名称以避免重复.我使用@JefréN建议的脚本.

I need check in my database names who are duplicated and change this name to avoid duplicates. I using script suggested by @Jefré N.

function eliminateDuplicates() {

    var repeats = {};
    var error = false;

    //cache inputs
    var $inputs = $("input[type='text']");

    //loop through inputs and update repeats
    for (i = 0; i < $inputs.length; ++i) {
        //cache current element
        var cur = $inputs[i];

        //remove class
        $(cur).removeClass("double-error");

        //get text of this element
        var text = $(cur).val();

        //no text -- continue
        if (text === "") {
            continue;
            }
        //first time we've came across this value -- intialize it's counter to 1
        if ((text in repeats) === false) {
            repeats[text] = 1;
            }
        //repeat offender. Increment its counter.
        else {
            repeats[text] = repeats[text] + 1;
            }

        //update the the value for this one
        $(cur).val(text + "-" + repeats[text]);
        }

    return error; // always returns false since I'm not sure
                  // when it's supposed to return true.
    }

所以脚本工作正常,但是如果我有多达一百个条目.但是,如果我有成千上万的记录,浏览器将冻结. Firefox完全崩溃了.如何通过添加一些加载线或某些时钟指针来防止浏览器冻结和崩溃?也许我需要使用一些setTimeout()函数或其他方法.请帮助防止该浏览器冻结和崩溃的问题.

So script working fine, but if I have up to hundred entries. But if I have several thousands of records, browser is freezing. Firefox crashing at all. How to prevent browser freezing and crashing by adding for example some loading line o some clock pointer? Maybe I need to use some setTimeout() function or something else. Please help to prevent this browser freezing and crashing problem.

我尝试过:

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) {
            // set Timeout for async iteration
            setTimeout(doChunk, 1);
        }
    }    
    doChunk();    
}

-

processLargeArrayAsync(veryLargeArray, myCallback);

没有成功. Chrome冻结,IE11浏览器也崩溃,Firefox崩溃.怎么了? 我的记录显示在HTML表中.

No success. Chrome freezing, IE11 explorer also, Firefox crashing. Whats wrong? My records appear in the HTML table.

有人建议使用网络工作者.也许有人在这里练习并有一个可行的例子?

Some people advise to use a web worker. Maybe someone here has the practice and have a functioning example?

推荐答案

我认为您代码中最麻烦的部分是DOM访问:获取输入值并更新它们.

I think that the most cumbersome part of your code is the DOM access: getting input values and updating them.

根据网络工作者文档,网络工作者具有它们的局限性,其中之一就是DOM操作.所以我会放弃该选项.

According to the webworkers documentation, webworkers have their limitations and one of them is DOM manipulation. So I'd discard that option.

为了解决问题,我将执行以下操作:

In order to fix things, I'd do as follows:

  1. 改进您的eliminateDuplicates算法(使其更快).
  2. 使eliminateDuplicates异步:将元素集划分为较小的元素,并在不同的事件循环滴答(setTimeout)中执行每个计算.
  1. Improve your eliminateDuplicates algorithm (make it faster).
  2. Make eliminateDuplicates asynchronous: divide the set of elements in smaller ones and perform each calculation in a different event loop tick (setTimeout).

在这里,我向您介绍我提出的解决方案.希望它能给您一些想法并帮助您解决问题.

Here I present you a solution I've come up with. Hope it gives you some ideas and help you to solve your problem.

首先,我调整了eliminateDuplicates(我称之为modifyDOM)

First, I tweaked a bit eliminateDuplicates (I called it modifyDOM)

function modifyDOM(elements, repeats) {
    var input, text, i = 0;
    for (; i < elements.length; i++) {
        input = elements[i];
        text = input.value;
        // Remove class.
        input.className = input.className.replace(/\bdouble-error\b/, '');
        if (text) {
            repeats[text] = ~~repeats[text] + 1;
            input.value = text + "-" + repeats[text];
        }
    }
}

我避免在主循环中使用jQuery,因为它的包装器使事情变慢了,在您的情况下,不值得使用它.这些微小的变化提高了每10.000个元素100ms的性能(给予或接受).

I avoided using jQuery inside the main loop because its wrapper makes things slower and in your case it wasn't worth using it. These small changes improved performance in 100ms per 10.000 elements (give it or take).

我创建了两个使用modifyDOM的函数:一个异步,另一个同步.

I created two functions that use modifyDOM: one asynchronous and other synchronous.

function parseElementsNonBlocking(elements, maxChunkSize) {
    var repeats = {},
        nChunks = Math.floor(elements/maxChunkSize),
        i = 0,
        j = 1;

    //loop through inputs and update repeats
    for(; i < nChunks; i++, j++) {
        setTimeout(modifyDOM.bind(null, elements.slice(i, j*maxChunkSize), repeats), 0);
    }
    // Rest
    setTimeout(modifyDOM.bind(null, elements.slice(i), repeats), 0);
}

function parseElementsBlocking(elements) {
    var repeats = {};

    //loop through inputs and update repeats
    modifyDOM(elements, repeats);
}

最后,为了测试所有内容,该函数在DOM准备就绪时执行并创建10.000输入.然后,它输出运行上述任何一种方法所花费的时间.

Lastly and in order to test everything, a function that executes when the DOM is ready and creates 10.000 inputs. It then outputs how long it takes to run any of the above methods.

$(function () {
    var inputsDiv = $('#inputs'), i, time;
    for (i = 0; i < 10000; i++) {
        var val = i % 3 === 0 ? 'Mickey' : (i % 3 === 1 ? 'Mouse' : '');
        inputsDiv.append('<input type="text" class="double-error" name="FirstName" value="' + val + '">');
    }

    time = Date.now();
    //parseElementsBlocking($("input[type='text']"));
    parseElementsNonBlocking($("input[type='text']"), 100);
    console.log(Date.now() - time);
});

在这里,您有小提琴来进行全部测试.

Here you have the fiddle to test it all.

这篇关于防止浏览器冻结和崩溃以进行长时间计算的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆