gaggitのブログ

コーディング、ガジェット、TIPS関連、FX

JavaScriptの実行が遅くなる 原因結果

前回、お伝えしたとおり、innerHTML処理が原因の捉えた証拠が以下の画像です。(画像は、実行途中からの計測)

f:id:gaggit:20160529081351p:plain

これは、IE11のデバッガーの「パフォーマンス」を実行した「タイムライン」の結果です。実行方法は、画面をクリック、またはCtrl-Eで計測を開始し、再度、画面をクリックかCtrl+Eで計測を終了します。パフォーマンスを使用するにあたっての注意点は、後述します。

 

これは、XMLHTTPRequestの実行結果をinnerHTMLをinnerHTL+=で追加書きした約180回目の処理で、innerHTMLの処理だけで約70秒ほどかかっています。念のために言っておきますが、180回分の合計時間ではありません、1回分の処理です。

さらに、この中で発生している処理をみてみると、DOMNodeRemovedが35回、DOMNodeInsertedが69回、発生していました。それぞれ1回の処理に10~20ミリ秒、30~40ミリ秒かかっています。前回、XMLHTTPRuest処理が1300回あたりでは、innerHTML処理で500秒ぐらいかかっていた可能性があります。(実現させようと、JavaScriptを実行しましたが200回あたりで、NetworkErrorでこけてしまいました)

とりあえず結論としては、メモリではなく、innerHTML処理が処理回数とともに処理時間が増大しており、レンダリング処理で停止したか、処理に多大な時間がかかっていて止まっているように見えるで、いいのかな。。。

 

私は対策として、一度にinnerHTMLに代入する方法を行いましたが、別の対策として、DOM操作メソッドを使って、要素を追加していく方法があるようです。以下のサイトにinnerHTMLによる注意点とDOM操作メソッドを使った追加の方法が2つ、書かれていました。

html5experts.jp

デバッガーの「パフォーマンス」を使用しての注意点というか、気が付いた点を述べます。

まず、タスクマネージャーで観測しながら、デバッガーを立ち上げると、Internet Explorerのプロセス数が2つになります。さらに別のタブを新たに開いて、そこでもデバッガーを立ち上げるとプロセス数が合計4つになります。つまりタブで1プロセス、それぞれのデバッガで1プロセスということのようです。ざっくりしか見ていませんが、メモリ消費は、タブのプロセスで約120MB、デバッガのプロセスで約300MBでした。

上記で話したとおり、NetworkErrorで止まってしまったため、一旦、パフォーマンスの計測を終了するために画面をクリックしたところ、デバッガのプロセスのメモリ消費が約300MBから約2,300MBまで一気に増えました。恐らく解析に2GBのメモリを割り当てたのでしょう。さらに計測終了直後に「タイムライン」横の「JavaScriptコールスタック」をクリックし、解析を始めると、こちらでもさらに約2GBのメモリ消費となり、合計4,300MBメモリを消費していました。まー、空いているメモリの度合いを計算しながら、メモリ割り当てを行っているでしょうが、少し驚きました。計測終了と同時にメモリ消費も元の約300MBに戻りました。また、解析中は、常にディスクアクセスが数十MB/sとなっていました。バックグランドでメモリを消費している方、元々メモリ搭載が少ない方は、注意が必要です。

今の気持ちを伝えると、まだまだ世間の3年前あたりをうろちょろしているなーって、ことです。やれやれ感が強いです。orz

まだまだ、いろいろ調査をしてみたいのですが、Android Studioでの開発はどうしたーって、ことで、調査は終了です(^^;。

5/30追記 調査続行中です。orz

5/31追記 原因:innerHTML、対応方法:変数の文字列で確定です。(5/30追記は、コーディングミスでした。すみません。)

6/8追記 原因:innerHTML、対応方法:textContentを使用する。データは、生のままです。htmlのタグは変換してくれません。

 

今日もがじがじっと~♪