javascript - 我是否向带有 javascript 循环的页面写入了太多数据?

标签 javascript performance loops

我正在尝试构建一个子网计算器作为我自己的个人项目来学习编程。我遇到问题的部分是我想提供有类子网范围,例如 172.16.1.1/30 将提供 16384 个子网...
172.16.0.0 - 172.16.0.3
172.16.0.4 - 172.16.0.7
172.16.0.8 - 172.16.0.11
……等

所以当我把它写到一个网站上时,它会锁定浏览器几秒钟,并且花费的时间比我想象的要长。我尽可能多地进行了研究,发现输入“setTimeout”将有助于锁定和处理 ClassB 子网(使用/32 时最大为 65536)。但是,当我进入数十万和数百万时,我仍然有问题。我创建了一个测试脚本来玩数字,看看有什么用。对此我很陌生,我没有主意。这是我的测试代码...

HTML:

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>My Page</title>

</head>
<body>
    <div id="subnetRange" style="border : solid 2px #ff0000; background : #000000; color : #ffffff; padding : 4px; width : 250px; height : 350px; overflow : auto; "></div>

    <script type="text/javascript" src="pump.js"></script>
</body>
</html>

JavaScript:

var i = 0;
var myArray = new Array();
document.getElementById('subnetRange').innerHTML = "Loading...";   //carry on pumping?

function doCalculation()
{

   //Surrounding loop to break the time out up by 1000 increments
   for ( var x = 0; x < 2000; x++) {
     myArray[i] = i;
     i = i + 1;
     var percent_complete=i;
   }

   return percent_complete;
}

function pump()
{
   var percent_complete=doCalculation();
   if (percent_complete<100000)
   {
      //pump();
      setTimeout(pump, 1);
   }
   if (percent_complete >= 100000) {
      document.getElementById('subnetRange').innerHTML = myArray.join("<br />");   //carry on pumping?
   }
}


//setTimeout(pump, 1);
pump();

我希望我提供了足够的信息来提供帮助。如果没有,请询​​问,我会尽我所能为您提供信息。

谢谢

最佳答案

您将 doCalculation 的计算分成 2000 个 block ,但是一旦数组的长度为 100000,您就可以执行

document.getElementById('subnetRange').innerHTML = myArray.join("<br />");

这是错误的方式。不填充数组是繁重的工作(在亚毫秒内发生),但 DOM 操作。你需要把它拆开,例如这样:

function pump() {
    var oldItemCount = myArray.length;
    var percent_complete = doCalculation();
    var newItems = myArray.slice(oldItemCount);
    document.getElementById('subnetRange').innerHTML += newItems.join("<br />");
    //                                               ^^^^^^^^^^^
    if (percent_complete < 100000) {
        setTimeout(pump, 1);
    }
}

( updated Demo )

注意上面的代码只是为了理解问题,可以做进一步的改进:newItems可以是doCalculation的返回值,这样就不需要切片了。而 innerHTML += 实际上可能会减慢无法对此进行优化的旧浏览器的速度(它们序列化 DOM,进行字符串连接,并再次解析巨大的 HTML 字符串)。您可能需要找到一种更好的方法来附加小块 DOM 元素。

关于javascript - 我是否向带有 javascript 循环的页面写入了太多数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17355965/

相关文章:

javascript - 命名空间的差异

javascript - 加载动态日历以在该月的正确日期开始

android - Firebase 实时数据库首次连接花费的时间太长

javascript - 我可以继承 DOM 类吗?

javascript - 如何检查 Javascript 对象数组是否始终具有相同的值

javascript - Selenium IDE - 无法复制电子邮件

javascript - 是否建议缓存仅在 Javascript 中使用两次的对象?

python - 在 HTML 中循环字典

python - 从 Pandas 单元格中提取列表并使用列表元素作为新列

javascript - 为什么成员(member) map 不能用来存储工具栏?