SPA(Single Page Application)は、最初に読み込んだ1枚のページの上で、JavaScriptがデータだけを取り直して画面を書き換えるWebアプリケーションの作りです。日本語の「SPA」は製造小売業(Speciality store retailer of Private label Apparel)の略でもありますが、この記事が扱うのはWebアプリケーションのほうです。サービス名だけでは構成の違いが分からないため、ここでは運営会社が自ら構成を公表している事例だけを出典付きで集め、在庫管理や販売管理のような業務システムをSPA化するときの判断基準と移行手順につなげます。SPAそのものの定義や開発言語はSPAとは?開発言語・フレームワークの選び方とMPA・SSRとの違い【2026年10月】で整理しています。
まとめ:SPA事例から分かる採否と移行の要点
公表されている事例を並べると、SPAが選ばれた画面には共通点があります。地図をドラッグする、メールを書きながら一覧を見る、課題を次々に開くといった、同じ画面で操作を何十回も繰り返す場面です。反対に、Netflixはログアウト状態のホームページからクライアント側のReactを外し、37signalsはHTMLをサーバーから送るHotwireを自社製品に使っています。閲覧が主役の画面にSPAは要りません。
本稿で紹介する業務SaaSの移行記録では、画面単位で段階的に置き換える方式が採られています。kintoneは100ページ以上を小さい単位で、freee販売は新旧2つのSPAをURL単位で出し分けながら移しています。GitHubは2026年時点でもRails画面とReact画面の境界をまたぐ遷移ではページ全体の読み込みが起きやすいと書いており、移行途中の境界にコストがかかることも分かります。判断はMicrosoftの意思決定テーブル(チームのJavaScript/TypeScript知識・スクリプト無効ブラウザー対応・クライアント側の動作量・UIの複雑さ)で画面ごとに行い、実装ではルーティング・認証トークンの置き場所・フォーカス移動の3点を最初に決めてください。
有名WebサービスのSPA事例と各社が公表した構成
次の表は、運営会社または命名者が一次情報で構成を説明している事例だけを並べたものです。「画面の性質」の列は、その構成がなぜ効いたのかを読むための当社の整理です。
| サービス | 公表日 | 公表された構成 | 画面の性質 |
|---|---|---|---|
| Googleマップ・Gmail | 2005年2月18日 | Ajaxアプリケーション | ドラッグ・入力の連続 |
| Twitter Lite | 2017年4月6日 | クライアント側JS+小さなNode.js | タイムラインの往復 |
| Spotify(TV・ゲーム機版) | 2019年3月25日 | Web版のSPA | 再生操作の連続 |
| GitHub Issues | 2026年5月14日 | Rails描画・Turbo・Reactの混在 | 課題を次々に開く |
SlackやLINE、noteなども競合記事ではSPAの例として挙がりますが、運営会社が構成を説明した一次情報は今回の調査では確認できなかったため、表には入れていません。
Googleマップ・Gmail:2005年にAjaxの代表例として名指しされた2つ
SPAの源流としてよく引かれるのが、Jesse James Garrettが2005年2月18日に公開した論考「Ajax: A New Approach to Web Applications」です。Garrettは「Google Suggest and Google Maps are two examples of a new approach to web applications」と書き、地図をつかんでスクロールしてもページの再読み込みを待たない操作感を例に挙げました。同じ論考はOrkut、Gmail、Google Groupsのベータ版も「are Ajax applications」としています。
当時の呼び名はAjaxですが、データだけを非同期で受け取って画面を書き換える発想は同じで、Gmailが「SPAの例」と語られる根拠はここにあります。
Twitter LiteとSpotify:運用費と単一チームの軽いクライアント
Twitterは2017年4月6日の技術ブログ「How we built Twitter Lite」で、Twitter Liteを「a client-side JavaScript application and a small, simple Node.js server」と説明しました。サーバーが受け持つのは認証・初期状態の組み立て・最初のHTMLの描画だけで、読み込み後はブラウザーがTwitter APIから直接データを取ります。同記事は、この構成のTwitter Liteをサーバー描画のデスクトップ版より「an order of magnitude less expensive to run」(運用費が1桁安い)とし、直近3か月で平均ロード時間を30%以上縮めたとも書いています。
Spotifyは2019年3月25日の新Web Playerの開発記事で、手本にしたTV・ゲーム機向けアプリを「a web-based Single Page Application」と明記しました。Spotify Web APIの上に1チームで作った軽いクライアントの好例だった、という位置づけです。どちらの事例も、API側を作り込んでおけば画面は薄いクライアントで済むという構図が共通しています。
GitHub:Rails画面とReact画面が混在する移行途中の実像
「GitHubはSPA」と一言で片づけるのは不正確です。GitHubは2026年5月14日のIssues画面の高速化の記事で、利用者の遷移を3種類に分けて計測しています。ページ全体を読み込むhard navigation、RailsのTurboで一部の領域だけを差し替えるTurbo navigation、既存のReactランタイム内で画面を切り替えるsoft navigationです。
同記事は「GitHub is still in the middle of moving from Rails-rendered pages to a React frontend」と書き、Rails画面からIssuesへ移るときのように境界をまたぐ遷移では、ブラウザーがページ全体を読み直すことが多いと説明しています。それが計測開始時点でhard navigationが最大の割合を占めた大きな理由でした。React内の遷移はキャッシュと先読みで改善し、主要コンテンツの表示時間を表す独自指標HPCが200ミリ秒未満となる割合を約4%から約22%へ上げています。業務システムを部分的にSPA化すると、旧画面と新画面の境界で同じ問題が起きます。
業務システム・業務SaaSの段階移行と公開画面の構成見直し事例
freee販売:新旧2つのSPAをURL単位でサーバーが出し分ける段階移行
国内の業務SaaSの移行記録として紹介するのは、freee販売のエンジニアが2026年9月18日に書いた「SPAを丸ごと差し替えながら、画面単位で新基盤へ引っ越した話」です。移行前のフロントエンドはReact 17で、ルーターはv5系にv6への互換パッケージを挟んだまま数年止まっていました。規模は手書きコードだけで数十万行、画面数は三桁です(記事は数値を丸めていると断っています)。
採った方式は単純です。旧フロントエンドと新フロントエンドを別々のSPAとして同時にビルドし、Railsのサーバーがリクエストされたパスと機能フラグを見て、どちらのHTMLを返すかを決めます。ブラウザーに届くのは片方だけなので、新旧でReactのメジャー版(17と18)もルーター(v5系とv7)もデータ取得(SWRとTanStack Query)も揃える必要がありません。それでもURL一覧・画面間メッセージ・外部サービスの設定値は共有せざるを得なかった、と書かれています。新旧の境界に残る共有物を先に洗い出す、というのが発注側にも使える教訓です。
kintone:Closure ToolsからReactへ100ページ以上を段階置換
サイボウズは2022年2月4日の「kintone フロントエンドリアーキテクチャプロジェクトで大切にしていること」で、ゴールを「全てのページが React によって表示されている」「フロントエンドが技術的にもチーム的にも分割されている」「ユーザー体験に関する指標に対する計測が行われており、チームの関心ごとになっている」の3つと明示しました。移行元はClosure Library・Closure Compiler・Closure Templatesの構成です。開発用のページなども含めると100ページ以上あり、ユーザーがJavaScriptで拡張できる仕組みも抱えているため、小さい単位でリリースしながら置き換える方針を選んでいます。
2024年12月4日のコード分割の記事では、React移行と並行してページごとにパッケージを分け、依存関係の一覧をバージョン管理してCIで差分を検知する仕組みを紹介しています。ネームスペースの一括リネームにはCodemodツールのjscodeshiftを使いました。3つ目のゴールに指標の計測を入れている点は発注側も真似する価値があります。計測しないと、SPA化は「速くなった気がする」で終わります。
SmartHR:MPA内のReactからReact SPA、Next.jsへ変えてきた経緯
SmartHRの2024年9月2日のフロントエンドの歴史を振り返る対談記事によれば、フロントエンドエンジニアが2人だった時期のReactは「SPA (Single Page Application) ではなく MPA (Multiple Page Application) の中で各ページごとに React を使う」使い方でした。その後Rails APIとReact SPAの組み合わせが主流になり、エンジニアが21名に増えた2022年頃からNext.jsを使うプロダクトが増えています。
同じ会社でも、チームの人数とプロダクトの数に応じて構成を変えています。SPA化は一度決めたら終わりの選択ではありません。
NetflixとHEY:クライアント側Reactの除去とHTML配信の事例
反対方向の事例も同じだけ参考になります。GoogleのAddy Osmaniが2018年11月5日に公開した「A Netflix Web Performance Case Study」によれば、Netflixはログアウト状態のデスクトップ版ホームページで、ReactなどのライブラリをやめてバニラのJavaScriptに切り替え、JavaScriptを200kB以上減らしました。これによりTime-to-Interactiveが50%以上短くなっています。Reactはサーバー側で使い続けており、同記事は「Simple static pages benefit from being server-rendered with minimal JavaScript」とまとめています。会員登録やログインの入口は閲覧が主役で、クライアント側の状態管理がほとんど要らない画面です。
37signalsは別の道を選びました。Hotwireの公式サイトは、JSONの代わりにHTMLを送ることで、JavaScriptをあまり使わずに現代的なWebアプリケーションを作る手法だと説明しています。テンプレートの描画はサーバーに残り、同社のメールサービスHEYを動かすために作られたフレームワーク群です。同じ考え方の実装はhtmxとは?JavaScriptなしで動的UIを作る仕組みとメリット・デメリット【2026年版】で扱っています。
業務システムのSPA化を判断する基準
Microsoftの意思決定テーブルが示す4つの軸
採否の判断で引用しやすい一次情報は、Microsoft Learnの「従来の Web アプリとシングル ページ アプリを選択する」です。SPAを選ぶ条件には、多くの機能を備えたリッチなユーザーインターフェイスが必要なこと、チームがJavaScript・TypeScript・Blazor WebAssemblyの開発に精通していること、ほかのクライアント向けのAPIを既に公開していることが挙がっています。逆に従来型を選ぶ条件は、クライアント側の要件が単純か読み取り専用であること、JavaScript非対応ブラウザーで動く必要があること、一般向けで検索エンジンからの流入に利点があることです。
| 要素 | 従来の Web アプリ | SPA | Blazor アプリ |
|---|---|---|---|
| チームのJavaScript/TypeScript知識 | 最小 | 必須 | 最小 |
| スクリプト無効ブラウザーの対応 | サポートされています | サポートされていません | サポートされています |
| クライアント側の動作が最小限 | 適している | オーバーキル | 実行可能 |
| リッチで複雑なUI要件 | 制限がある | 適している | 適している |
行見出しは短縮していますが、判定の語は引用元のままです。ただし、Blazorのスクリプト無効時の対応は描画モードに依存します。静的SSRによる表示と、JavaScriptを必要とする対話機能を区別してください。実務で一番効くのは3行目で、クライアント側の動作が最小限の画面へのSPA導入は公式の分類で「オーバーキル」です。同ページは、SPAフレームワークには「より高いアーキテクチャとセキュリティの専門知識が必要」で、従来型より更新が頻繁なため変更頻度が高くなるとも述べています。
SPA化の候補を選ぶ5つの操作・機能要件
同じページがSPAの利点として挙げている具体は次の5つです。
- ページを再読み込みせずに操作できる
- バックグラウンドでデータを取得できる
- 増分更新により、送信ボタンを押さなくても部分的に入力したフォームを保存できる
- ドラッグアンドドロップのようなクライアント側の動作を従来型より簡単に実装できる
- 接続が戻ったときにサーバーへ同期するモデルを持たせ、切断状態でも動かせる
自社の業務のどこに当たるかを先に確かめてください。長い入力フォームの途中保存、倉庫や現場でのオフライン入力、ガントチャートやシフト表の並べ替え。これらに当てはまらない場合は、既存APIの再利用や画面間の状態維持も含めて利点を確認し、移行・保守費用に見合うかを判断してください。
SPA化の見送りを先に検討する業務システムの3条件
ここからは当社の設計判断です。次の3条件は、SPA化を見送る案から検討するための判断材料です。該当数だけで総コストは決まらないため、最終的には移行費・保守費・操作時間の削減効果を比べて決めます。画面の大半が一覧と帳票の閲覧で、更新操作が1日数回しか起きない。フロントエンドを継続して見る担当者が社内におらず、保守を都度発注している。法定帳票や監査証跡のように、印刷とPDF出力が主な出口になっている。
最後の条件は見落とされがちです。SPAはURLと描画結果の対応を自前で維持する構造なので、「この画面をそのまま印刷して保存する」要件が入ると、印刷用CSSと状態復元の作り込みが増えます。従来型でも、帳票の改ページ・余白・印刷対象の制御には印刷用CSSなどの実装が必要です。SPAでも従来型でも、帳票要件と画面状態の再現方法を分けて見積もります。
SPA化で表面化する落とし穴と実装上の対処
SPAはhistory.pushState()でアドレスバーのURLだけを書き換え、変わった領域のDOMだけを差し替えます。Googleの「JavaScript SEO の基本を理解する」も、クライアントサイドルーティングを使うSPAではフラグメント(#)ではなくHistory APIでビュー間のルーティングを実装するよう求めています。なお、利用者の操作と無関係に履歴を積み増す実装はGoogleのスパムポリシー違反になります。正当なルーティングとの線引きは戻るボタンの乗っ取りとは?Googleが2026年6月スパム認定した違反と対応チェックにまとめました。
History APIの後継にあたるNavigation APIは、MDN browser-compat-data 8.1.5の時点でChrome 102・Edge 102・Firefox 147・Safari 26.2に入り、主要エンジンが揃いました。下限を決めるときは本体ではなくintercept()で見てください。Chrome・Edgeでintercept()が入ったのは105です。リンク・フォーム送信・戻る/進むをnavigateイベント1か所で受け取れますが、アドレスバーへの入力やリロードボタンからの遷移ではイベント自体が発火しません。
navigation.addEventListener("navigate", function (event) {
if (!event.canIntercept) return;
if (event.hashChange || event.downloadRequest !== null || event.formData !== null) return;
const url = new URL(event.destination.url);
if (url.pathname !== "/orders" && url.pathname !== "/orders/") return;
event.intercept({
focusReset: "manual",
async handler() {
const res = await fetch("/api/orders" + url.search, { signal: event.signal });
if (!res.ok) throw new Error("HTTP " + res.status);
renderOrders(await res.json());
const heading = document.getElementById("page-heading");
heading.setAttribute("tabindex", "-1");
heading.focus();
}
});
});
受注一覧(/orders配下)への遷移だけを横取りし、APIからJSONを取って描画したあと、見出しへフォーカスを移す例です。focusResetの既定値はafter-transitionで、遷移後にautofocus属性を持つ最初の要素、無ければbodyへフォーカスが戻ります。自前で見出しへ移すならmanualで既定を切ってください。
認証トークン:localStorageへのセッション識別子保存の禁止
APIをJSONで呼ぶ構造になると、認証トークンをJavaScriptから読める場所に置きたくなります。OWASPのHTML5 Security Cheat Sheetはこれをはっきり否定し、「Do not store session identifiers in local storage as the data is always accessible by JavaScript.」と書いています。同じシートはsessionStorageとlocalStorageについて「A single Cross Site Scripting can be used to steal all the data in these objects」とも警告しており、XSSが1か所でも通ればWeb Storageの中身はまとめて持ち出されます。
緩和策として同シートが挙げるのはhttpOnly属性付きのCookieです。APIを同一サイト配下に置けば、SPAでもCookieベースの認証は成り立ちます。社内システムだから安全という理屈は通りません。
ルート変更時のフォーカス制御の欠落と支援技術への影響
SPAでURLとDOMだけを更新し、フォーカス移動や変更通知を実装しない場合、支援技術の利用者が画面変更に気づきにくくなります。キーボードで操作する人のフォーカスは前の画面の位置に残り、読み上げ環境の人は遷移そのものに気づかない。全社員が毎日使う社内システムでは、特定の職員だけが業務を終えられない状態になります。
対処は、ルート変更のたびに新しい画面の見出しへフォーカスを移すことです。見出し要素は既定ではフォーカスを受け取れないので、上のコードのようにtabindex="-1"を付けてからfocus()を呼びます。ルーティングライブラリを選ぶ段階で、この挙動が組み込まれているかを確かめておくと後戻りが減ります。
社外公開画面のクロール:soft 404とnoindexの置き方
顧客向けポータルや応募フォームのように社外に公開する画面では、検索エンジンへの見え方も問題になります。Googleの同ドキュメントによれば、ページはレンダリングのキューで「数秒間(またはそれ以上)」待つことがあります。存在しないIDのURLでも200を返して「該当データがありません」と描くだけのSPAはsoft 404として扱われるため、404を返すURLへリダイレクトするか、JavaScriptでnoindexを追加します。ただし「Google が noindex タグを検出した場合は、レンダリングと JavaScript の実行がスキップされる可能性があります」とあるとおり、初期HTMLにnoindexを置いてJavaScriptで外す実装は機能しません。レンダリング方式ごとの違いはレンダリングとは?ブラウザ描画の仕組みとCSR/SSR/SSGの違い・選定基準を解説で比較しています。
部分SPA化から始める移行の進め方
切り出す画面の優先順位:操作の往復回数と移行境界
最初に移す画面は、入力回数が多く、1回の作業で複数の項目を行き来する画面から選びます。受発注の入力、シフト表の編集、棚卸のように、従来型では「保存して一覧へ戻り、また開く」を繰り返している画面です。往復が減るぶん、作業完了までの時間短縮が数字に出やすい箇所でもあります。
月次帳票やマスタ参照の画面から移すと、工数をかけた割に何も変わらないという評価になります。移行順は業務のボリュームではなく、操作の往復回数で決めてください。GitHubの事例のとおり、行き来の多い画面群は同じ側(新か旧か)にまとめて移さないと、境界をまたぐたびにページ全体の読み込みが発生します。
旧画面との並行稼働:パス分割と機能フラグによる切り替え
部分SPA化では、旧画面とSPA画面がURL空間を共有します。境界の切り方は2通りあります。1つはSPAが受け持つパスをプレフィックスで固定し、それ以外は従来のサーバー側ルーティングへ通す方法です。
location /app/ {
try_files $uri $uri/ /app/index.html;
}
location /api/ {
proxy_pass http://backend:3000;
}
このNginx設定は、対応するファイルやディレクトリが存在しない場合にindex.htmlへフォールバックし、APIへのリクエストを別のプレフィックスでバックエンドへ転送します。末尾スラッシュ無しの/appは前方一致に入らないので、そこだけリダイレクトを1本足しておきます。もう1つが、freee販売のように同じURLのままサーバーが新旧どちらのHTMLを返すかを機能フラグで決める方法です。URLを変えずに画面単位で切り替えと切り戻しができる代わりに、出し分けの条件をサーバー側で管理し続ける必要があります。既存のURLを社外に配っている業務システムでは後者が向きます。新旧画面でCookieベースの認証セッションを共有する設計なら、Cookieのパス設定を両方が対象となる範囲にします。別ドメインや別の認証基盤を使う場合は、SSOなどの連携方法を別途設計します。
外注前に発注側が決めておく4項目
SPA化を外部に依頼する場合、見積もりを取る前に社内で確定させておく項目が4つあります。対象ブラウザーとバージョンの下限、SPA化する画面の一覧と残す画面の一覧、認証方式(Cookieかトークンか、SSOの有無)、移行前後で比べる性能指標です。
性能指標は「速くする」ではなく指標名まで決めます。初回表示はLCP、操作応答はINPで測り、同じ回線・同じ端末で比較します。SPA内の画面遷移は、計測環境のソフトナビゲーション対応を確認し、遷移開始から主要コンテンツ表示までの時間も別途測ります。ブラウザーの下限も年号ではなくバージョン番号で書いてください。「Chrome 105以上」と言えるかどうかで、使えるルーティング実装が変わります。提案を比べるときは、フレームワーク名ではなく「どの画面をどの順で移すか」の分割案が出ているかを見てください。当社でも既存システムのシステムマイグレーション・リプレイスとして、画面単位の段階移行を支援しています。フレームワークの現行版と選び方はSPAとは?開発言語・フレームワークの選び方とMPA・SSRとの違い【2026年10月】を参照してください。
よくある質問
SPAの使用例にはどんなサービスがありますか?
運営会社や命名者が一次情報で構成を説明している例は、Googleマップ・Gmail(2005年にAjaxアプリケーションとして名指し)、Twitter Lite(2017年・クライアント側JavaScriptと小さなNode.jsサーバー)、SpotifyのTV・ゲーム機向けアプリ(2019年・Web版のSPA)です。GitHubは2026年時点でRails描画のページとReactの画面が混在する移行途中にあります。業務SaaSではfreee販売・kintone・SmartHRが移行の記録を公開しています。
SPA化のメリットは何ですか?
Microsoft Learnが挙げる利点は、再読み込みなしの操作、バックグラウンドでのデータ取得、入力途中のフォームの保存、ドラッグアンドドロップの実装しやすさ、切断中も動いて後から同期できる設計の5つです。Twitter Liteのように、画面をAPIの上の薄いクライアントにすることでサーバー側の運用費が下がった例もあります。同じ画面で操作を繰り返す業務は有力な適用先ですが、既存APIの再利用やオフライン対応も採用理由になります。
SPA開発のデメリットは何ですか?
最初の1画面が重くなること、チームにJavaScript・TypeScriptの知識が必須になること、フレームワークの更新が頻繁で保守の手間が増えることです。実装面では、localStorageに置いた認証情報がXSSで盗まれる危険、遷移時にフォーカスが移らず支援技術の利用者が取り残される問題、社外公開画面でのsoft 404が起きやすくなります。閲覧が中心の画面ではSPA化は割に合いません。
SPA化とは何ですか?アパレル業界のSPAとは違うのですか?
別の言葉です。この記事で扱うSPA化は、Webアプリケーションを1枚のページの上でデータだけを差し替える構造へ作り替えることです。アパレル・小売の文脈のSPAはSpeciality store retailer of Private label Apparelの略で、企画から製造・販売までを自社で一貫させる製造小売業のビジネスモデルを指します。社内文書では「シングルページアプリケーション化」と書き分けると混同を防げます。
業務システムを全画面SPA化する必要はありますか?
ありません。Microsoft Learnは、大規模な従来のWebアプリケーションの中に1つ以上のSPAのようなサブアプリケーションを置くハイブリッド構成を「最も単純な」方法として挙げています。kintoneもfreee販売も画面単位で段階的に移しています。全画面を一度に置き換える計画は、切り戻し先がなくなるぶん失敗したときの影響が大きくなります。