严重影响性能的常见Javascript错误?[关闭]


10

在我参加的最近一次UI / UX MeetUp上,我在一个使用Javascript(jQuery)进行交互和UI的网站上提供了一些反馈-这是相当简单的动画和操作,但是在一台像样的计算机上的性能令人震惊。

它实际上使我想起了我遇到过的很多站点/程序,其中的某些操作绝对会破坏性能。它通常在Java几乎可以替代Flash的情况下(至少在这种情况下更为明显)。这与我使用的具有更多Javascript和功能但运行非常平稳的某些Web应用程序形成了鲜明的对比(IBM的COGNOS是我想不到的一个)。

我很想知道开发JS会导致网站性能下降的一些常见问题。


可能与其他所有程序相同:进行不必要的工作,并一次又一次地执行相同的工作,通常数百次。

1
@delnan是非常正确的,但似乎在JS中更普遍了。知觉也许?
Nic

1
在谈论JavaScript时,谈论“站点”已经有点过时了。它无处不在,如今已用于一切。
亚当·克罗斯兰

@Adam Crossland,您是绝对正确的-在同一情况下,我想我也通过一个非常依赖jQuery的本地应用程序帮助开发人员。
Nic

1
并非完全是您问题的答案,因此我在此发表评论:我经历了JavaScript大量渲染的情况,而实际上是浏览器的渲染引擎耗费了数秒钟的时间。因此,要解决性能瓶颈,我会首先寻找不必要的渲染操作。
user281377 2011年

Answers:


8

一个常见的性能杀手是.lengthfor循环内调用HTMLCollection :

function foo(collection) {
    for (var index = 0; index < collection.length; index++) {
        // do something awesome here
    }
}

该反模式使每次通过循环时都要计算集合的大小。更好的方法是计算循环外的长度:

function foo(collection) {
    var collectionLen = collection.length;
    for (var index = 0; index < collectionLen; index++) {
        // do something awesome here
    }
}

3
取决于浏览器。以这个基准为例:在FF 5中,“正常”版本与“优化”版本的运行时间几乎相同。即使在真正老旧的浏览器中,如果JS实际上对元素进行任何感兴趣的操作,类似的事情也不会成为瓶颈。

1
嗯!也许当今高度优化的JIT编译器使这一点过时了。
亚当·克罗斯兰

4
我不是一个真正的专家,但是从ECMA规范来看,长度似乎只是数组对象的一个​​属性。因此,调用它只是返回值,而不是计算所有元素。不知道所有实现是否都遵循规范,但是如果这样做,您的代码根本不会提高性能。
Jacek Prucia

4
@JacekPrucia他说集合,而不是数组 -通常,在实际代码中,这将意味着由诸如之类的函数返回的DOM元素列表document.getElementsByTagName。该函数返回一个实时字段,该实时nodeList字段在每次.length访问该属性时都会重新计算其长度。
Yi Jiang

2
@JacekPrucia 基准测试,这是一项性能改进。属性查找并不便宜。
雷诺斯2011年

4

不,问题不是来自用作闪存替换的JS。如果您对此不满意,请记录有关actionscript的yourelf:它与JS非常接近。

作为性能杀手,您可以发现一些不良做法:

  • 在连续事件上附加事件处理程序,例如滚动,移动鼠标或类似的东西。这有2个缺点:如果未充分触发事件,则您的应用程序将无法响应。如果触发太多,那么您将拥有巨大的CPU负载而一无所获。
  • 进行同步AJAX调用。Javascript不是多线程的,因此,当JS的一部分正在等待某些东西时,您的应用程序将被冻结。您最好使用异步AJAX调用,并且以相同的方式使用setTimeout / setInterval拆分较长的计算阶段,并使应用程序保持响应状态。
  • 像其他任何语言一样,算法复杂度很高。

我已经看到不止几个应用尝试旋转,缓解或赋予全浏览器图像动画效果,并在此过程中惨败-这就是Flash替换注释的出处:)
Nic

由于AJAX中的第一个A代表异步,因此从技术上讲它不是AJAX,如果它是同步的,那么您的观点仍然是一个不错的主意。
Karl Bielefeldt

是的,不是严格意义上的AJAX。但是无论如何,这必须避免:D
deadalnix

3

我在一个使用Javascript(jQuery)进行交互和UI的网站上提供了一些反馈-这是相当简单的动画和操作,但是在一台像样的计算机上的性能令人震惊。

性能的最大问题是使用高级抽象(如jQuery),而又不了解底层的DOM模型和CSS3动画模型(或canvas或svg)。

如果您不知道如何在没有抽象的情况下做到这一点,那么您对哪些技术是快速的还是缓慢的绝对了解为零

学习JavaScript,学习DOM。一旦了解了这两个,并且知道了您的抽象功能,您就可以有效地使用它们。当然,大多数时候,您会意识到抽象是要放慢速度,而无需库就可以手动进行。


1

Javascript的优点和缺点是它非常灵活。话虽如此,它实际上允许您执行很多情况下可能不应该执行的操作。

从我参与过的代码审查中,主要关注点通常与CSS渲染有关。对于较新的JS开发人员,我们倾向于看到在全局范围内使用了太多的变量。

同样,不正确的关闭通常会导致内存泄漏。但是,只要您的代码遵循该框架,大多数现代Javascript框架都可以防止此类问题。


0

这是我大约一年前找到的有关编写更好的jquery代码的快速链接:http : //net.tutsplus.com/tutorials/javascript-ajax/10-ways-to-instantly-increase-your-jquery-performance /

我刚刚在同事代码中发现的一件事是降低性能,那就是缓存不需要缓存的数据。

例:

var table = $("#data").dataTable(.....);

DataTables是一个jQuery插件,用于制作漂亮的网格。无论如何,该表中有近5k行,应用了DataTables插件,然后将其保存在table变量中,实际上使FireFox和IE都警告脚本花费了太长时间。故事的寓意,仅在需要时才缓存数据。


1
听起来DataTables确实是一个效率低下/性能不佳的插件,而不是缓存问题。5k没什么。
雷诺斯

@Raynos:他说的是5k ,而不是5 KB的数据。“行” 可能是非常大的事情。
克里斯·法默

@ChrisFarmer如果“行”很大,那么您会遇到其他问题。
雷诺斯

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.