[JavaScript] パフォーマンス改善（その1）

JavaScriptのパフォーマンス改善は効果があるのか、ブラウザ毎に計測してみました。（2018年12月現在）

```Markdown:動作環境
OS: Windows 10 Pro
Google Chrome: 70.0.3538.110
Mozilla Firefox: 63.0.3
Microsoft Edge: 42.17134.1.0
Microsoft Internet Explorer: 11.407.17134.0
```

```Markdown:JavaScriptライブラリ
jQuery: 3.1.1
```

# jQueryのappend

アンチパターンは、繰り返し処理の中で、`append`を毎回呼び出します。

```JavaScript:index.js
for (var i = 0; i < roopNum; i++) {
    tempSelector.append('<li>' + i + '</li>');
}
```

改善パターンは、繰り返し処理の外で`append`を1回だけ呼び出します。

```JavaScript:index.js
for (var i = 0; i < roopNum; i++) {
    html.push('<li>' + i + '</li>');
}
tempSelector.append(html.join());
```

[デモはこちら](https://yunbow.github.io/sample-javascript-performance/avaivale/jquery_append/)
[ソースファイルはこちら](https://github.com/yunbow/sample-javascript-performance/tree/master/avaivale/jquery_append/)

計測結果は下記の通りです。
`append`を1回だけ呼び出した場合と毎回呼び出した場合では
結果が大きくことなりました。
`append`の呼び出し回数は少なくした方がよさそうです。

|ブラウザ名|10回|100回|1000回|
|:--|:--|:--|:--|
|Google Chrome（Anti）|0|7|78|
|Google Chrome|1|4|28|
|Mozilla Firefox（Anti）|0|11|165|
|Mozilla Firefox|1|1|30|
|Microsoft Edge（Anti）|4|70|238|
|Microsoft Edge|2|15|56|
|Microsoft Internet Explorer（Anti）|5|41|344|
|Microsoft Internet Explorer|4|18|186|

# jQueryのIDセレクター

アンチパターンはjQueryのセレクターでクラス名を指定します。

```JavaScript:index.js
for (var i = 0; i < roopNum; i++) {
    $('.tempClassName').append('<li>' + i + '</li>');
}
```

改善パターンは、jQueryのセレクターでIDを指定します。

```JavaScript:index.js
for (var i = 0; i < roopNum; i++) {
    $('#tempListsId').append('<li>' + i + '</li>');
}
```

[デモはこちら](https://yunbow.github.io/sample-javascript-performance/avaivale/jquery_selector_id/)
[ソースファイルはこちら](https://github.com/yunbow/sample-javascript-performance/tree/master/avaivale/jquery_selector_id/)

計測結果は下記の通りです。
jQueryのセレクターをIDで参照する方が速いです。

|ブラウザ名|10回|100回|1000回|
|:--|:--|:--|:--|
|Google Chrome（Anti）|1|10|94|
|Google Chrome|1|6|63|
|Mozilla Firefox（Anti）|4|7|94|
|Mozilla Firefox|3|15|27|
|Microsoft Edge（Anti）|5|39|200|
|Microsoft Edge|9|22|152|
|Microsoft Internet Explorer（Anti）|5|54|373|
|Microsoft Internet Explorer|3|38|333|

# jQueryのfind

アンチパターンはjQueryの`find`を使用せずにクラス名のセレクターを指定します。

```JavaScript:index.js
for (var i = 0; i < roopNum; i++) {
    $('.tempClassName').append('<li>' + i + '</li>');
}
```

改善パターンは、jQueryの`find`を使用してクラス名のセレクターを指定します。

```JavaScript:index.js
for (var i = 0; i < roopNum; i++) {
    $('#tempContentsId').find('.tempClassName').append('<li>' + i + '</li>');
}
```

[デモはこちら](https://yunbow.github.io/sample-javascript-performance/avaivale/jquery_find/)
[ソースファイルはこちら](https://github.com/yunbow/sample-javascript-performance/tree/master/avaivale/jquery_find/)

計測結果は下記の通りです。
jQueryのセレクターでIDと同様に
IDのセレクターからfindを使用して参照する方が速いです。

|ブラウザ名|10回|100回|1000回|
|:--|:--|:--|:--|
|Google Chrome（Anti）|1|7|96|
|Google Chrome|1|7|82|
|Mozilla Firefox（Anti）|3|17|81|
|Mozilla Firefox|2|26|35|
|Microsoft Edge（Anti）|6|54|201|
|Microsoft Edge|10|32|188|
|Microsoft Internet Explorer（Anti）|15|53|379|
|Microsoft Internet Explorer|7|34|495|

# jQueryのメソッドチェーン

アンチパターンは、メソッドチェーン使わずに`append`を呼び出します。

```JavaScript:index.js
for (var i = 0; i < roopNum; i++) {
    tempSelector.append('<li>' + i + '</li>');
    // ～ 省略 ～
    tempSelector.append('<li>' + i + '</li>');
}
```

改善パターンは、メソッドチェーン使って`append`を呼び出します。

```JavaScript:index.js
for (var i = 0; i < roopNum; i++) {
    tempSelector.append('<li>' + i + '</li>').append('<li>' + i + '</li>').append('<li>' + i + '</li>').append('<li>' + i + '</li>').append('<li>' + i + '</li>').append('<li>' + i + '</li>').append('<li>' + i + '</li>').append('<li>' + i + '</li>').append('<li>' + i + '</li>').append('<li>' + i + '</li>');
}
```

[デモはこちら](https://yunbow.github.io/sample-javascript-performance/avaivale/jquery_method_chain/)
[ソースファイルはこちら](https://github.com/yunbow/sample-javascript-performance/tree/master/avaivale/jquery_method_chain/)

計測結果は下記の通りです。
それほど大きな差はありません。

|ブラウザ名|10回|100回|1000回|
|:--|:--|:--|:--|
|Google Chrome（Anti）|7|69|448|
|Google Chrome|5|49|503|
|Mozilla Firefox（Anti）|11|120|654|
|Mozilla Firefox|26|74|394|
|Microsoft Edge（Anti）|29|159|1792|
|Microsoft Edge|20|154|1810|
|Microsoft Internet Explorer（Anti）|51|410|4041|
|Microsoft Internet Explorer|56|501|3775|

# jQueryのセレクターキャッシュ

アンチパターンは、jQueryのセレクターを変数にキャッシュせずに、毎回セレクターを生成します。

```JavaScript:index.js
for (var i = 0; i < roopNum; i++) {
    $('#tempListsId').append('<li>' + i + '</li>');
}
```

改善パターンは、jQueryのセレクターを変数にキャッシュします。

```JavaScript:index.js
for (var i = 0; i < roopNum; i++) {
    tempSelector.append('<li>' + i + '</li>');
}
```

[デモはこちら](https://yunbow.github.io/sample-javascript-performance/avaivale/jquery_selector_cache/)
[ソースファイルはこちら](https://github.com/yunbow/sample-javascript-performance/tree/master/avaivale/jquery_selector_cache/)

計測結果は下記の通りです。
それほど大きな差はありません。

|ブラウザ名|10回|100回|1000回|
|:--|:--|:--|:--|
|Google Chrome（Anti）|1|8|77|
|Google Chrome|4|11|44|
|Mozilla Firefox（Anti）|16|68|222|
|Mozilla Firefox|29|27|204|
|Microsoft Edge（Anti）|9|48|174|
|Microsoft Edge|9|24|138|
|Microsoft Internet Explorer（Anti）|10|40|346|
|Microsoft Internet Explorer|5|36|323|

以上です。

# 関連記事

[[JavaScript] パフォーマンス改善（その1）](https://qiita.com/yun_bow/items/289450b8e1bd396dce4a)
[[JavaScript] パフォーマンス改善（その2）](https://qiita.com/yun_bow/items/084ad827038356c76725)