Upgrade to Pro — share decks privately, control downloads, hide ads and more …

これがなかったらSPA開発詰む~13年前にSPAに挑んだエンジニアの屍~

 これがなかったらSPA開発詰む~13年前にSPAに挑んだエンジニアの屍~

7/24開催のReact Osakaで発表したReactをはじめとするSPAフレームワークの歴史に立脚して「これがなかったらSPA開発詰む」についてのスライドです。

Avatar for 落葉 剛

落葉 剛

July 25, 2026

Other Decks in Programming

Transcript

  1. REACT OSAKA 2026.07 ・ LT #react_osaka 1. つかみのつかみ:2016年、JavaScriptを学ぶということ ▹ 引用:Jose

    Aguinaga「How it feels to learn JavaScript in 2016」(2016年) ▹ 初心者「jQueryでデータ取って表示したいだけなんだけど」 ▹ ベテラン「2016年にjQuery? React + Babel + npm + Webpack + TypeScript…」 ▹ 初心者「……バックエンドに逃げます」 ▹ 現代のReact学習者の心の声:「なんでただのHello Worldにここまでせにゃならんのだ」 ▹ → それ、レジェンドの屍でできてます。 これがないとSPA開発は詰む! 01 / 15
  2. REACT OSAKA 2026.07 ・ LT #react_osaka 3. 掴み:Reactが生まれた、その月 ▹ 2013年5月29日

    — Reactがオープンソースで世に出た(JSConf US) – ※発表時、JSXは会場でブーイングされた(答えですら最初は拒絶された) ▹ 同じ月、私は素手でSPAに挑んでいた(それを知らずに) →案件期間は2013年5月~2014年1月 ▹ 対戦相手:IE8~10 / Android 4.2 標準ブラウザ / jQuery 1.9 ▹ 逃げ道その1:バックエンドは他社 → SSRが使えない ▹ 逃げ道その2:SPA向けの答え(Knockout 2010 / Backbone 2010)は3年前から海外にあった – でも私のレーダーに乗ったのはキックオフ後の2013年8月。海外動向を追わないSIerには届かなかった ▹ → 断片HTML(.html)をajaxで受け取り、手でDOMを組むしかない これがないとSPA開発は詰む! 03 / 15
  3. REACT OSAKA 2026.07 ・ LT #react_osaka 4. 全体像:私は「SPAフレームワーク」を丸ごと自作していた 手で作ったモンスター 正体(現代SPAの要素)

    断片HTML + DOM操作の描画エンジン 宣言的レンダリング 画面切替で append / 削除 ルーター .on() 魔改造 画面関数へのデータ流し込み get/set の一元管理回路 100本超の <script> を手で並べる コマ送りアニメ + GPU移譲 これがないとSPA開発は詰む! 合成イベント / 委譲 データバインディング 状態管理(← 今日の主役) モジュールシステム import(依存解決) アニメーション / パフォーマンス 04 / 15
  4. REACT OSAKA 2026.07 ・ LT #react_osaka 5. 速射モンスター(1)描画・ルーター・イベント・バインディング ▹ 描画エンジン:断片HTMLをDOM操作で置換/挿入/削除(=宣言的レンダリングの自作)

    ▹ ルーター:画面切替を認識して自動でappend/削除(テンプレエンジンと融合) – IE8に History API 無し → location.hash / hashchange と殴り合い(戻るボタンと血みどろ) ▹ .on() 魔改造:貼り直しても消えないよう自動re-attach…したかった ▹ データバインディング:画面ごとの関数内で変数を手でDOMに流し込む これがないとSPA開発は詰む! 05 / 15
  5. REACT OSAKA 2026.07 ・ LT #react_osaka 6. 速射モンスター(2)import が無い世界:100本超の <script>

    地獄 ▹ コード分割は やってた(画面ごとにJSファイルを分割) ▹ でも当時 import / モジュールシステムが無い → 依存解決は手作業 ▹ index.html に <script> が……200本? 300本?(多すぎて誰も数えなかった) ▹ 読み込み順を睨みながら手で並べる ▹ 合計 数百MB。体感、ほぼ1GB。 ▹ 専用Android端末のメーカーから真顔で一言:「これは端末負荷試験用のソースですか?」 これがないとSPA開発は詰む! 06 / 15
  6. REACT OSAKA 2026.07 ・ LT #react_osaka 7. 速射モンスター(3)コマ送りアニメと、CPUを救ったCSS3 ▹ 当時のjQueryアニメは貧弱

    → フレーム計算を手実装してリッチアニメを実現 ▹ 全部それでやると CPU資源が枯渇して死亡 ▹ 一部を まだピヨピヨのCSS3アニメでGPUに移譲 → CPU負荷を逃がす これがないとSPA開発は詰む! 07 / 15
  7. REACT OSAKA 2026.07 ・ LT #react_osaka 8. 事件:子供の「解答途中」が、消える ▹ 一時状態(アニメ進捗・問題の途中回答/進捗)はDBに持たない

    → JSの変数に保持 ▹ ある日、事件: – 「解いてる途中の解答が、一定確率で消える」 ▹ しかも——環境によって発生確率が違う ▹ (スコアはAPIサーバが握ってた → そこは無事) これがないとSPA開発は詰む! 08 / 15
  8. REACT OSAKA 2026.07 ・ LT #react_osaka 9. 探偵:なぜ環境で確率が違うのか ▹ まず、環境ごとに死に方が違った:

    – Windows Vista + IE9 → GC以前に、初期ロードで即クラッシュ(あの物量が牙をむいた) – Android 4.2 → 初期ロードは根性で耐えるも、アニメ超絶スロー+解答が消える ▹ 共通の元凶は メモリ ▹ 消えるデータ = どこからも参照されてない孤児 → GCが回収 ▹ 孤児が回収されるタイミングはエンジンごとにバラバラ → 逼迫した端末ほど即回収 → 消える確率が環境で違う ▹ 当時の私の診断:「ガベージコレクタの限界だ」 これがないとSPA開発は詰む! 09 / 15
  9. REACT OSAKA 2026.07 ・ LT #react_osaka 11. ウルトラC:GCから解答を守れ ▹ 対策:状態を

    get/setの回路で一元管理(Redis的なストア) ▹ さらに 定期アクセスで「お掃除」されないようキープ ▹ → 解答、消えなくなった。守り抜いた これがないとSPA開発は詰む! 11 / 15
  10. REACT OSAKA 2026.07 ・ LT #react_osaka 12. 答え合わせ(現代の視点で) ▹ ×

    GCの「限界」じゃない → GCは正しく仕事してた(孤児を掃除してただけ) ▹ ◦ 「環境で確率が違う」からGCタイミング差を見抜いた診断は 名探偵 ▹ 「定期アクセス」は要らなかった → 生きた参照を握れば、触らなくても残る ▹ ◎ 私が作った get/set 回路の正体 = 状態管理ストア(Redux/Zustandの祖先) これがないとSPA開発は詰む! 12 / 15
  11. REACT OSAKA 2026.07 ・ LT #react_osaka 13. 着地:これがないと、SPAは詰む ▹ タイトルの「これ」

    = 状態管理 ▹ 「消えてほしくない状態は、消えるものの外に置け」 ▹ = 現代の useState を上げる / store に置く(lifting state up) ▹ スコアはAPIが守った。でも子供の「途中」を守れるのは、フロントの自分だけ だった ▹ あなたの useState / store は、2013年に取締役に激詰めされた末の答え です これがないとSPA開発は詰む! 13 / 15
  12. REACT OSAKA 2026.07 ・ LT #react_osaka 13.5 レジェンドから、現代のReactへ物申す(おまけ・カット可) ▹ 問:useEffect

    は、誰の屍を拾ったのか? ▹ 答:私の屍(.on()魔改造=依存で再実行 / GC後始末=cleanup / 画面遷移でfetch) ▹ useEffect = 埋葬したはずの「命令的な副作用」の墓標。全部を一箇所に埋めた集合墓地 ▹ React自身が言ってる → 公式ページ You Might Not Need an Effect ▹ 隣のVueは同じ屍を弔い分けた: – 更新はリアクティビティが自動吸収(ref/computed/テンプレ)=effect不要 – mount/unmount はライフサイクルフック(onMounted/onUnmounted) – 独立した副作用関数(watchEffect)も一応いる。……でも主役じゃない ▹ 業界の潮流も signals(Vue型のきめ細かいリアクティビティ)へ:Solid / Svelte / Angular… ▹ ※useEffectも「外部システムとの同期」用途は正当。全否定ではない これがないとSPA開発は詰む! 14 / 15
  13. REACT OSAKA 2026.07 ・ LT #react_osaka 13.5 レジェンドから、現代のReactへ物申す(おまけ) ▹ 問:useEffect

    は、誰の屍を拾ったのか? ▹ 答:私の屍(.on()魔改造=依存で再実行 / GC後始末=cleanup / 画面遷移でfetch) ▹ useEffect = 埋葬したはずの「命令的な副作用」の墓標。全部を一箇所に埋めた集合墓地 ▹ React自身が言ってる → 公式ページ You Might Not Need an Effect ▹ 隣のVueは同じ屍を弔い分けた: – 更新はリアクティビティが自動吸収(ref/computed/テンプレ)=effect不要 – mount/unmount はライフサイクルフック(onMounted/onUnmounted) – 独立した副作用関数(watchEffect)も一応いる。……でも主役じゃない ▹ 業界の潮流も signals(Vue型のきめ細かいリアクティビティ)へ:Solid / Svelte / Angular… ▹ ※useEffectも「外部システムとの同期」用途は正当。全否定ではない これがないとSPA開発は詰む! 14 / 15
  14. REACT OSAKA 2026.07 ・ LT #react_osaka 14. 最後に:私が払った代償 ▹ 技術的に一番ヤバかった実装

    = 画像の暗号化・復号化(XOR、復号は自作) ▹ なのに——記憶がありません。実装が9ヶ月の最後の最後だったから ▹ 9ヶ月間、日付をまたぐ前に帰れた日はゼロ / 8日連続で会社に泊まり込み ▹ 行きつけのバーの夏のバカンスも、私の実装爆発で吹き飛んだ → そして記憶も飛んだ ▹ 手でSPAを殴る = 記憶を代償に払うこと ▹ ※これは武勇伝じゃない。警告です → だから、どうか フレームワークを使ってください これがないとSPA開発は詰む! 15 / 15