1. ホーム
  2. javascript

[解決済み] innerHTMLは非同期ですか?

2022-11-07 18:34:58

質問

私は自分自身を馬鹿にしないことを望みますが、私はこれらの2行のコードで何が起こっているかを理解しようとしています。

document.body.innerHTML = 'something';
alert('something else');

私が観察しているのは、HTMLが更新される前にアラートが表示されることです(あるいは、更新されていても、ページが更新/再描画/何でもされていないのかもしれません)。

次のものを見てください。 コードペン をご覧ください。

なお alert の中に setTimeout(..., 0) は役に立ちません。にはもっとイベントループが必要なようです。 innerHTML が実際にページを更新するために、より多くのイベントループを必要とするようです。

EDITです。

書き忘れましたが、私はChromeを使用しており、他のブラウザは確認していません。Chrome でのみ表示されるようです。それでも、私はなぜそれが起こっているのかに興味があります。

どのように解決するのですか?

innerHTMLの設定は、DOMに加えることができるほとんどの変更と同様に、同期的です。しかし レンダリング のレンダリングは別の話です。

(DOM は "Document Object Model" の略であることを思い出してください。これは単なるモデルであり、データの表現です。ユーザーが画面上で見るものは、そのモデルがどのように見えるべきかのイメージです。ですから、モデルを変更したからといって、瞬時に絵が変わるわけではなく、更新に時間がかかるのです(笑)。

JavaScriptの実行とウェブページのレンダリングは、実際には別々に行われます。簡単に言うと、まずページ上のすべての JavaScript が実行されます (イベント ループからです。 この素晴らしいビデオ をご覧ください)、次に の後に、ブラウザがウェブページに何らかの変更を加えてユーザーに表示することです。計算負荷の高いコードを実行すると、ブラウザが JS の実行ステップを過ぎてページのレンダリング ステップに入るのを妨げ、ページがフリーズしたり吃音になったりするからです。

Chrome のパイプラインは次のようなものです。

ご覧のとおり、すべての JavaScript が最初に実行されます。次に、ページのスタイル設定、レイアウト、描画、合成が行われます(quot;render")。このパイプラインのすべてが、毎フレーム実行されるわけではありません。どのページ要素が変更されたか(もしあれば)、そしてそれらがどのように再レンダリングされる必要があるかに依存します。

注意してください。 alert() も同期で、JavaScript のステップの間に実行されます。そのため、ウェブページへの変更を確認する前に警告ダイアログが表示されるのです。

パイプラインの「JavaScript」ステップでは一体何が実行されるのでしょうか?すべてのコードは 1 秒間に 60 回実行されるのでしょうか? JSコードは、イベントリスナーやタイムアウトなど、スタックにある場合にのみ実行されます。以下はその例です。 前の動画 (を参照してください(本当に)。

https://developers.google.com/web/fundamentals/performance/rendering/