はじめに
これまで何となく fetch
や SPA
という言葉を使っていましたが、React
での開発を通じて、それらがどう貢献しているのかはよく分かっていませんでした。
そこで今回、『プロになるためのWeb技術入門』を読んで基礎から学び直した内容を、自分なりに整理してまとめます。
fetchとは
fetch
は、JavaScriptで非同期通信を行うための関数で、主にJSON形式のデータをやり取りするのに使われます。
従来のWebアプリでは、サーバーからHTMLを丸ごと受け取っていましたが、fetch
を使えば必要なデータだけを取得し、画面に反映できるため、表示速度や操作性が大きく向上します。
XHR(XMLHttpRequest)との違い
以前は XMLHttpRequest(XHR)
を使って非同期通信を行っていましたが、fetch
はPromiseをベースで書けるため、非同期処理のコードがシンプルに書けます
SPAとは
SPAは、 Single Page Application
の略称です。
従来のWebアプリでは、ユーザーの操作ごとにサーバーから HTML全体を再取得 していたため、画面が再読み込みされるたびに白くなったり遅延が発生していました。
また、POSTの再送信を防ぐため、 PRG(Post-Redirect-Get)
パターンを使う必要があり、画面の切り替えに時間がかかっていました。
しかし、fetch
を用いた SPA
を使うことによりJSON形式でレスポンスでき、結果をそのままJavaScriptによって描画するため、表示が高速化されます。
PRG(Post-Redirect-Get)とは
フォームの送信(POST)後に、そのまま結果画面を表示すると「再読み込み時に再送信されてしまう」という問題が起きます。
それを防ぐために、POST後に一度リダイレクト(Redirect)し、GETで最終的な画面を表示するパターンです。
目的は、ユーザーの「再読み込み」操作で、同じPOSTリクエストが再送されて、同じデータが複数登録される ことを防ぐことです。
SPAにおけるURLの課題
SPA
では、JavaScriptにより「画面遷移しているように見える」だけで、実際のURLが変わらない という特性があります。
このデメリットは以下のようなものが挙げられます。
- 特定の画面をブックマークとしても、対象の画面が保存できない
- ブラウザ上の戻る・進むボタンが機能しない
これらのデメリットに対して2つの解決方法があります。
1. フラグメント
この課題への解決策の1つが 、フラグメント(URLの # のあとに付く部分)の活用です。
例えば次のような形式です。
https://example.com/#profile
ブラウザのアドレスバーでフラグメント部分(#profile)が変化しても、ブラウザには認識されますがサーバーには送信されません。
ブラウザ側では、JavaScriptの location.hash
を使って、フラグメントの変化を検知・監視することができます。
ただし、フラグメントを使う方法には、以下の弱点があります。
- URLと画面が1対1に対応していないため、Googleなどの検索エンジンがこの部分を読み取れないことがあり、検索結果に表示されにくくなる(SEOに弱い)
- URLのフラグメントが変わっても、サーバーではその違いが分からないため、他の人に共有しても同一画面が再現されない可能性がある
2. History API
そこで使われるのが History API
です。
history.pushState()
を使うことで、サーバーへのリクエストなしに、URLを変更したように見せかけながらページ遷移が可能になります。
これにより、以下のメリットが挙げられます。
- URLと画面が1対1で対応
- URLごとのブックマークが可能
- 戻る・進むボタンも機能する
- SEO対策にも効果的
このように、History API
を用いることで、フラグメント
のデメリットを克服することができるようになりました。
Reactにおけるルーティング
また、React
ではこのHistory API
を活用したReact Router
が使われています。
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/profile" element={<Profile />} />
</Routes>
</BrowserRouter>
);
}
このように、BrowserRouter
を使えば history.pushState()
を意識することなく、「画面とURLの1対1の対応」 を自然に実現できます。
SPAの初期表示の課題
ただしSPA
にはもう1つ課題があります。
それは、初回表示時にJavaScriptの読み込みと実行が完了するまで画面が表示されない という点です。
この問題に対処する技術が、 SSR(サーバーサイドレンダリング) です。
代表的なフレームワークである Next.js
は、React
をベースにしつつ SSR
に対応しており、初期表示の高速化や、SEOの改善に役立ちます。
まとめ
今回は、SPA
や fetch
について「なぜ使われているのか」「どんなメリットがあるのか」が少しずつ理解できました。
今後、現在学習中の React
やこれから学習する Next.js
で、画面遷移やデータ取得を扱うときは、こうした背景を意識しながら使いこなしていきたいと思います。