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

同じアプリを10回作成しました:モバイルパフォーマンスのためのフレームワーク評価

概要

  • モバイル性能重視 のフレームワーク選定の経緯
  • 主要10フレームワーク で同一機能のアプリを構築・比較
  • バンドルサイズとFCP で大きな差異を確認
  • MarkoやSolidStart など次世代型の優位性
  • ビジネス観点からも遅延は致命的 であることを強調

なぜこの検証を始めたか

  • 現場で使う不動産エージェント向け アプリのため、モバイル実用性が最重要要件
  • Next.js、SolidStart、SvelteKit で比較開始も、React系の根本的な限界に直面
  • VueやAngularも含めた主要フレームワーク全体 を検証対象に拡大
  • 同一機能・同一DB・同一UI で10種類のKanbanアプリを実装し、徹底比較
  • 単なる趣味ではなく、実務上の意思決定 として本気で性能を測定

主要な発見・結論

  • Marko, SolidStart, SvelteKit, Nuxt はFCP 35〜39msで「体感即時」表示
    • Next.jsは467ms、12〜13倍遅い
    • 次世代と旧世代の間に圧倒的な差
  • バンドルサイズ最小はMarko (88.8kB raw/28.8kB圧縮)、Next.jsの1/6.36
    • SolidStartも41.5kB圧縮で優秀
  • Qwik CityはResumabilityパターン で即時インタラクティブを実現
  • Nuxt(Vue3)は正しく設定すれば次世代並み性能 を達成
  • React・Angularは根本的に性能上限あり
    • TanStack Start(React19)はNext.jsより1.5倍マシだが、Solid版の2倍サイズ
    • Analog(Angular20)はさらに重い
  • MPA型(Marko, HTMX)はページごとに最小のJS出荷
    • SPA型は初回でルーティング等も含めて多めに出荷、コード分割してもベースが重い

モバイルWeb性能が重要な理由

  • モバイルWebは世界の主流。URLがあれば、必ずスマホでアクセスされる現実
  • 30kB vs 170kBの違い は「見た目の良さ」や「信頼感」まで直結
  • 遅い=ユーザー離脱率28% (ダウンタイムの3倍以上、SpeedCurve調査)
  • 遅延はブランドイメージ全体を損なう。単なる数値ではなく心理的ダメージも大
  • 実測で113kB差=3Gで1.5〜2秒遅延。キャッシュもデプロイごとに無効化され現実的には毎回ダウンロード発生

実験のセットアップ

  • 10フレームワークで同一Kanbanアプリ を実装
    • Next.js 16 (React19)
    • TanStack Start (React19)
    • TanStack Start + Solid (SolidJS 1.9)
    • Nuxt 4 (Vue3)
    • Analog (Angular20)
    • Marko (@marko/run)
    • SolidStart (SolidJS 1.9)
    • SvelteKit (Svelte5)
    • Qwik City
    • Astro + HTMX
  • 全て同じ機能・同じDB(SQLite+Drizzle ORM)・同じUI(Tailwind CSS+DaisyUI)
  • 全実装で約17コンポーネント、CRUD・ドラッグ&ドロップ・コメント・タグ管理・サーバーサイドバリデーション等を網羅
  • 依存ライブラリは極力最小限 (ドラッグ&ドロップなど必要最小限のみ)

レベル別Webアプリ設計の示唆

  • 本記事はLevel 5(高度なクライアント状態管理やナビゲーションが必要な場合)向け
  • 実はLevel 3(HTMXやバニラJS強化のサーバーレンダリング)やLevel 4(Lit等Web Components追加)で十分なケースが多い
  • シンプルな設計ほどバンドルも小さく、保守性も高い

まとめ・重要ポイント

  • フレームワーク選択=ビジネスインパクト。特にモバイルでは1kBごとに体感が変わる
  • React/Angularは根本的なアーキテクチャの壁 があり、今後も劇的な改善は難しい
  • Marko, SolidStart, SvelteKit, Nuxt 等の新世代フレームワークが「即時表示・軽量」を両立
  • Vue(Nuxt)は設定次第で新世代に食い込む が、React/Angularは脱落
  • 現実のプロダクションアプリは依存追加で5〜10倍重くなる ため、フレームワーク選定時の差はさらに拡大
  • モバイルWeb最適化=全ユーザー体験の底上げ。デスクトップ最適化ではモバイル利用者が必ず犠牲になる

この知見が、フレームワーク選定やアーキテクチャ設計時の指針となることを願います。

Hackerたちの意見

Svelteを実際のプロダクションアプリケーションで使っている者として、Svelteに関する彼らの推奨には100%同意します。全体的な開発体験が他に比べて圧倒的に良いです。なんか、直感的に「これだ!」って感じ。簡単でシンプル。パフォーマンスの面も考慮に入れてないけど、それもまた利点の一つです。よくゲームの難易度に例えますが、Svelte/SvelteKitは「イージーモード」で動いている感じです。同じ結果を得られて、精神的にも余裕が保てるし、髪の毛も残せます。

Svelteのカスタムエレメント(ウェブコンポーネント)を使って、既存の.net / alpine.jsサイトにスロットインするコンポーネントを作ってます。すごく良い開発体験で、ポータブルなコンポーネントができました。それぞれのコンポーネントは独自のバンドルになっていて(別々のvite設定を使って実現)、コンポーネントのグループをまとめてバンドルすることもできます。ツールセクションにある各ツールはSvelteのカスタムエレメントです。https://www.appsoftware.com/tools/utilities/calculators

僕はVueを選ぶかな。お金ももらえるし、でも仕事の面ではReactが王様だね。趣味の範囲でやるなら、liveviewやdatastarとか、面白いものがいっぱいあるから、結構楽しめるよ。Reactはシンプルでいいと思うし、だから僕みたいな普通の開発者も楽しめるんだよね。

Next.jsを使い続けるつもりです。なぜなら、それがSaaSベンダーが拡張SDKでサポートしているもので、エコシステムを構築するよりも他にやるべきことがたくさんあるからです。こういう制約がない人には代替案が素晴らしいと思いますが、そうでなければ、最小限のJavaScriptで伝統的なJavaや.NETフレームワークを使いたいです。

投稿の内容は一旦置いといて(個人的には素晴らしかったけど)、ここの文章のクオリティはすごいね。根本的にはドライな技術的なトピックなのに、そのレポートを全部読むのが楽しかった。期待以上に情報量があって、しかも面白かった。読むのが楽しいって最高だね。

うーん、同じ文が何度も繰り返されているのを見つけたよ。時々、読むのがちょっと変だった。

これはただの悪い文章じゃなくて、ChatGPTでごまかしたゴミだよ。でも内容自体も同じで、ビジネスが同じアプリを10回も作らせるなんてありえない。特にカンバンボードみたいなつまらないもので。

これはハードコーディングされた配列のtodoリストじゃない。データベースの永続性、複雑な状態管理、実際の製品のために構築するようなインタラクションを持つ本物のアプリだ。チャットGPTにレイアウトを修正してもらって、このメッセージのすぐ上にあるテーブルが横スクロールなしで完全に見えるようにできる?

うん、残念ながらこの文章は明らかにChatGPTのスラップだね。編集:関連する投稿がフロントページにあるよ。https://news.ycombinator.com/item?id=45722069

それにしても > これは単なる不便ではない。これはテクノフェーダリズムだ。この記事にはこういうのがたくさんあるね。まるで顔に唾を吐かれたような感じ。

我々の小さな会社では、コアアプリケーションを再構築する際に、どの大手が未来に賭けるべきかを決めるために、いつもの候補をレビューしました。最終的にVueとSvelteで悩んで、Vue/Nuxtに決めました。私たちには最も直感的な構文だと思ったし、技術的に見ても最も良い軌道に乗っているように感じました。それから1年経ちましたが、思ったほど進んでいないけど、少なくともReactよりはVue/Nuxtの方が良い選択だと思います。この記事もそれを支持しているようです。また、私は(大きなLLMの助けを借りて)レビューを行い、彼らもVueがエージェント的なコーディングアシスタンスに最適な構文とパターンを持っていると同意しているようです。「ファーストコンテンツフルペイント」や「サイズ」に関する勝利は最も重要ではありません。私たちはVueコミュニティをもっと信頼しています。Reactは膨れ上がった官僚的な混乱を引き起こすレシピのように思えます。Svelteもまだ強力な候補に見えますが、私たちはVueのコアチームがとても好きで、ほとんどの人がVue/Nuxtの構文やパターンを楽しんでいます。

Vueの大きな利点は、オプションとコンポジションAPIがあることだね。一つが使いにくかったら、もう一つを試せるから。Vueから他のフレームワークに移ろうとしたこともあるけど、どれも状態管理やリアクティビティ、モジュール性をこんなに簡単に扱えるものはなかった。結局、いつも戻ってきちゃうんだよね。

Vueの方がいいけど、もう3年以上も死んでるのが問題だね。

いい記事だね。特にモバイルに焦点を当てているのがありがたい。モバイルはしばしば見落とされがちだけど、ウェブにアクセスするデバイスとしては圧倒的に多いからね。スマホの現実は厳しくて、SPAスタイルのアーキテクチャで多くのユーザーに良い体験を提供するのはかなり難しい。「遅さはすべてを毒する。」その通り。ユーザーがシステムを使うのに苦労して、コンテンツが読み込まれるのを待っていたり、ボタンが反応するのを待ちながらイライラしているのを見るのほど、衝撃的なことはないよね。P75やP90のデバイス向けにエンジニアリングするのは、フレームワークがデフォルトで提供する以上の努力が必要だと思う。フレームワーク側からもっとこの点に焦点を当ててほしいな。Vueでも、比較的良さそうに見えるのに、 decentな結果を得るためにフレームワークと戦わなきゃいけない気がすることが多いから。

すごく良い記事だね。私の専門分野ではないけど、この分野で働いている人には非常に役立つはず。 > 「誰かが潜在的な買い手の前でプロフェッショナルに見せようとしているとき、遅いアプリは単なる迷惑ではなく、リスクになる。」これを読んで良かった。実際、こんな風に考える開発者が少ないのは驚きだよね。 > モバイルはウェブだ。だからなんだよね。コンピュータを持っていない人がたくさんいるけど、高価なスマホを持っている人も多い。だから、大きなPCディスプレイには頼れないけど、 decentなサイズの小さな画面は期待できる。私のアプリやサイトが高品質な小さな画面でうまく動くようにすることを学んだよ(本当に小さな画面で動かすのとは違うけどね)。主な注意点は、ネットワーク接続の質だね。接続が不安定なときでも、ちゃんと動くようにしないといけないと思う。

「誰かが潜在的な買い手の前でプロフェッショナルに見せようとしているとき、遅いアプリは単なる迷惑ではなく、リスクになる。」私も開発者として、後にマネージャーとしてその経験がある。ここでローカルミニマにハマらないように本当に気をつけないといけない。ほとんどの場合、勝つのはバンドルサイズではなく、オフラインでも優雅に動作するアプリをエンジニアリングすることだよ。ユーザーが手動でデータを事前に読み込むか、良いキャッシュにフォールバックすることでね。

新しいプロジェクトを始める前は、いつもこうやってリサーチして新しいことを試してたんだけど、最近は何があるか見るのをやめちゃった。Django/React(vite)に落ち着いたんだ。この組み合わせをマスターして、アイデアからアプリを実稼働させるまで数時間でできるようになった。もっと良くて早くて現代的な代替があるのは知ってるけど、もう気にしなくなっちゃった。もしかしたら、ウェブフレームワークに対して疲れちゃったのかも。別のことを学ぶ方が、また別のウェブフレームワークのドキュメントを読むよりもいいかな。

正直なところ、アプリがめちゃくちゃ複雑なことをしていなければ、最も遅いスタックでも大抵の人には十分早いと思うよ。あまり心配しなくてもいいんじゃないかな。個人的な効率の方が、ほとんどの場合はずっと重要だと思う。

代わりに言ってあげるよ:もうどうでもよくなったんだよね。終わらないから。本当に。

もしかしたら、ウェブフレームワークに疲れちゃったのかも。結局、ウェブ開発には新しいものがたくさん出てきたけど、今のやり方を続けてるからって何かを逃してるわけじゃない。個人的には、成熟したバックエンドフレームワーク(だいたいLaravelかDjango)を使って、フロントエンドは最小限のJSでやるのが好きなんだ。新しいライブラリもいろいろ試したけど、切り替える理由があまり見つからなかったな。

この記事を信じるなら、Reactは(相対的に)大惨事だね。誰か理由を説明してくれない?他の抽象化と比べて、Reactがそんなに遅くて大きい理由は何なの?

現時点でReactのパフォーマンスが(相対的に)ひどいってのはかなり確立された事実だね。Reactが成功してるのは、優れた技術だからじゃなくて、劣った技術にもかかわらず成功してるんだ。非常に確立された技術に勝つのは本当に難しいし、Reactは巨大なエコシステムを持ってるから、多くの企業がそれに依存してる。だから、関連する仕事もたくさんあるしね。遅い理由については、私の知識は最新じゃないけど(最近のアップデートにはあまり追いついてない)、一般的な考え方はこうだよ:

  • Reactのランタイム自体が40kBだから、何かをする前に(CSRでレンダリングする前やSSRでハイドレートする前に)ランタイムをまずダウンロードしないといけない。
  • ほとんどのフレームワークは、状態更新を管理するためにシグナルを使うようになってる。状態が変わると、その状態のオブザーバーが通知されて、DOMを手術的に更新する前に最小限のコードが実行される。Reactは代わりに、コンポーネントツリー全体のコードを再実行して、結果を現在のDOMと比較してから変更を適用する。これはもっと多くの作業で、かなり遅いんだ。時間が経つにつれて、Reactではこれを軽減するための技術(メモ化、Reactコンパイラなど)が開発されてきたけど、それでも必要以上に多くの作業をしてるし、他のフレームワークではデフォルトで少ない作業で済むから、これらの技術はあまり必要ないことが多い。興味があれば、js-framework-benchmark [1]がChromeのリリースごとに数百のフレームワークをテストしたベンチマークを公開してるよ。

SpeedCurveに言及すると、彼らのホームページにはスキップリンクがあるけど、id="main"は見つからなかった。