【问题标题】:Why is this javascript code making browser draw 50% CPU and so much memory?为什么这段 javascript 代码让浏览器占用 50% 的 CPU 和如此多的内存?
【发布时间】:2010-10-31 12:53:16
【问题描述】:

我有这个横幅旋转代码:

function ban_rot() {
    //First preload images
    // counter
    var i = 0;

    // create object
    imageObj = new Image();

    // set image list
    images = new Array();
    images[0] = "../Graphics/adv/1.gif"
    images[1] = "../Graphics/adv/2.jpg"

    // start preloading
    for (i = 0; i <= images.length; i++) {
        imageObj.src = images[i];
    }
    ///////////////////////
    var links = new Array("http://www.link1.com", "http://www.link2.se");
    var alts = new Array("alt1", "alt2");
    var titles = new Array("title1", "title2");

    var counter = 0;
    var banner_div = document.getElementById("ban_rot");
    cycle();

    function cycle() {
        if (counter == links.length) {
            counter = 0;
        }
        else if (counter < links.length) {
            banner_div.innerHTML = '<a href=\"' + links[counter] + '\"><img src=\"' + images[counter] + '\" border=\"1px\" style=\"border-color:#000;\" alt=\"' + alts[counter] + '\" title=\"' + titles[counter] + '\"></a>';
            //increase counter
            counter++;
        }
        setInterval(cycle, 8000);
    } //end cycle function
} //end ban_rot function

使用此代码,在 Firefox 或 Chrome 中大约 2-3 分钟后,内存上升,cpu 达到 50% 左右。 计算机变得迟钝,我必须终止 Chrome 和 FF。

上面这段代码有什么原因吗?

谢谢

【问题讨论】:

  • 如果情况需要,函数内部的函数就可以了。在这里,计数器和链接数组是私有的,因此ban_rot 之外的函数将无法访问它们。在不创建闭包的情况下解决此问题的唯一方法是污染名称空间并希望没有人在页面中拥有多个横幅旋转器(或任何其他可能使用相同变量的代码)。话虽如此,但我对带有名称的闭包有点不舒服。
  • 你们疯了。函数内部的函数绝对没有问题,并且“带名称的闭包”是完全安全的,因为它是作为函数声明语句完成的,而不是作为“命名匿名函数”(由于实现不佳而存在问题)。
  • 是的,functions in functions是javascript最棒的特性。
  • 哦还有@Camran:在声明数组时,你应该养成写var a = [value, value, value];而不是使用new Array(...);的习惯

标签: javascript jquery html security memory


【解决方案1】:

在此处使用setTimeout() 而不是setInterval(),如下所示:

setTimeout(cycle, 8000);

使用setInterval(),您每次排队的函数堆栈越来越多,而不是在 8 秒后调用一次,我们排队另一个间隔计时器以每 8 秒运行一次,所以您会得到:

  •   8 秒:1 次运行
  • 16 秒:2 次运行
  • 24 秒:4 次运行
  • 32 秒:8 次运行
  • ...呃哦

使用setTimeout(),当计时器到时,您将只运行一次,而不是每 8 秒运行一次额外

需要明确的是,发生这种情况因为您每次运行时都会调用它,正常的一次性使用不会成为问题,setInterval() 本质上没有什么坏处。

【讨论】:

  • 乍一看,这听起来有点像setInterval() 普遍存在的问题,但实际上 OP 只是做错了。
  • @Tomalak - 你是对的,它确实是这样读的,让我澄清一下它是特定于用法的。
猜你喜欢
  • 1970-01-01
  • 2019-05-10
  • 1970-01-01
  • 1970-01-01
  • 2022-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多