SPAはコードレベルでどのように実現されているのか?

ワンワン!🐶 技術的な詳細へようこそ! 「ブラウザの機能を乗っ取る」という表現がぴったりなくらい、JavaScriptが裏で3つの重要な仕事をこなしています。
具体的にコード(JavaScript)レベルで何が起きているのか、3ステップで解説します。
1. 🛑 「ちょっと待った!」(イベントの無効化)
ブラウザには元々「<a>タグ(リンク)をクリックしたら、そのURLへ飛ぶ」という標準の機能が備わっています。 SPAでは、これを力ずくでキャンセルします。
使う呪文(メソッド)は event.preventDefault() です。
// リンク(<a href="/next">)がクリックされた瞬間を監視
document.querySelector('a').addEventListener('click', function(event) {
// 【最重要】 ブラウザ標準の「ページ移動」をキャンセルする!
event.preventDefault();
console.log("移動を阻止しました。ここからは俺(JS)の仕事です");
// ...続きの処理へ
});
-
技術的なポイント: これを実行した時点で、ブラウザは「URLを変えてサーバーにリクエストを送る」という本来の仕事を放棄します。結果、URLはピクリとも動きません。
2. 🕵️♂️ 「裏で取ってくる」(非同期通信)
画面移動を止めたので、今のままでは何も起きません。 そこでJavaScriptは、Fetch API を使って、こっそりサーバーに「次の画面のデータ(部品)」を取りに行きます。
// 裏でサーバーにデータを取りに行く
fetch('/api/next-page-data')
.then(response => response.json()) // JSONとして受け取る
.then(data => {
// dataの中身: { title: "次のページ", content: "これが新しい記事です..." }
updateScreen(data); // 次のステップへ
});
-
技術的なポイント: 画面(ブラウザのウィンドウ)はそのまま表示しつつ、バックグラウンド通信(Ajax)を行うため、ユーザーは読み込み待ちの「白い画面」を見なくて済みます。
3. 🎨 「書き換える」(DOM操作)
データが届いたら、今表示されているHTMLの一部を、新しいデータで上書きします。これをDOM(ドム)操作と言います。
function updateScreen(data) {
// 今ある <div id="app"> の中身を、新しいデータで塗り替える
const app = document.getElementById('app');
// HTMLの中身をガサッと入れ替える(乱暴な例ですがイメージです)
app.innerHTML = `
<h1>${data.title}</h1>
<p>${data.content}</p>
`;
}
-
技術的なポイント: ブラウザ全体を再読み込みするのではなく、
id="app"という枠の中身だけ を手術のように入れ替えています。
🎬 全体の流れのまとめ図
-
クリック検知: ユーザーがリンクを押す。
-
preventDefault(): JSが「動くな!」とブラウザを止める(URL変わらず)。 -
fetch(): JSが「データ取ってくるわ」と裏で走る。 -
innerHTML = ...: JSが「持ってきたデータでここ書き換えとくね」と画面を更新する。
これが、「URLが変わらずに画面だけが変わる」技術的な正体です。
補足:じゃあどうやってURLを変えるの?
現代のSPA(React Routerなど)では、上記に加えてもう一つ、History API という技術を使います。
// ブラウザのURL欄を、ページ移動せずに「書き換えるだけ」の命令
window.history.pushState(null, null, '/next-page');
これを最後に実行することで、「ページ移動はしていない(高速)」だけど「URLは変わっている(ブックマークできる)」という、いいとこ取りを実現しているのです。
🤔フムフム