React.lazyとSuspense:なぜ「ただの遅延読み込み」以上の価値があるのか
やあ。今日もフロントエンドの深淵を覗き込んでいるかな?
Reactで中規模以上のアプリケーションを開発していると、必ずぶち当たる壁がある。そう、「バンドルサイズの肥大化」だ。ユーザーがまだ開いてもいない画面のコードまで、初期ロードで律儀に全部読み込ませるなんて、今のWebの基準ではいささか親切すぎる。
今日は、Reactの標準機能である `React.lazy` と `Suspense` を使って、この問題をスマートに、かつ「宣言的」に解決する方法を深掘りしていく。公式ドキュメントには書いていない、現場のリアルな勘所を伝授しよう。
—
1. ブラウザの裏側で何が起きているのか?
`React.lazy` を使うと、Reactはコンポーネントを「最初からメモリに載せるもの」ではなく、「必要になった瞬間にネットワーク越しに取得するモジュール」として扱うようになる。
裏側では、WebpackやViteなどのバンドラーが、そのコンポーネントを別のJSチャンク(独立したファイル)として切り出している。ブラウザは、そのコンポーネントがレンダリングツリーに現れた瞬間に、初めてそのファイルを `fetch` しに行く。
ここで重要なのは、「読み込み中の状態」を誰が管理するかだ。従来のReactだと、`useState` で `isLoading` フラグを立てて、`if (loading) return
そこで登場するのが `Suspense` だ。
—
2. 現場で使える「綺麗なコード」の書き方
まずは、基本形を見てみよう。特定の画面(ルート)を遅延読み込みする、最も標準的で美しいパターンだ。
import React, { lazy, Suspense } from ‘react’;
// コンポーネントを動的にインポート(コード分割の境界線となる)
// React.lazyはPromiseを返す関数を受け取る
const HeavyDashboard = lazy(() => import(‘./pages/HeavyDashboard’));
const App = () => {
return (
我々のアプリケーション
{/
Suspenseは「境界線」を作る。
配下のコンポーネントが読み込み中(Promiseが解決していない状態)の間、
fallbackで指定したUIをレンダリングする。
/}
}>

コメント