JavaScript は現在、すでに最も人気のある言語です。Web サイトのインターフェイス、サーバーサイド、ゲーム、オペレーティング システム、ロボットなど、さまざまなことができます。
しかし、正直なところ、これだけ人気があるとはいえ、その性能はまだ限界に達していません。はい、改善されていますが、あらゆる面でネイティブ アプリに追いつくまでは、HYBIRD アプリを作成するときにパフォーマンスを最適化するためのいくつかのトリックを使用する必要があります。
Firefox には現在最速の JavaScript パーサー SpiderMonkey があります。
JavaScript を高速化するためにさまざまな取り組みが行われていますが、その 1 つが asm.js であり、Emscripten によって作成された JavaScript のサブセットであり、JavaScript に対して多くの最適化を行います。 C/C++ からコンパイルされたコード。コンパイルされたコードは醜いため、最適化されたコードを自分で書くことはできませんが、非常に高速に実行されます。この記事を読むことをお勧めします
話はやめて、例を示してください
さて、私たちの目標は、より高速な JavaScript コードを作成することです。コードをより高速に実行し、メモリ効率を向上させるためのヒントをいくつか紹介します。私は厳密に DOM と Web アプリケーションについて話しているのではなく、JavaScript について話していることに注意してください。DOM はその一部にすぎません。
百聞は一見に如かず、Firefox38とChrome39のテストを使用したjsperfテストケースを追加する最初のものとして追加します。
#1 Cast を入力しないでください
JavaScript は動的に型付けされますが、速度を上げたい場合はその機能を使用しないでください。変数の型の一貫性を保つようにしてください。これは配列にも当てはまりますが、ほとんどの場合ブラウザによって最適化されますが、異なるタイプの配列を混合しないようにしてください。これが、JavaScript にコンパイルされた C/C++ コードが静的型付けを使用する理由の 1 つです。
{ var x = '2'; var y = 5; x = 2; x + y; }
テストケース
その他: 文字列型と数値型の変換
例えば、文字列を数値に変換する必要があります parseInt と parseFloat は最良のメソッドですか?見てみましょう。
parseFloat("100") +"100" // 整型 parseInt("100", 10) "100"|0 "100" >> 0 "100" << 0 // 仅适用于正数 "100" >>> 0
parseInt test ~ parseFloat test
Firefox はビット単位の演算に最適化されており、parseInt や + 演算よりも約 99% 高速にコードを実行します。 Chrome では明らかにビット単位の演算子が優先されず、parseInt 関数よりも 62% 遅くなります。
parseFloat は、どちらのブラウザでも + 演算子より高速です (Firefox 28%、Chrome 39%)。
では、Node/Chrome または Firefox アプリケーションを作成している場合はどうでしょうか?私の意見では、一般的に parseInt 関数を使用するのが正しいと思います。
#2 オブジェクトを再構築しないでください
オブジェクトの再構築はコストがかからないため、避けるべきです:
delete 演算子を使用しないでください
削除操作は、null プロパティを割り当てるよりもはるかに時間がかかります。どちらのブラウザでも null の割り当ては 99% 高速ですが、オブジェクトの構造は変更できませんが、削除は変更できます。
編集: これは少し誤解を招きやすいと思います。delete 演算子を使用してはいけないという意味ではありません。delete 演算子には独自の使用例があり、オブジェクトのメモリ リークを防ぐことができます。
delete vs null
後で属性を追加しないでください
後で属性を追加しないようにしてください。最初からオブジェクトの構造を定義するのが最善です。これは、Firefox では 100%、Chrome では 89% 高速です。
動的プロパティ VS 事前定義された構造
#3 文字列の連結
文字列の連結は非常にコストのかかる操作ですが、どのような方法を使用する必要がありますか?確かに Array.prototype.join ではありません。
+= 演算子は + よりもはるかに高速なようで、String.prototype.concat と Array.prototype.join はどちらのブラウザでも高速です。 Array.prototype.join は市場の予想と一致し、最も遅いです。
文字列連結テスト
#4 正規表現の正しい使い方
RegExp.prototype.execを使う必要はありませんね。
ただし、RegExp.prototype.test と String.prototype.search にはパフォーマンスの違いがあります。どちらのメソッドが速いか見てみましょう:
正規表現メソッド
String よりも RegExp.prototype.exec の方がはるかに高速です。より高速ですが、まったく同じものではないため、その違いについてはこの記事の範囲を超えています。この Q&A を参照してください。
RegEx.prototype.test の方が速いのは、おそらく一致が見つかったインデックスを返さないためです。 String.prototype.search は、必要な一致するインデックスを見つけるためにのみ使用してください。
ただし、別の文字列の位置を見つけるために正規表現を使用する必要はありません。String.prototype.indexOf メソッドを使用できます。
String.prototype.search VS String.prototype.indexOf
另一个有趣的基准是String.prototype.indexOf VS RegExp.prototype.test,我个人预计后者要快,这是在Firefox中发生的事情,但在Chrome中,事实并非如此。 RegExp.prototype.test在Firefox中快32%,而在Chrome中String.prototype.indexOf快33%。在这种情况下,你自己选择喜欢的方式吧。
#5限制声明/传递变量的范围(作用域)
假如你调用一个函数,浏览器必须做一些所谓的范围查找,它的昂贵程度取决于它要查找多少范围。尽量不要依辣全局/高范围的变量,尽量使局部范围变量,并将它们传递给函数。更少的范围查找,更少的牺牲速度。
这个测试告诉我们,从局部范围内传递和使用变量比从更高的声明范围查找变量快,无论是Chrome和Firefox。
内部范围VS高范围VS全局
#6你不需要所有的东西都用jQuery
大多数开发者使用jQuery做一些简单的任务,我的意思在一些场合你没有必要使用jQuery,你觉得用$.val()始终是必要的吗?就拿这个例子:
$('input').keyup(function() { if($(this).val() === 'blah') { ... } });
这是学习如何使用JavaScript修改DOM的最重要原因之一,这样你可以编写更高效的代码。
用纯JavaScript100%完成同样的功能100%的速度更快,这是JSPerf基准测试
$('input').keyup(function() { if(this.value === 'blah') { ... } });