2

因此,我对 JavaScript 编码相当陌生,尽管对一般编码而言并不陌生。在编写源代码时,我通常会考虑我的代码将在其中运行的环境(例如某种虚拟机) - 以及可以预期的代码优化级别。(1)

例如,在 Java 中,我可能会写这样的东西,

Foo foo = FooFactory.getFoo(Bar.someStaticStuff("qux","gak",42);
blub.doSomethingImportantWithAFooObject(foo);

即使该foo对象仅在该位置使用(因此引入了不必要的变量声明)。首先,我认为上面的代码比内联版本更易读

blub.doSomethingImportantWithAFooObject(FooFactory.getFoo(Bar.someStaticStuff("qux","gak",42));

其次,我知道 Java 编译器代码优化无论如何都会处理这个问题,即实际的 Java VM 代码最终会被内联 - 所以在性能方面,两者之间没有区别。(2)

现在到我的实际问题
我通常可以在 JavaScript 中期望什么级别的代码优化?

我认为这取决于 JavaScript 引擎——但由于我的代码最终会在许多不同的浏览器中运行,所以我们只做最坏的假设,看看最坏的情况。我可以期待适度的代码优化吗?我还需要担心哪些情况?


(1) 我确实意识到找到好的/最好的算法和编写组织良好的代码比一些代码优化更重要,并且对性能的影响更大。但这将是一个不同的问题。

(2) 现在,我意识到没有优化的实际差异很小。但那是无关紧要的。有一些很容易优化的功能非常有效,我只是懒得写一个。想象一下上面的代码片段在一个for被称为 100'000 次的循环中。

4

3 回答 3

4

不要对优化抱太大希望,不会有

  • 尾递归优化,
  • 循环展开,
  • 内联函数
  • ETC

由于客户端上的 javascript 不是为执行繁重的 CPU 工作而设计的,因此优化不会产生巨大的影响。

编写高性能 javascript 代码有一些指导方针,大多数是次要的和技术性的,例如:

  • 不使用eval(),arguments.callee等某些函数,这将阻止 js 引擎生成高性能代码。
  • 使用原生特性而不是手写特性,比如不要编写自己的容器、json 解析器等。
  • 使用局部变量而不是全局变量。
  • 永远不要对数组使用 for-each 循环。
  • 使用parseInt()而不是Math.floor.
  • 并远离 jQuery。

所有这些技术更像是经验的东西,背后可能有一些合理的解释。因此,您将不得不花一些时间搜索或尝试使用 jsPerf来帮助您确定哪种方法更好。

当你发布代码时,使用闭包编译器来处理死分支和不必要的变量,这不会大大提高你的性能,但会让你的代码更小。

一般来说,最终的性能很大程度上取决于你的代码组织得有多好,你的算法设计得有多仔细,而不是优化器的表现如何。


以上面的示例为例(假设FooFactory.getFoo()andBar.someStaticStuff("qux","gak",42)总是返回相同的结果,并且Bar,FooFactory是无状态的,someStaticStuff()并且getFoo()不会改变任何东西。)

for (int i = 0; i < 10000000; i++)
  blub.doSomethingImportantWithAFooObject(
      FooFactory.getFoo(Bar.someStaticStuff("qux","gak",42));

即使带有 -O3 标志的 g++ 也无法使该代码更快,因为编译器无法判断是否是BarFooFactory状态的。因此,任何语言都应避免使用此类代码。

于 2012-11-14T14:38:37.423 回答
1

你是对的,不同的 JS VM 的优化水平是不同的。但!有一种解决方法。有几种工具可以为您优化/最小化您的代码。最受欢迎的之一是谷歌。它被称为闭包编译器。你可以试试网络版本,还有一个用于构建脚本等的命令行版本。除此之外,我不会尝试优化,因为毕竟 Javascript 有点快。

于 2012-11-14T14:15:05.747 回答
1

一般来说,我认为除非你的代码真的很脏(让你的所有变量都在全局范围内,创建大量 DOM 对象,对非最佳数据源进行昂贵的 AJAX 调用等),否则真正的窍门优化性能将用于管理您在运行时加载的所有其他内容。

在几十张图片上加载几十张图片,或者为巨大的背景图片制作动画,以及拉入大量脚本和 css 文件,这些对性能的影响都比编写良好的中等复杂的 Javascript 所产生的影响要大得多。

也就是说,快速的 Google 搜索会找到几个关于 Javascript 性能优化的来源:http: //www.developer.nokia.com/Community/Wiki/JavaScript_Performance_Best_Practices

http://www.nczonline.net/blog/2009/02/03/speed-up-your-javascript-part-4/

http://mir.aculo.us/2010/08/17/when-does-javascript-trigger-reflows-and-rendering/

正如其中两个链接所指出的那样,浏览器中最昂贵的操作是重排(由于 DOM 操作,浏览器必须重绘界面),因此在性能方面您需要最谨慎. 其中一些可以通过对您正在修改的内容进行智能来缓解(例如,应用类比临时修改内联样式更便宜),因此将您的关注点(样式与数据)分开将非常重要.

只做你必须做的修改,以完成工作,(即,而不是做“HULK SMASH (DOM)!”用 AJAX 调用替换整个页面块的方法,而不是调用屏幕抓取远程源让 JSON 数据只更新所需的最少元素)和其他常识性方法将使您比对 for 循环进行数小时的细微调整要远得多(尽管,常识会让您走得更远,那里,也)。

祝你好运!

于 2012-11-14T14:36:25.477 回答