4

ノードの山で多くのクラスを変更するための効率的なアルゴリズムを考え出そうとしていますが、javascript が DOM をどのように処理するかについての理解に大きな穴があることがわかりました。

ブラウザ/javascript は、フラッシュのようにエラスティック レーストラックを使用しますか? それとも、変更があるたびにディスプレイ全体が再描画されるイベント駆動型ですか?

「エラスティック レーストラック」は、フラッシュがループする大きな大きなループを想像するフラッシュ パラダイムです。ユーザーの処理中に変更が蓄積され、フラッシュの処理中にフラッシュ エンジンが競合してすべての変更を何度も適用します。

別の方法は、属性が変更されるたびに画面全体が再描画されるイベント モデルです。これはおそらくブラウザーが行うことですが、よくわかりません。

そして、変更がなければ何も起こらないハイブリッドアルゴリズムを考えることができます-しかし、変更がある場合は、それらが蓄積されることを許可されます-私のシンクの皿のようなものです。

属性の変更と DOM の挿入を処理するために使用されるアルゴリズムの簡単な説明を持っている人はいますか?

4

1 に答える 1

6

Flash の「エラスティック レーストラック」はブラウザから継承されました。もちろん、ブラウザの世界ではそうは呼ばず、イベント ループと呼んでいます。

JavaScript のイベント ループの歴史は、Netscape でのプログレッシブ GIF および JPEG レンダリングから始まりました。プログレッシブ レンダリング (部分的に読み込まれたコンテンツの描画) には、Netscape が非同期ダウンロード レンダリング エンジンを実装する必要がありました。Brendan Eich が JavaScript を実装したとき、この非同期イベント ループはすでに存在していました。そのため、別のレイヤーを追加するのはかなり簡単な作業でした。

したがって、ブラウザのイベント ループは次のようになります。

    Event loop
        ┌──────────┐
        │          │
        │          │
        │          ▼
        │        check if there's any new ───────▶ parse data
        │        data on the network                    │
        │          │                                    │
        │          ▼                                    │
        │        check if we need to execute  ◀─────────┘
        │        any javascript ──────────────────▶ execute
        │          │                               javascript
        │          ▼                                  │
        │        check if we need to ◀────────────────┘
        │        redraw the page  ──────────────▶ redraw page
        │          │                                   │
        │          │                                   │
        └────◀─────┴─────────────────◀─────────────────┘

彼らが言うように、残りは歴史です。Microsoft が JavaScript をコピーしたとき、Netscape との互換性を維持するために、イベント ループを複製する必要がありました。そのため、Netscape および IE との互換性を維持するために、誰もが同じことをしなければなりませんでした。

JavaScript には手動でイベント ループに再帰する機能がないことに注意してください (たとえば、tcl などの一部の言語では実行できます)。そのため、ブラウザは、実行する JavaScript がなくなるまで待機してから、ページを再描画する必要があります。スクリプトが終了するまで、ページの再描画を強制することはできません。

このため、要素の幅や高さなどの計算された値を作成直後に読み取ろうとすると、間違った値が返されることがあります。ブラウザーはまだそれらを描画していません。ページの再描画後にコードを実行する必要がある場合の回避策はsetTimeout、タイムアウト値を 0 にして を使用し、ブラウザがイベント ループを 1 回実行できるようにすることです。


追加の詳細:

高価なリフローを引き起こす例外的な条件が 1 つあります。リフローは、ページ レイアウトを計算するブラウザーであることに注意してください。通常、ブラウザが変更されたページを描画する必要がある場合にトリガーされます。

ページ内の何かが変更されると、リフロー計算がキューに入れられ、すぐには実行されません。上記の説明のように、リフローは JavaScript 実行の最後にのみ実行されます。しかし、ブラウザーがすぐにリフロー計算を実行する原因となるケースが 1 つあります。それは、幅や高さなどの計算値を読み込もうとした場合です。

詳細については、この関連する質問を参照してください: DOM 環境でリフローが発生するのはいつですか?

于 2013-10-27T15:53:16.947 に答える