【実務・中級編】 React.lazyとSuspenseによるコード分割 – React実践ガイド

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をレンダリングする。
/}
ダッシュボードを読み込み中…

}>

);
};

export default App;

なぜこの書き方が優れているのか?

ここでの最大のポイントは、「読み込み状態の管理」をコンポーネントの責務から切り離している点にある。`HeavyDashboard` は、「自分がどうやって読み込まれるか」を一切気にする必要がない。ただUIとしてそこに存在するだけだ。これがReactが目指した「宣言的UI」の真骨頂だよ。

—

3. 実務で遭遇する「落とし穴」への対策

しかし、現場は教科書通りにはいかない。中級者として知っておいてほしい「現場の知恵」が2つある。

① 「ErrorBoundary」との併用は必須

`lazy` で読み込むファイルがネットワークエラーなどで取得できなかったらどうなるか? 画面は真っ白になり、コンソールには無慈悲なエラーが出る。
だからこそ、`Suspense` と `ErrorBoundary` はセットで使うのが鉄則だ。

// 読み込み失敗時のフォールバックUI
const ErrorFallback = () =>

読み込みに失敗しました。再読み込みしてください。

;

// 運用コードではこう包む
}>
}>


② チャンクの分割単位を意識する

何でもかんでも `lazy` にすればいいわけではない。細かくしすぎると、今度はリクエスト数が爆発して「ウォーターフォール(リクエストの連鎖)」が発生し、逆にパフォーマンスが落ちる。
「ページ単位」や「モーダルなどの大きな機能単位」で分割するのが、今のところ一番費用対効果が高い。

—

最後に:アーキテクトからのアドバイス

`React.lazy` と `Suspense` を使いこなすことは、単に「ロード時間を短縮する」ことだけが目的じゃない。「アプリケーションの依存関係を疎結合にする」という、アーキテクチャ上の大きなメリットがあるんだ。

もし後輩から「どこで分割すべきですか?」と聞かれたら、こう答えてやってくれ。
「ユーザーがその機能を使う可能性が低い場所、あるいは初期ロードには不要な重いライブラリを抱えている場所。そこが、君のコードを分割すべき境界線だ」と。

コードを綺麗に保つことは、自分たちの未来のメンテナンスコストを払っているのと同じことだ。今日学んだことを、ぜひ明日のPR(プルリクエスト)に活かしてくれ。期待しているよ。

コメント

タイトルとURLをコピーしました