- 2010年代初頭の Backbone と 2025年の React を比較し、15年間のフロントエンドの発展が実際にどれほど進歩したのかを振り返る議論
- Reactは見た目には 簡潔でモダン だが、内部では複雑な 抽象化レイヤー によって単純さを装っている
- Backboneはコードこそ冗長だが、イベントの流れとDOM操作が明示的 で、初級開発者でも動作を追いやすい
- Reactは 状態管理、依存配列、クロージャの問題 などにより、内部動作を理解していないとデバッグが難しい構造
- 結局のところ「イベント + 状態 = UI」という本質をあらためて思い出させ、シンプルさとhackableな構造を備えた新しいモデルの必要性を提起する
15年間の進歩
- 一方は 2010年代のフレームワーク(Backbone)、もう一方は 10年以上発展してきたReact で書かれたパスワード入力欄の例
- 2つのコード実装は長さもほぼ同じで、機能も同一
- Reactは膨大な開発者の時間と巨大なエコシステムの支援を受けてきた
- しかし著者は「Reactがどれほど良くなったか」よりも、「どれほど進歩していないか」のほうが興味深いと指摘する
- Reactは 見かけ上の単純さという幻想 を与えるが、実際には複雑な抽象化のせいで理解の難易度が高い
- Backboneはイベント発生 → ハンドラ実行 → HTML生成 → DOM挿入という単純な流れを明示的に表現する
- 一方のReactは内部動作を隠しており、単純な例を超えると 内部メカニズムを理解しなければ解決できない問題 が発生する
単純さの幻想 (The Illusion of Simplicity)
- Reactはコードがきれいに見えるが、これは 明示的な単純さの代わりに抽象的な複雑さ を選んだ結果
- Backboneは冗長ではあるが、「何がいつ起きるのか」を明確に示す
- 初級開発者でもコードの流れを追いやすい
- Reactでは内部状態とレンダリングロジックが隠されているため、予期しないバグ が頻繁に起きる
- 例: リスト項目のkeyをインデックスに変えると、Reactが別のコンポーネントだと認識して状態を初期化する
value が undefined に変わると、非制御 → 制御コンポーネントへの切り替え によって入力値がリセットされる現象が起きる
useEffect 使用時に 無限ループ が生じる問題もよくある
- 依存配列にレンダーごとに新しく生成されるオブジェクトが含まれると、Reactはそれを変更とみなす
- これを防ぐために
useMemo、useCallback で 識別性を安定化(stabilize identities) する必要がある
- 以前は考えなくてもよかった概念に気を配らなければならない負担が生じる
- クリックハンドラが 古い状態(stale state) を参照する問題もある
- 関数が生成時点の状態をキャプチャするため
- 解決策は状態を依存配列に入れるか、
setState(x => x + 1) のような 関数型アップデート を使うこと
- しかしどちらの方法も その場しのぎ(workaround) のように感じられる
魔法の代償 (Magic Has a High Price)
- こうした問題は例外的な状況ではなく、中規模以上のアプリでよく起きる一般的な問題
- デバッグするには reconciliation algorithm、render phase、scheduler(batch update) の理解が必要
- Reactは「なぜ動くのかわからなくても動く」構造だが、問題が起きると内部を知らなければ解決できない
- 「Reactを本当に理解するには自分で作ってみるべきだ」と言われるほど複雑
- “Build your own React” のようなチュートリアルも存在する
- しかし単純な パスワードバリデータ を作るために、仮想DOM、スケジューリング優先度、同時レンダリングを理解しなければならないという点は 批判的な示唆 を含んでいる
- BackboneとjQueryは 正直でhackableな構造 を持つ
- ソースコードを直接見て修正できる
- DOMメソッドベースなので理解と拡張が容易
- 一方でReactの 抽象化レイヤー は内部へのアクセスや修正を難しくする
次の段階は何か (So, What's Next?)
- 結局、ReactとBackboneはいずれも 「イベント + 状態 = UI」 という同じ問題を解こうとする試み
- 大規模アプリではReactの複雑さが正当化されるかもしれないが、大半の中小規模アプリには過剰な負担 である
- シンプルさと透明性を備えた 新しいUIモデルが必要
- DOMのように堅牢でありながら直感的なシステム
- BackboneやjQueryのように、すぐ理解できて修正しやすい構造 を志向する
2件のコメント
中小規模のアプリでは、BackboneやjQueryよりもJavaScript Classを設計するほうが、次を見据えた姿勢になる気がします。
jQueryやBackboneにあるテンプレートをまた覚え直して進めるのは、退化のように感じます。
Hacker Newsのコメント
Backbone、Angular 1、Ember、React をすべて使ったことがある
React が人気を得た理由を見落としてはいけない。コンポーネント合成、イベント処理、状態管理、効率的な DOM 更新などの面で、React は既存フレームワークの慢性的な問題を解決した
Backbone は DOM のライフサイクル管理が複雑で、イベントハンドラを文字列で指定しなければならず、保守が難しかった。React は単方向の状態フローと仮想 DOM によって、こうした問題を単純化した
今なら素の JS を使いたいときは、Backbone より lit-html のようなテンプレートソリューションのほうがずっと良いと思う
フロントエンドは昔も複雑だったし今も複雑だが、今のほうがはるかに苦痛が少ない
アプリの複雑さはコンポーネント数ではなく、状態管理から生まれる
Backbone Store の双方向データフローのせいで UI が止まる問題をよく経験した。React の革新は 単方向データフロー を中心に据えた Flux アーキテクチャだった
良いフレームワークとは、「成功の罠(Pit of Success)」へ自然に導いてくれる道具だと思う。React はその役割をうまく果たしてきた
たとえば stale closure、無限 useEffect ループ、キー変更による入力初期化 のような問題は Backbone にはなかった
Backbone の問題は目に見えていてデバッグしやすかったが、React の問題は抽象化の裏に隠れている
ほとんどのアプリは Facebook 規模ではないので、明示的で単純なアプローチのほうがむしろ良いこともある
人気のある技術を「悪い」と断定するのは、一種の 素朴な傲慢さ に見える
もちろん人気が品質を保証するわけではないが、世界中の優秀なエンジニアたちがみな騙されたと考えるのは行き過ぎだ
大企業とマーケティングが後押しすれば CTO は採用し、キャリアがかかっていれば誰も「これは微妙だ」とは言わない。人気 ≠ 適合性だ
React が勝ったのは技術的優秀さだけではなく、Facebook のマーケティングと生態系の自己強化 のおかげでもあった
15 年経った今でもコードの長さや複雑さは大して減っていない。単に 別の形で複雑になっただけ だ
過去を振り返るのはノスタルジーのためではなく、私たちが 釣り合わない複雑さ を追加していないか点検するためだ
Web は今でも デザインパターンの西部開拓時代 のようなものだ。それを受け入れたら気が楽になった
結局のところ、プロジェクトごとに トレードオフを再評価 する必要がある
「簡単なことに React は不要だ」という主張は、ありがちな React の誤謬(React fallacy) だ
単純な例で React を評価するのは、「Hello World の長さで言語を評価する」ようなものだ
簡単なことにも React を使う理由は、複雑なことにも React を使うからだ。一貫したツールセット は保守に有利だ
Backbone は「フレームワークのように見えるが、実際には接着コードの塊」だった
React の本当の勝利は、DOM を直接操作する必要がなくなり、リアクティブな状態管理 が可能になった点だ。この二つが開発生産性を大きく高めた
昔のチュートリアルリンク、アーカイブ版
今は LLM がコードをどう理解するか により関心がある。JSX のような宣言的構文は LLM フレンドリーだ
ただ、useEffect 以降の React は 表現力と明示性 の面でむしろ曖昧になった気がする
React がなぜ人気を得たのかがよく表れている
React のコードは大半が 素の JS と HTML で、核となるのは
useStateひとつだけだ。直感的で、ドキュメントがなくても理解できるBackbone は
.space-y-2のような文字列セレクタに依存していて、保守が地獄だった。クラス名を一つ変えただけでアプリの半分が壊れるReact はこうした問題を構造的に解決した
Backbone のコードは「何がいつ起きるか」が明確だが、React は内部動作を理解する必要がある
私も React の動作タイミングを理解するために Dan Abramov の useEffect ガイド と Mark Erikson のブログ を何度も読んだ
Backbone のコードは 10 年後に見てもすぐ理解できた
6 年前にチームを Backbone から Angular に移した
Backbone は 直感的で魔法のない構造 なのでジュニアには良かったが、最終的には TypeScript と Angular のほうがより体系的だった
今は NG20 を使っていて満足している。いつかブラウザがもっと多くの機能を標準で提供するようになれば、また単純なやり方に戻れるかもしれない
私たちは常に 抽象化の上でプログラミング している
重要なのは、その抽象化が 複雑さに見合う生産性向上 をもたらすか、そして 信頼できるか ということだ
最悪の場合でもデバッグ可能であるべきだ
React の入力フィールドは Backbone より Undo 動作をより自然に処理 する
Backbone は 1 文字ずつ戻すが、React は単語単位で戻す