世界を動かす技術を、日本語で。

現代のCSSがSPAを終わらせる時が来た

2025年7月26日原文(jonoalderson.com)

概要

  • ネイティブCSSトランジション の登場により、SPA(Single Page Application)を選ぶ最大の理由が消滅
  • 多くのWebサイトが 本来不要な複雑さ をSPAで実装し、パフォーマンス低下を招く現状
  • View Transitions APISpeculation Rules など、モダンブラウザによる新機能の進化
  • SPAとMPA(Multi Page Application) のパフォーマンス比較で、MPAが圧倒的に優位
  • 本質的なWeb開発の指針は「 必要なものだけを使い、プラットフォームの力を活かす」こと

ネイティブCSSトランジションがSPAの優位性を無効化

  • 「アプリのような体験」 を求める声から、安易にSPAアーキテクチャを選択する傾向
  • 実際には、 SPAの導入理由は「滑らかなページ遷移」 のみが主な動機
  • しかし、 View Transitions API のようなネイティブ機能により、 JavaScript不要で滑らかな遷移 が実現可能
  • SPAでは、 本物の滑らかさではなく「シミュレーション」 に過ぎないケースが大半
  • 例:Next.jsやGatsbyなどのSPAは、 大量のJavaScript でネイティブ挙動を模倣

SPAの「滑らかさ」は幻想

  • SPAでよく見られる問題点
    • ページ遷移のローディング状態間のフェード
    • スクロール位置の復元失敗
    • フォーカス挙動の不一致
    • コンポーネント再ハイドレーションによる遅延
    • レイアウトシフトやスケルトン画面
    • 効果に見合わないパフォーマンス低下
  • SPAの本質は「ネイティブ機能の再発明」 であり、結果的に重く脆いUXに

Webプラットフォームの進化

  • Chromium系ブラウザ(Chrome, Edge等) で、 View Transitions API が利用可能
  • CSSのみでページ間アニメーション を実現
    • 例:@view-transition { navigation: auto; } などのシンプルな記述
  • 共通要素のアニメーション も、view-transition-name属性で簡単指定
  • JavaScriptドリブンなトランジション も、document.startViewTransitionで柔軟に対応可能

Speculation Rulesによる高速ナビゲーション

  • Speculation Rules で、ユーザーの行動を元に 事前プリロード・プリレンダ を自動化
    • 例:リンクにhoverやタッチした瞬間にページを先読み
  • 瞬時のページ遷移 を実現、ローディングスピナー不要
  • ただし、 ページが重いと逆効果 (無駄なCPU・バッテリー消費)

ブラウザの進化と「シンプルさ」への回帰

  • Back/Forward Cache(bfcache) など、ブラウザ標準の高速化機能が充実
  • SPAの設計パターン(クライアントサイドルーティング等)はbfcacheと相性が悪い
  • HTML+CSS中心のクリーンな実装 が、パフォーマンス・安定性・SEOで圧倒的有利

SPA vs MPA:パフォーマンス比較

  • SPA(Next.js等)
    • JSバンドル:1〜3MB
    • TTI(操作可能までの時間):3.5〜5秒
    • ルート遷移:シミュレーション
    • SEO:複雑・脆弱
    • スクロール/アンカー挙動:不安定
  • MPA + View Transitions + Speculation Rules
    • JSバンドル:0KB(必要時のみ追加)
    • TTI:約1秒
    • ルート遷移:ネイティブ
    • SEO:簡単・堅牢
    • スクロール/履歴処理:ブラウザ標準で完璧

本当に必要な「アプリ的」要素とは

  • 多くのWebサイトはアプリではなく、SPAの恩恵を受けない
    • 例:ECサイト、ドキュメント、マーケティングサイト、ブログ
  • シンプルな構造・高速なマークアップ・クリーンなURL が最優先
  • 必要な場合のみ最小限のインタラクションを追加 すれば十分

意図的な技術選定のすすめ

  • ReactやTailwind、Vite等の利用自体は否定しない
  • 「必要なものだけを必要な分だけ」 ブラウザに届ける設計が重要
  • HTML、CSS、ネイティブナビゲーションの活用 で、誰にとっても快適なWeb体験

2025年型Web開発の指針

  • SPAは一時的な制約の解決策だったが、今や不要
  • View Transitions APIによるネイティブなページ間遷移
  • Speculation Rulesによる瞬時のプリレンダナビゲーション
  • クリーンなマークアップと高速なロード、実URLの維持
  • 「プラットフォームの力を活かす」ことが最適解

まとめ:Webの本質に立ち返ろう

  • SPAで「滑らかさ」を追求するのは時代遅れ
  • モダンなサーバーレンダリング、CSSアニメーション、意図的なプリロード戦略 の組み合わせが最適
  • 不要なJavaScriptを減らし、2025年らしいWeb開発 を実践
  • ユーザーも開発者も、より速く・シンプルで・後悔の少ないWeb体験 を実現

Hackerたちの意見

SPAは、シームレスな遷移だけじゃなくて、クライアントサイドでのユーザージャーニーをたくさん詰め込むことも大事なんだよね。サーバーにあまり負担をかけずにね。例えば、2025年になっても、ほとんどのショップがフィルターを変えたり、カテゴリーを掘り下げるたびに完全にリロード(再取得)しなきゃいけないのが、俺の一番の不満なんだ。よくあるケースは、ショップに行って「本」をクリック(リクエスト)、次に「ファンタジー」サブセクションをクリック(別のリクエスト)、探してる本が実は「SF」だと気づいて戻る(リクエスト、キャッシュされてるといいな)そして「SF」に行く(またリクエスト)。ユーザーがカタログ全体をダウンロードして、サーバーに触れずにフィルターを適用できる方が、ずっと良いUXだよね。チェックアウトに行くまでサーバーに頼らなくて済むし。でも、データ量が多いって言うかもしれないけど、Amazonならともかく、ほとんどのショップのセクションは、1つの商品の写真より少ないキロバイトでそのパターンを実現できるデータに効率的に詰め込めるんだ。2005年頃からこんなウェブアプリを作ってきたけど、なんでもっと一般的じゃないのか理解できないよ。

HTMX(やそれに似たもの)は、これをたくさん解決してくれるんだ。今のSPAを使うと、フロントエンドとバックエンドの2つのアプリを作ることになることが多いんだよね。俺はサーバーサイドでたくさん作りたいし、クライアント側にはちょっとしたインタラクティブな要素(表示/非表示、折りたたみ/展開、エフェクト)を追加したいんだ。でも、SPAの必要性はまだあると思うよ。

うーん、フルリロードしなきゃいけないのが一番痛いのは、サイトの効率性だと思う。実際のデータは数KBだけど、ページ自体は100MBダウンロードしなきゃいけなくて、ウェブブラウザは1GBのRAMを消費してる。Hacker Newsのナビゲーションがひどいとは思わないけど、ほとんどのナビはリロードだよ。2008年の4GB RAMのノートPCでも問題なく動くし。でも、同じデバイスでDoorDashに行くと、50アイテムのリストを読み込むのに30秒かかる。ダブルダッシュのカウントダウンをくれるけど、カレーを注文して6パックのソーダを手に入れるのに3分以内は無理だと思う。2.5分は、インターフェースが表示されるのを待ってる時間だし、ほとんどがフルリロードじゃないんだ。

スパのバックスワイプを使うと、ほとんどの場合ページのトップに戻っちゃうんだよね。アプリから出て戻っても効果ないし、マルチページのスパを作るのって本当に難しい。

チェックボックスセレクターを使えばできるよ。例えば、[0]を見てみて。俺はフロントエンドはあんまりやらないから、ChatGPTにコードを振ってもらったんだけど、これがベストな方法かは分からないよ。[0] https://html-preview.github.io/?url=https://gist.githubuserc...

一般的に言って、企業はカタログ全体をダウンロードさせたくないんだ。競合他社が簡単に分析できるようになっちゃうからね。もし本を売ってる店なら、何十万冊もあるかもしれない。そんなのをクライアントに転送するのは良い体験じゃないし、それに伴う帯域幅やメモリの使用も考えると、あまり良くないよ。

そうなんだよね、これって貴重な反例だと思うんだけど、リンクをシフトクリックして新しいタブで開く時(これってみんながよくやることだよね)、マルチページアプリケーションだと追加の手間はゼロなんだよね。でも、SPAだとそれを管理しなきゃいけない。もしリンクが存在しなくて、カテゴリにアクセスするのがセレクト入力だけだったら、UXはあまり良くないよね。

SPAは、ユーザーがアプリ内で長時間セッションを持つときに意味があるんだ。大きなバンドルを読み込む苦労に対して、読み込み後は本当に小さなネットワークリクエストで済むからね。スムーズな遷移はいい副産物だけど、SPAの理由じゃない。この記事の核心的な主張、つまりクライアントサイドのルーティングがページ遷移の解決策だっていうのは、SPAが解決する問題を完全に誤解してるよ。だから、もしSPAの誤解を共有してて、間違った問題を解決するために使ってたら、この文章は100%正しいよ。でも、SPAはjQueryの時代に登場したもので、Reactの時代じゃないんだ。複雑なアプリを持っていて、大きなjQueryのスパゲッティを読み込んで、アプリの各divをそれぞれのミニアプリとして扱って、小さなネットワークリクエストで全てを同期させてた。これは、古いブラウザで遅い接続のユーザーがデータを変更するたびに、全てのコードをリロードしたくないという実際の問題を解決したんだ。jQueryのおかげでSPAが実現可能になったんだよ。その後、Reactや他のフレームワークがスパゲッティ感を減らして、実際に普及したんだ。時には怪しい理由でね。でも、SPAの最も強い主張は、キャッシュできる大きなコードバンドルを一度の読み込みで提供する解決策として使うことなんだ。ユーザーの期待されるセッション時間が長いときに、その複雑さの苦労をする価値があるからね。

たくさんの雑なjQueryモジュールが本当にSPAの viable optionだったかは分からないな。人々はそれを試みたけど、SPAの時代はbackbone.jsから始まったと言えるよ。

低帯域幅や不安定な接続(攻撃的なキャッシングと組み合わせて)は、SPAを支持する最も強い理由の一つだよ(アプリケーションのAに重点を置いて、ウェブサイトではなくね)。良好な接続があるときにアプリのフロントエンド全体を訪れて(キャッシュして)、その後のアプリの使用は最小限の帯域幅で進められるんだ。

これって本当?古いSPAって言うと、ブラウザで動くJavaアプリを思い浮かべるんだよね。それは確実にjQueryよりも古いよ。(この質問をダウンボートするためにこのサイトを使うの、なんか面白い。)

でっかいjQueryスパゲッティを読み込むって言ってるけど、俺は早い段階からスコープを制限するためにIIFEみたいなJSデザインパターンを使って、コードを整理して構造化するのに時間をかけたんだ。モジュールの遅延読み込みやミニファイもね。とにかく、俺の経験では、AngularJSが構造化されたフロントエンドアプリケーションを作るための最大の試みだったと思うし、Java開発者にはすごく受けてた(Angularは今でも人気らしいし)。モジュール化や依存性注入、テストのしやすさが大きなポイントだった。Backboneでアプリを始めたとき(FlexアプリをiPadで動かせなかったから)、機能の大半はバックエンドにあると思ってテストなんていらないって主張してたんだけど、間違ってた。後にAngularJSでの再構築はフロントエンドのテストがかなり重要になったよ。今では、現代のAngularコードの冗長さや複雑さ、間接的な感じにはうんざりしてる。Javaコードも同様だけどね。

Hacker Newsで議論の続きを見る