0Pricing
React Academy · レッスン

useLayoutEffectとuseEffectの実行タイミング

useLayoutEffectがDOMの変更直後、ブラウザーの描画前に同期的に実行されることを学びます

「useLayoutEffectとuseEffectの実行タイミング」はCoddyKit上の無料React Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはReact Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 React Academyコースには全4レッスンが含まれています。

useLayoutEffectのタイミング

useLayoutEffectは、ReactがDOMの変更を適用した直後、ブラウザがその変更をペイントする前に、同期的に実行されます。ブラウザから見ると、レイアウトエフェクトとDOMの変更は、途切れることのない同じ同期処理ブロックの一部です。

useEffectのタイミング

useEffectは、ブラウザがペイントを完了した後に非同期で実行されます。ユーザーが更新されたUIを先に見て、その後でエフェクトが実行されます。そのためuseEffectはレンダリング性能への影響が小さくなりますが、エフェクトによって見た目に変化が生じる場合は、2回目のペイントサイクルが発生します。

タイムスタンプ実験

両方のエフェクトでタイムスタンプをログ出力すれば、タイミングの違いを確認できます。useLayoutEffectにconsole.log('layout', Date.now())を追加し、useEffectにconsole.log('passive', Date.now())を追加してください。コンソールでは、レイアウトエフェクトのタイムスタンプが必ずパッシブエフェクトのタイムスタンプより早くなり、実行順序を確認できます。

ユーザーに見える影響

useEffectが見た目に影響するstateを更新すると、ユーザーには2回のレンダーが見えます。最初は古いstateでレンダーされ、その後、エフェクトの実行後に修正されたレンダーが行われます。これは、目に見えるちらつきやレイアウトの再配置として現れます。useLayoutEffectなら、そのstate更新がブラウザのペイント前にコミットされるため、この問題を防げます。

useLayoutEffectのstate更新による同期的な再レンダー

useLayoutEffect内でsetStateを呼び出すと、Reactはペイント前にもう一度レンダーとコミットのサイクルを直ちに実行します。ブラウザがペイントするのは最終結果だけなので、ユーザーが中間状態を見ることはありません。これがuseLayoutEffectの主な用途です。DOMを測定し、新しい値を計算してstateを設定し、1回の整ったペイントを保証します。

パフォーマンス上の注意点

useLayoutEffectはペイント前に同期的に実行され、追加のレンダーを引き起こす可能性があるため、多用すると性能が低下することがあります。同期処理が重い場合、ブラウザのペイントがブロックされ、目に見えるカクつきが発生します。視覚的なちらつきを防ぐ必要がある場合にだけ使用し、それ以外ではuseEffectを使用してください。

Strict Modeでの二重呼び出し

React Strict Mode(開発時のみ)では、useLayoutEffectとuseEffectの両方が、1回のマウントにつき2回呼び出されます。順序は、マウント、クリーンアップ、再度マウントです。これにより、適切にクリーンアップされないエフェクトを検出できます。本番ビルドでは二重呼び出しは発生しません。

パフォーマンスの原則:まずはuseEffectを使う

デフォルトでは、常にuseEffectを選択してください。目に見えるちらつきや不正なレイアウトの問題を実際に確認して再現できる場合にだけ、useLayoutEffectへ切り替えます。useLayoutEffectを使いすぎると、ブラウザのペイントパイプラインを不必要にブロックし、体感性能を低下させる可能性があります。

SSRの注意点:サーバー上でのuseLayoutEffect

useLayoutEffectはサーバー上では実行できません。サーバー環境にはDOMもブラウザのペイントサイクルも存在しないためです。サーバーでレンダーされるコンポーネントで使用すると、Reactは警告を出力します。対処方法は、エフェクトを条件付きでスキップすることです。typeof window !== 'undefined'を確認するか、SSR対応のコードではuseEffectに切り替えてください。

どちらを使うかの判断方法

次のように自問してください。「このエフェクトは、最初のペイントでユーザーに見えるものを変更しますか?」答えが「はい」なら、ちらつきを防ぐためにuseLayoutEffectを使います。「いいえ」なら、データ取得、サブスクリプション、分析、ログ出力、その他ほとんどの副作用にはuseEffectを使います。この判断基準で、実際のユースケースの大半に対応できます。

useLayoutEffectの同期的な性質

useLayoutEffectはDOMの変更と同じ同期処理ブロック内で実行されます。useLayoutEffectの実行中、Reactはユーザーイベントへの応答など、他の処理を実行できません。そのため、処理は短く、目的を絞ったものにする必要があります。useLayoutEffect内で長時間実行される同期コードを書くと、ブラウザによる画面への描画が直接遅延します。

useLayoutEffectのタイミング

DOMの変更やブラウザのペイントに対して、useLayoutEffectは正確にはいつ実行されますか?

レッスンのまとめ:useLayoutEffectとuseEffectの比較

useLayoutEffectは同期的に実行され、ブラウザのペイント前に発火するため、DOMの測定や見た目の修正に適しています。useEffectはペイント後に発火し、データ取得、サブスクリプション、その他ほとんどの副作用に適しています。基本的にはuseEffectを使い、視覚的なちらつきによってuseLayoutEffectが必要だと確認できた場合にだけ切り替えてください。SSRではガードなしで使用しないでください。

よくある質問

「useLayoutEffectとuseEffectの実行タイミング」レッスンは無料ですか?

はい。「useLayoutEffectとuseEffectの実行タイミング」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、React Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 React Academyコースには全4レッスンが含まれています。

「useLayoutEffectとuseEffectの実行タイミング」で何を学びますか?

useLayoutEffectがDOMの変更直後、ブラウザーの描画前に同期的に実行されることを学びます ブラウザで直接実行するハンズオンコードでReact Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

React Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのReact Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「useLayoutEffectとuseEffectの実行タイミング」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このReact Academyレッスンでコードを書いて実行できますか?

はい。すべてのReact Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. レンダリングフェーズとDOMコミット
  2. useLayoutEffectとuseEffectの実行タイミング
  3. useLayoutEffectによるDOM要素の測定
  4. レイアウトスラッシングと視覚的なちらつきの回避
← React Academyに戻る