javascript优化_极端JavaScript优化

news/2024/7/19 14:42:55 标签: python, java, 编程语言, 算法, js
<a class=javascript优化" width="403px" height="256px" style="outline: none;" />

javascript优化

2010 update: Lo, the Web Performance Advent Calendar hath moved

2010年更新: Lo, Web Performance Advent Calendar已移动

Dec 20 This article is part of the 2009 performance advent calendar experiment. Today's article is a second contribution from Ara Pehlivanian (here's the first).

12月20日本文是2009年效果降临日历实验的一部分。 今天的文章是Ara Pehlivanian的第二篇文章(这是第一篇文章)。

There's a Belorussian translation provided by Patricia. Thanks!

帕特里夏(Patricia)提供了白俄罗斯语翻译。 谢谢!

Ara PehlivanianAra Pehlivanian has been working on the Web since 1997. He's been a freelancer, a webmaster, and most recently, a Front End Engineer at Yahoo! Ara's experience comes from having worked on every aspect of web development throughout his career, but he's now following his passion for web standards-based front-end development. When he isn't speaking and writing about best practices or coding professionally, he's either tweeting as
@ara_p or maintaining his personal site at http://arapehlivanian.com/.
@ara_p发推 文或维护其个人网站 http://arapehlivanian.com/ 。

There's an odd phenomenon underway in the JavaScript world today. Though the language has remained relatively unchanged for the past decade, there's an evolution afoot among its programmers. They're using the same language that brought us scrolling status bar text to write some pretty heavy duty client-side applications. Though this may seem like we're entering a Lada in an F1 race, in reality we've spent the last ten years driving an F1 race car back and forth in the driveway. We were never using the language at its full potential. It took the discovery of Ajax to launch us out of the driveway and onto the race track. But now that we're on the track, there's a lot of redlining and grinding of gears going on. Not very many people it seems, know how to drive an F1 race car. At least not at 250 mph.

当今JavaScript世界正在发生一种奇怪的现象。 尽管该语言在过去十年中一直保持相对不变,但其程序员之间仍在不断发展。 他们使用的语言使我们能够滚动状态栏文本来编写一些功能强大的客户端应用程序。 尽管这看起来像是我们正在参加F1比赛的拉达赛车,但实际上,我们在过去十年中一直在车道上来回驾驶F1赛车。 我们从未充分利用这种语言的潜力。 发现Ajax使我们离开了车道,进入了赛道。 但是现在我们已经步入正轨,正在进行很多齿轮的重新涂胶和磨削。 似乎没有多少人知道如何驾驶F1赛车。 至少不是以250 mph的速度行驶。

The thing of it is, it's pretty easy to put your foot to the floor and get up to 60 mph. But very soon you'll have to shift gears if you want to avoid grinding to a halt. It's the same thing with writing large client-side applications in JavaScript. Fast processors give us the impression that we can do anything and get away with it. And for small programs it's true. But writing lots of bad JavaScript can very quickly get into situations where your code begins to crawl. So just like an average driver needs training to drive a race car, we need to master the ins and outs of this language if we're to keep it running smoothly in large scale applications.

事实是,将脚踩到底并以每小时60英里的速度行驶很容易。 但是很快,如果您要避免打磨停顿,就必须换档。 用JavaScript编写大型客户端应用程序是同一回事。 快速处理器给我们的印象是,我们可以做任何事情并摆脱它。 对于小型程序,这是事实。 但是,编写大量不良JavaScript可能会很快陷入代码开始爬行的情况。 因此,就像普通驾驶员需要接受培训才能驾驶赛车一样,如果要使它在大规模应用中保持平稳运行,就需要掌握这种语言的来龙去脉。

变数 (Variables)

Let's take a look at one of the staples of programming, the variable.Some languages require you to declare your variables before using them, JavaScript doesn't. But just because it isn't required doesn't mean you shouldn't do it. That's because in JavaScript if a variable isn't explicitly declared using the 'var' keyword, it's considered to be a global, and globals are slow. Why? Because the interpreter needs to figure out if and where the variable in question was originally declared, so it goes searching for it. Take the following example.

让我们看一下编程的主要内容之一,变量。某些语言要求您在使用变量之前先声明变量,而JavaScript不需要。 但是仅仅因为它不是必需的并不意味着您不应该这样做。 这是因为在JavaScript中,如果未使用'var'关键字明确声明变量,则该变量被视为全局变量,并且全局变量很慢。 为什么? 由于解释器需要弄清楚是否在最初声明了该变量以及在何处声明了该变量,因此它将继续进行搜索。 请看下面的例子。

function doSomething(val) {
    count += val;
};

Does count have a value assigned to it outside the scope of doSomething? Or is it just not being declared correctly? Also, in a large program, having such generic global variable names makes it difficult to keep collisions from happening.

计数是否在doSomething范围之外分配了值? 还是只是未正确声明? 同样,在大型程序中,具有这样的通用全局变量名称使得很难防止发生冲突。

循环 (Loops)

Searching the scope chain for where count is declared in the example above isn't such a big deal if it happens once. But in large-scale web applications, not very much just happens once. Especially when loops are concerned. The first thing to remember about loops, and this isn't just for JavaScript, is to do as much work outside the loop as possible. The less you do in the loop, the faster your loop will be. That being said, let's take a look at the most common practice in JavaScript loops that can be avoided. Take a look at the following example and see if you can spot it:

搜索作用域链以查找上面的示例中声明了count的地方,如果发生一次就没什么大不了的。 但是在大型Web应用程序中,一次不会发生很多事情。 特别是在涉及循环时。 关于循环的第一件事要记住,这不仅是针对JavaScript,还包括在循环外进行尽可能多的工作。 您在循环中执行的次数越少,循环将越快。 话虽如此,让我们看一下可以避免JavaScript循环中最常见的做法。 看下面的示例,看看是否可以发现它:

for (var i = 0; i < arr.length; i++) {
    // some code here
}

Did you see it? The length of the array arr is recalculated every time the loop iterates. A simple fix for this is to cache the length of the array like so:

你看见了吗? 每次循环时都会重新计算数组arr的长度。 一个简单的解决方法是像这样缓存数组的长度:

for (var i = 0, len = arr.length; i < len; i++) {
    // some code here
}

This way, the length of the array is calculated just once and the loop refers to the cached value every time it iterates.

这样,数组的长度仅计算一次,并且循环在每次迭代时都引用缓存的值。

So what else can we do to improve our loop's performance? Well, what other work is being done on every iteration? Well, we're evaluating whether the value of i is less than the value of len and we're also increasing i by one. Can we reduce the number of operations here? We can if the order in which our loop is executed doesn't matter.

那么,我们还能做些什么来提高循环的性能呢? 好吧,每次迭代还要完成哪些其他工作? 好吧,我们正在评估i的值是否小于len的值,并且还将i增加一。 我们可以减少这里的手术数量吗? 我们可以执行循环的顺序无关紧要。

for (var i = 100; i--; ) {
    // some code here
}

This loop will execute 50% faster than the one above because on every iteration it simply subtracts a value from i, and since that value is not "falsy," in other words it isn't 0, then the loop goes on. The moment the value hits 0, the loop stops.

该循环的执行速度比上述循环快50%,因为在每次迭代中,它仅从i中减去一个值,并且由于该值不是“虚假的”,换句话说,它不是0,因此循环继续进行。 值达到0的那一刻,循环停止。

You can do this with other kinds of loops as well:

您也可以使用其他类型的循环来执行此操作:

while (i--) {
    // some code here
}

Again, because the evaluation and the operation of subtracting 1 from i is being done at the same time, all the while loop needs is for i to be falsy, or 0, and the loop will exit.

再一次,因为同时进行评估和从i减去1的运算,所有while循环所需的条件是i等于或为0,并且循环将退出。

快取 (Caching)

I touched briefly on caching above when we cached the array length in a variable. The same principle can be applied in many different places in JavaScript code. Essentially, what we want to avoid doing is sending the interpreter out to do unnecessary work once it's already done it once. So for example, when it comes to crawling the scope chain to find a global variable for us, caching it the reference locally will save the interpreter from fetching it every time. Here, let me illustrate:

当我们将数组长度缓存在变量中时,我简要地谈到了上面的缓存。 可以在JavaScript代码的许多不同位置应用相同的原理。 从本质上讲,我们要避免的工作是,一旦解释器发送完毕,就将其发送出去进行不必要的工作。 因此,例如,当涉及到范围链的查找以为我们找到一个全局变量时,将其缓存在本地将避免每次保存解释器。 在这里,让我说明一下:

var aGlobalVar = 1;
 
function doSomething(val) {
    var i = 1000, agv = aGlobalVar;
    while (i--) {
        agv += val;
    };
    aGlobalVar = agv;
};
 
doSomething(10);

In this example, aGlobalVar is only fetched twice, not over a thousand times. We fetch it once to get its value, then we go to it again to set its new value. If we had used it inside the while loop, the interpreter would have gone out to fetch that variable a thousand times. In fact, the loop above takes about 3ms to run whereas if avg += val; were replaced with aGlobalVar += val; then the loop would take about 10ms to run.

在此示例中,仅提取了GlobalVar两次,而不超过一千次。 我们先获取它以获取其值,然后再次进入它以设置其新值。 如果我们在while循环中使用过它,那么解释器将花费1000次来获取该变量。 实际上,上面的循环大约需要3毫秒才能运行,而avg += val; 被替换为aGlobalVar += val; 那么该循环大约需要10毫秒才能运行。

物业深度 (Property Depth)

Nesting objects in order to use dot notation is a great way to namespace and organize your code. Unforutnately, when it comes to performance, this can be a bit of a problem. Every time a value is accessed in this sort of scenario, the interpreter has to traverse the objects you've nested in order to get to that value. The deeper the value, the more traversal, the longer the wait. So even though namespacing is a great organizational tool, keeping things as shallow as possible is your best bet at faster performance. The latest incarnation of the YUI Library evolved to eliminate a whole layer of nesting from its namespacing. So for example, YAHOO.util.Anim is now Y.Anim.

嵌套对象以使用点表示法是命名空间和组织代码的好方法。 不幸的是,在性能方面,这可能会有点问题。 在这种情况下,每次访问值时,解释器都必须遍历您嵌套的对象才能获得该值。 值越深,遍历越多,等待时间越长。 因此,尽管命名间隔是一种出色的组织工具,但尽可能使内容变浅是提高性能的最佳选择。 YUI库的最新化身经过发展,从其命名空间中消除了整个嵌套层。 因此,例如, YAHOO.util.Anim现在是Y.Anim

概要 (Summary)

These are just a few examples of how to improve your code's performance by paying attention to how the JavaScript interpreter does its work. Keep in mind though that browsers are continually evolving, even if the language isn't. So for example, today's browsers are introducing JIT compilers to speed up performance. But that doesn't mean we should be any less vigilant in our practices. Because in the end, when your web app is a huge success and the world is watching, every millisecond counts.

这些只是通过关注JavaScript解释器如何工作来提高代码性能的几个示例。 请记住,尽管浏览器在不断发展,即使它不是该语言。 因此,例如,当今的浏览器正在引入JIT编译器以提高性能。 但这并不意味着我们应该对自己的做法保持警惕。 因为最终,当您的Web应用程序获得巨大成功并且全世界都在注视时,每一毫秒都是至关重要的。

Tell your friends about this post on Facebook and Twitter

在Facebook和Twitter上告诉您的朋友有关此帖子的信息

翻译自: https://www.phpied.com/extreme-javascript-optimization/

javascript优化


http://www.niftyadmin.cn/n/1306189.html

相关文章

zTree实现多选树

zTree实现多选树 1、实现源码 <!DOCTYPE html> <html> <head><title>多选树</title><meta http-equiv"content-type" content"text/html; charsetUTF-8"><link rel"stylesheet" type"text/css"…

httpwatch使用_使用PHP#2自动化HTTPWatch

httpwatch使用In part 1 I demonstrated how you can use PHP to script and automate HTTPWatch. And how you can get data back, either reading the API docs or using a quick HAR hack to get a lot of data in one go. 在第1部分中&#xff0c;我演示了如何使用PHP编写脚…

zTree实现基本树

zTree实现基本树 1、实现源码 <!DOCTYPE html> <html> <head><title>zTree实现基本树</title><meta http-equiv"content-type" content"text/html; charsetUTF-8"><link rel"stylesheet" type"text…

zTree实现删除树节点

zTree实现删除树节点 1、实现源码 <!DOCTYPE html> <html> <head><title>zTree实现基本树</title><meta http-equiv"content-type" content"text/html; charsetUTF-8"><link rel"stylesheet" type"…

绩效工作机会

Im sure quite a few of you my fellow readers are crazy about web performance. And if youre seeking new challenges, timing cant be any better. Below are three excellent opportunities in three of the most high-traffic sites on the planet. 我敢肯定&#xff0c…

zTree实现删除树子节点

zTree实现删除树子节点 1、实现源码 <!DOCTYPE html> <html> <head><title>zTree实现基本树</title><meta http-equiv"content-type" content"text/html; charsetUTF-8"><link rel"stylesheet" type&quo…

javascript加载_JavaScript加载策略

javascript加载2010 update: Lo, the Web Performance Advent Calendar hath moved 2010年更新&#xff1a; Lo&#xff0c; Web Performance Advent Calendar已移动 Dec 15 This article is part of the 2009 performance advent calendar experiment. Todays article is a co…

zTree实现获取一级节点数据

zTree实现获取一级节点数据 1、实现源码 <!DOCTYPE html> <html> <head><title>zTree实现基本树</title><meta http-equiv"content-type" content"text/html; charsetUTF-8"><link rel"stylesheet" type…