JSの実行速度とページ表示アルゴリズムを調べる

JSまたはページレンダリングの速度のテストは、ありがたい仕事です。 テストは、最も同一の条件下で実行され、同じ機能を持つものがテストされる場合にのみ、現実を反映します。 結局のところ、高速であるか、トラックであるか、スポーツカーであるかを問われると、誰もがすぐにスポーツカーだと答えます。 そして、フィールドが糞トレーラーでイエスなら? それぞれの場合の勝者は、特定のタスクを実行するのに最も適したものになります。



この記事にはいくつかの仮説と事実があります。 ファンのスピーチやブラウザの向きを変更するための呼び出しはありません



だから、実験用のウサギ:



IE9を仮想マシンにインストールしているため、IE9をテストしませんでした。これには、速度の低下と値の顕著な広がりが存在します。





JSエンジンは最適化、最適化されていますが、最適化されていません



JSエンジンの速度をめぐる競争はうまくいきました。ブラウザーの応答性が向上し、コーダーがページの表示をより細かく制御できるようになり、アニメーションが目を楽しませました。 これらはすべての利点ではなく、長期間にわたってリストすることができます。 SunSpiderDromaeoV8 Benchmark Suiteなど、すばらしいベンチマークの最適化の素晴らしさについて学びました。 問題は、これらすべてのベンチマークが何をしようとしていたのかということです。 JS実行速度? おそらく。 そして多分そうではない。



DOMは何を構築する必要がありますか?



単純な馬の真空球の例を見てみましょう。ループ内のスクリプトがDOMノードを作成し、それがドキュメントに追加されます。



少し先に走ります。 Javascriptエンジンはブラウザとは別に存在できることを知っているので、テストスクリプトの実行は3つの段階に分かれると想定しています。



  1. ノードを作成するJS機能の実行(簡単にするために、「JS」と呼びましょう)
  2. ブラウザ(DOM)でのDOMオブジェクトの作成
  3. ノードのレンダリング(レンダリング)




順次実行



明らかに、要素を表示するメカニズムを実装する最も簡単な方法は、コマンドを順番に実行することです。最初に、JS関数を実行します。このコマンドにより、DOMノードのインスタンスを取得し、レンダリングに送信します。



画像



これは悪い実装方法ではありません。 主な欠点は、ブラウザの他の機能部分からJSエンジンを「遮断」できないことです。 ただし、これを回避する簡単な方法があります。



一度に1つのタスクを実行する



そして、耳を失い、レイヤーをいくつかの実行キューで分割しましょう。 JSエンジンは、タスクをDOMオブジェクトのファクトリーにさらに渡した後、一連のコマンドを単に実行のためにキューに入れ、スリープ状態にします。 ファクトリは必要なすべてのコマンドを実行し、同時にレンダリングの準備が整ったオブジェクトのセットを作成します。 すべてをレンダリングキューに入れ、バトンをレンダリングシステムに渡します。 出来上がり!



画像



このようなアーキテクチャでは、ブラウザの一部を他の部分から「遮断」するのは非常に簡単で、タスクキューを介して通信が行われます。



完全な並行性



前の実施形態では、ステップは順次実行される。 しかし、3つの並列システムを作成するとどうなりますか? DOMオブジェクトのファクトリはジョブキューを監視し、コマンドが表示されるとすぐに、DOMノードをすぐに作成し、それをレンダリングキューに送信します。



画像



怖い はい、とても面白いです!



テスト中



上記の各アーキテクチャのJS実行速度を測定してみましょう。 まだテストを開始していませんが、最初のケースでは2番目と3番目の3つのステージすべての速度、つまりキューの作成速度のみを測定することは既に明らかです。 しかし、これは現実を反映しません!



3つのアプローチのバランスをとるために、単純なベンチマーク( RapidShare / Yandex / pasteBin )を作成しました。 いくつかの空白のクローンがランダムに生成されます。 クローンが行の最後の場合、利用可能なすべての空きスペースを占めるように幅が割り当てられます。 要素は浮遊しており、描画されるまで、どの位置と幅があるかは明確ではありません。 実際、私はすべてをコマンドの順次実行に導きました。



テストは本当に驚きました。



まず、負荷なしでテスト結果を見てみましょう。



画像

500 750 1000
Firefox 19 30 45
オペラ 6 10 14
クロム 5 9 14


FoxはOperaとChromeの3倍遅れています。 ChromeはOperaよりも少し高速ですが、反復の回数が増えると、遅延は減少します。



「ブレーキ」をオンにします



画像

500 750 1000
Firefox 950 2350 4800
オペラ 610 1250 2100
クロム 5700 20500 〜55000


私は自分の目を信じることができませんでした。 1000回の繰り返しで、Chromeは残酷な思いやりに陥り、脆弱な魂をm笑せず、スクリプトの実行を停止することで苦しみを終わらせるよう要求します。 これは車輪の中の棒です!



Operaは無条件で競争に勝ちました。



ちょっとした分析



負荷のある結果と負荷のない結果の比率をとると、かなり興味深い画像が表示されます。 Firefoxのパフォーマンスは50〜100倍低下します。 反復回数による速度の低下はほぼ線形です。 ブラウザの画像と動作は、最初のスキームであるステップの順次実行に非常によく適合しています。 視覚的に、Foxはループが完了するまでページをレンダリングしません。



Operaでは、負荷をオンにしたときの速度低下は100から150倍です。 オペラは、スクリプトの実行時にページをレンダリングします。これは、3段階の並列実行スキームに非常に似ています。



Chromiumの速度低下の範囲は1,000〜4,000倍です。 Chromeは、ループが完了するまでページをレンダリングしません。 これは一連のステップに非常に似ています。



おかしい。



おわりに



私の記事は部分的に理論的であり、そこに示されているアーキテクチャは実際には確認されていません。



要素のサイズを分析するスクリプトを作成するときは、注意して注意してください。 レンダリングアーキテクチャの違いは、嘆かわしい速度低下につながる可能性があります。



UPD。 Yandexのベンチマークへのリンクを追加しました



多くの人が、どのプログラムでチャートを作成するかを尋ねます。 Corel Photopaint X5を手動で。



UPD2。 pasteBinへのリンクを追加しました。 お友達ありがとう!



All Articles