はじめに
この記事は グロースエクスパートナーズ Advent Calendar 2025 の5日目です。
アドベントカレンダー特別企画として、古くからJavaScriptに携わってきた弊社のテクニカルフェロー北條さんとの座談会を実施しました。
座談会では、北條さんが歩んできたJavaScriptの歴史を紐解くべく、色々な質問をぶつけてみました。約120分のロングセッションのエッセンスをQ&A形式でお届けします。
ボリュームが多いため、3回に分割してお送りします!
対談相手の北條さん
北條さんは以下のような経歴を持つ、グロースエクスパートナーズのテクニカルフェローです:
- グロースエクスパートナーズにおけるテクニカルフェローかつ最古参エンジニアの一人
- C++を「母国語」と呼ぶ低レイヤ出身のエンジニア
- JavaScriptはC++の次に大好きな言語
- 学生時代にデジタル回路設計からソフトウェアに転向し、アセンブラで鍛えた速度感とハードウェア視点を武器に活動
- 学生時代から憧れたEmacsを今も使い続ける筋金入りのUNIX文化の継承者
- IE地獄やRhino時代のサーバーサイドJavaScriptにも深く関わってきた「歩くJS史」
1. IE6地獄とメモリリークとの戦い
👤 司会:
北條さんは、悪名高きInternet Explorer 6(以下、IE6)の時代にもJavaScriptで開発されていましたよね。その頃のエピソードについてお聞かせください。
💡 北條:
今振っていただいたIE6時代のJavaScriptですが、まず言語仕様もひどくて、Javaみたいな見た目なんですけども、おまじないをあちこちに書かないとちゃんと動かないとか、こういう順番でやるとバグが出るとか、地雷が非常にたくさんあって気を使う言語でした。
IE6で忘れられないのは、結構大型の案件で、IE6のJavaScriptでクライアント側を実装した時のことです。当時Ajaxという言葉が出始めるか出始めないかくらいの頃だったと思うんですけど、フロントエンド・チームが凄く頑張ってAjaxを積極的に使った当時としては超先進的で規模の大きなアプリケーションがありました。そのWebアプリがメモリリークで、3ページくらい進むとすぐ固まってしまって使えないということで、なんとかしてほしいと言われました。なぜか僕一人だけがそこにいて、メモリリークを直すという作業をすることになりました。
当時はPrototype.jsというのがあって、それを使って実装されていました。IE6のJavaScriptエンジンがどういうふうにメモリ管理をしているか、あとは品質の低い製品によく見られるパターンに沿っているんだろうなという気はしていて、それを主軸にメモリリークする箇所を絞り込んでいきました。
ブラウザの中でメモリリークしているので、ブラウザの中の例えばスタックの状態とか、スレッドが何本立っているかとか、そういう細かいことはわかりません(注:当時はブラウザに開発者ツールがなかった!)。そこで、外部からアプリケーションのメモリ消費量の増加具合がわかるようなツール——Microsoft社製だと思いますが、無料で配っているツールがあったので——それでIE6のプロセスのメモリが増加する様子を見ながら直すというのをやりましたね。
この時役に立ったのは、プログラミング言語がどういうふうに実装されていて、どういうテクニックが使われているのかという知識です。IE6だとガベージコレクターですね。当時のIE6のJavaScriptエンジンは参照カウント方式のガーベージコレクターを採用していたと思うんですけども、参照カウント方式でよくミスしてしまいそうなパターンでメモリリークが出ているんだろうなと考えて、いくつか実験したところ、3〜4種類ぐらいのパターンでメモリリークすることがわかりました。それをPrototype.js自身も踏んじゃっていたし、アプリケーションの方も結構踏んでいたので、そういうところを直していきました。
ちなみに、元々1週間の予定で組まれていたのが、アプリケーションの実装が一定の規約に沿って整然と実装された事にも助けられ丁寧に作業していったら3日で解決してしまったんですね。これ多分、お客様側のプロマネとしては、「エンジニアを1週間貼り付けても駄目だったんだから、メモリリークは勘弁してくださいね」っていうシナリオでやっていたと思うんですけど、3日目に「メモリリーク治りました」って言ったら、結構びっくりしてましたね。その外部からプロセスの利用メモリを観察する——OSとのやり取りをトラップして見ているツールなんですけども——それがメモリの増加を報告しなくなったので。びっくりして喜んでいたんじゃなくて、「治っちゃったの!?」っていう感じで、そういう予定ではなかったみたいです。まるで狐に摘まれたかのような顔をしていたのが印象に残っています。まあ、そんな時代でしたね。
👤 司会:
座談会に向けて少し調べてみたのですが、本当に当時の開発者の悪夢みたいな話が大量に出てきて、びっくりした次第です。
私が中学生ぐらいの頃を思い出すと、IEを使っているとしょっちゅうブラウザの画面が真っ白になるようなことがあったんですが、あれがメモリリークということなんですか?
💡 北條:
一概には言えないですね。もっとやばいバグもたくさんIE6にはあり、相当な恨みを買ったブラウザだと思います。弊社で当時よくフロントを実装していたKさんとか、結構IE6に泣かされた経験がいろいろあるんじゃないかなと思います。それこそ開発者ツールも、IE6にはありませんでした。やっぱりChromeとかFirefoxにデバッグツールみたいなのがついた時には、かなり楽になりました。普通のプログラミング言語だと、やっぱりデバッガーっていうのは、概ね最初からついているものですからね。
その時のECMAScript的には、ES3より前なんじゃないかな。まあすごく混乱していた状態の頃だと思いますね。だから、そのIE6でメモリリークを直したアプリケーションはIE6じゃないと、多分絶対に動かないような状況ですね。このブラウザの、こういうコードはサポートされている、されていないっていうのがきちんと定まっていなかった。物好きな人は調べて、これは書ける、書けない、こうなる、こうするとこうなっちゃうとかっていうのがブログに書かれている程度だと思います。
👤 司会:
IE6用の黒魔術がいろいろあったみたいな話もあるみたいで。
💡 北條:
はい。まあ、他のブラウザもみんな黒魔術があったんですけど、IE6は特にひどかったですね。
外部のツールを使ってメモリリークの原因を探ったと言いましたが、当時は他に頼れるものは何もなかったのです。
🗣️ ちょっと脱線:ベテランたちから届いた声
座談会後に、当時を知るベテラン勢から以下の声が届きました!当時のフロントエンドは本当に大変だったのですね・・。
😰 「IEの非互換のために徹夜しましたよね」
😌 「いまとなっては良い思い出のつらい日々を思い出しました」
💣 「今思い返すと、地雷原で寝起きするような状態でした」
2. 「母国語はC++」— 言語設計を見抜く力
👤 司会:
北條さんは、大学時代からデジタル回路といった低レイヤーの世界も触ってこられて、ハードウェアへの理解もあるとのことです。今伺ったIE6のメモリリーク解決についても、そのような知見が結構生きたということなのでしょうか?
💡 北條:
いえ、そのIE6のメモリリークの件は、ハードウェアの知識は必要ない範囲ではあります。ただ、よく子供の頃から機械ものが大好きで、時計を分解して元に戻せなくて親に怒られるっていうパターンの育ち方をしているので、エンジニアとして、プログラミングもゲームもいろんなものがやっぱり好きでした。
よく私は「母国語はC++です」っていう話をするんですけども、C++はかなり早い時期から使っていたというのと、C++の哲学みたいなのがすごく好きなので、ずっと他の言語をやるときも、基本的に「やっぱりC++で言うところのこういう話なんだな」っていう解釈の仕方をするおかげで、いろんな言語の仕組みに興味が持てるところがあるので、そういう意味で母国語ですね。
例えばJavaだとか、Pythonだとか、今だとRubyとか、Perl、PHP、LISP系も、ClojureっていうJVMで動くやつもあるし、Scheme、Common Lisp、Emacs Lisp、あと、皆さん知らないと思うんですが、AutoLISPっていう、AutoCADっていうCADソフトウェアで使えるLISPがあるんですよ。そういうのも全部見てきました。あと、ErlangとかEiffelとか。プログラミング言語って時々話題になるタイミングが必ずあるんですね。
そうすると、「その言語がどういうところでもてはやされているのか?」とか、母国語のC++に照らし合わせてどういう言語機能があって、プログラミング言語の設計上、選択しなきゃいけないことがいろいろあるんですけども、それはどのスタイルを取っているのかなとか考えるわけです。
最近だと、Rustっていうのは、いよいよC++に息の根を止めに来た言語なんですけど、例えばRustがメモリマネジメントのところをどういうふうに見ているのか——これ、Rustの一番の特徴部分なんですけど——それがどういうモデルで設計されていて、どう実装されているのかとか。あと、RustはOOP(オブジェクト指向プログラミング)が一応できることにはなっているんですけども、いわゆるJavaとかの普通のオブジェクト指向言語から見るとできない、できそうにないことが非常にたくさんあって。昔のオブジェクト指向言語でおまけ的についていたトレイトっていうやつを、もうメインで使っていますっていう特徴があったりとか。
そういうのを見て、プログラミングで、どういう時にどういうふうに書けるのかを理解したり、その時に、どういう性能上だったり、安定性の上で問題になるような実装が使われるのかを考えるのがとても好きです。
Rustとフロントエンド開発の深いつながり
北條さんが「C++に息の根を止めに来た言語」と表現したRustは、実はJavaScript/フロントエンド開発者にとっても無関係ではありません。
- フロントエンドツールチェーンの高速化: SWC(Babelの代替)、Turbopack、Biome(Rome後継)など、近年のJavaScriptビルドツールやリンターの一部の主要ツールがRust 製に置き換わりつつあり、劇的な高速化を実現しています。
- WebAssemblyのエコシステム: RustはWebAssemblyと極めて相性がよく、WebAssemblyの最重要言語の一つです。
- ランタイムの進化: DenoはRustで実装されたJavaScript/TypeScriptランタイムで、V8の周辺をRustでラップすることで、権限管理などを備えたセキュアな実行環境を提供しています。
「メモリ安全性を言語レベルで保証しながらC++並みの性能」というRustの特性が、JavaScriptエコシステムの次世代インフラを支えているのです。
📅 JavaScript技術年表 — 本記事で登場した技術たち
※ 本年表はインタビュー内容の理解を助けるための参考情報です。詳細な歴史については公式ドキュメントや一次資料をご参照ください。
本記事で北條さんが言及した技術について、歴史的な背景をまとめました。
ECMAScript (ES1)
| 項目 | 内容 |
|---|---|
| 登場年 | 1997年6月 |
| 開発者・組織 | Ecma International / TC39 |
| 思想背景(何のために作られた技術なのか) | JavaScriptが急速に普及するなか、NetscapeのJavaScriptとMicrosoftのJScriptが互換性のない形で独自進化し始めた。動作がブラウザごとに異なる状況が広がり、Web全体の信頼性が揺らぎ始めたため、両社を含むベンダーがECMAに集まり、言語仕様を統一する必要が生じた。こうして、共通基盤としてのECMAScript(ES1)が策定された。 |
| 解決した課題 | JavaScript/JScript など既存実装で共通して利用されていた基本的な構文、データ型、組み込みオブジェクト(Object・Array・Function など)を、言語のコア仕様として整理・文書化した。これにより、ブラウザ実装が依拠すべき最低限の振る舞いが統一的に定義された。 |
| 現在の位置づけ | 歴史的な初版仕様。後続の ES3・ES5・ES6(ES2015)以降の流れの出発点であり、現代JavaScriptの基礎を形作った。 |
| 影響を与えたもの | JavaScriptをWeb技術として正式に標準化する基盤を提供し、ブラウザベンダー間の互換性維持の指針となった。その後のES3による機能拡張や、Ajax時代・モダンフレームワーク時代の発展へとつながる土台となった。 |
ECMAScript 3 (ES3)
| 項目 | 内容 |
|---|---|
| 登場年 | 1999年12月 |
| 開発者・組織 | Ecma International / TC39 |
| 思想背景(何のために作られた技術なのか) | ES1の後、Webはフォーム入力やアプリケーション的な利用が増え、JavaScriptにも例外処理・正規表現などの安定した機能が求められるようになった。一方で、主要ブラウザの実装には依然として差異が残り、既存の互換性も考慮する必要があった。これらの要件を踏まえ、標準化委員会(TC39)では大規模な仕様変更を避けつつ、実務利用に耐える最小限の改善を加えた統一仕様として ES3がまとめられた。 |
| 当初の目的 | JavaScriptの言語仕様を標準化し、ブラウザ間の互換性を確保 |
| 解決した課題 | 正規表現、try/catch、より厳密な文字列処理などを標準化 |
| 現在の位置づけ | ES5(2009年)、ES6(2015年)を経て、現在は毎年更新されるES20XX体制 |
| 影響を与えたもの | 10年間「最新仕様」として君臨し、IE6〜8時代のJavaScriptの基盤となった |
ES3からES5までの「失われた10年」
北條さんが「ES3より前なんじゃないかな」と語るように、2000年代前半のJavaScriptは標準化が混乱していました。ES4は野心的すぎて頓挫し、ES3(1999年)からES5(2009年)まで10年もの空白期間が生まれました。この間、各ブラウザは独自拡張を進め、開発者は互換性地獄に苦しむことになりました。
XMLHttpRequest / Ajax
| 項目 | 内容 |
|---|---|
| 登場年 | 1999年(Internet Explorer 5に実装)/ 2005年頃「Ajax」として注目 |
| 開発者・組織 | Microsoft(ActiveXオブジェクトとして実装した) |
| 思想背景(何のために作られた技術なのか) | デスクトップアプリのように滑らかに動くWebメール/業務アプリを実現するため、ページ全体を再読込せずにサーバーと対話したいという要請が高まっていた。 |
| 当初の目的 | OutlookのWeb版でページ遷移なしでサーバーと非同期通信を行う |
| 解決した課題 | フォーム送信やリンククリックのたびにページ全体をリロードする必要があった |
| 現在の位置づけ |
fetch() APIに主役の座を譲りつつも、レガシーコードでは現役 |
| 影響を与えたもの | Gmail、Google Maps(2004-2005)の登場で「Ajax」という概念が確立。SPAの礎を築いた |
「Ajax」という名前の由来
2005年に登場したGoogle MapsやGmailは、XMLHttpRequestを利用した革新的なUIを実現しました。これについてUXデザイナーのJesse James Garrettは「Ajax: A New Approach to Web Applications」という記事を公開し、「ページ遷移なし、非同期でのデータ取得、JavaScriptによる画面描画」という手法を「Asynchronous JavaScript and XML」の頭文字をとったAjaxと名付けました
Internet Explorer 6 (IE6)
| 項目 | 内容 |
|---|---|
| 登場年 | 2001年 |
| 開発者・組織 | Microsoft |
| 思想背景(何のために作られた技術なのか) | Windows XPと密結合したブラウジング体験を提供し、ActiveXや独自機能で企業システムをWindows陣営に囲い込むというプラットフォーム戦略があった。 |
| 当初の目的 | Windows XPの標準ブラウザとして、Webブラウジング体験を提供 |
| 解決した課題 | 当時としては高機能なCSS対応、XMLサポートなど |
| 現在の位置づけ | 2014年にサポート終了。Web開発者にとっては「悪夢の象徴」として語り継がれる |
| 影響を与えたもの | 独自実装の乱立が標準化の重要性を痛感させ、後のWeb標準化運動を加速させた |
IE6が「悪夢」と呼ばれる理由
北條さんが「相当な恨みを買ったブラウザ」と表現するIE6。その悪名高さの理由は:
- 独自実装の嵐: CSSボックスモデルの解釈違い、PNG透過非対応など
- 開発者ツール皆無: デバッグはalert()頼み
- 長すぎた寿命: 2001年リリース後、IE7まで5年以上も「最新版」として君臨
- 仕様が謎: 仕様や動作に不可解なところが多く、何が正しいのか全く分からないという恐怖と背中合わせだった。
皮肉にも、IE6の問題点が「ブラウザ間の互換性」「Web標準」の重要性を世界に知らしめました。
Prototype.js (Prototype JavaScript Framework)
| 項目 | 内容 |
|---|---|
| 登場年 | 2005年2月 |
| 開発者 | Sam Stephenson(Ruby on Railsコミュニティ出身) |
| 思想背景(何のために作られた技術なのか) | 当時は標準化された高階関数や統一的なDOM APIがなかったため、それらを補完するユーティリティ群を提供するアプローチが求められていた。 |
| 当初の目的 | Ruby on RailsのAjaxヘルパーとして、JavaScriptをより書きやすくする |
| 解決した課題 | ブラウザ間の差異吸収、DOM操作の簡略化、クラスベース継承の模倣 |
| 現在の位置づけ | jQueryの台頭により利用は減少。レガシーシステムで稀に見かける程度 |
| 影響を与えたもの |
$() 関数、Ajaxラッパーは後のjQueryに影響。each()、map()、filter()などの高階関数はES5で標準化 |
Prototype.jsの功罪と遺産
北條さんが「Prototype.jsを使って実装されていた」と語るように、2005〜2008年頃のAjaxアプリケーション開発では定番のライブラリでした。
関数型メソッドの共通化とイディオムの統一:
重要な功績として、Prototype.jsは“関数型ユーティリティの事実上の標準化”にも貢献しました。
Prototype.js登場以前、JavaScriptにはmapやfilterといった関数型メソッドが標準化されておらず、プロジェクトごと・エンジニアごとに手作業でユーティリティ関数を実装するのが当たり前でした。
そのため、
- 「まずは Array.prototype に forEach を書くところから…」
- 「map の仕様どうする? 」
- そして人によってデザインが微妙に異なり、衝突しがち…
といった“毎回発生する面倒な作業”が常態化していました。
Prototype.js を導入することでこの状況は大きく改善され、チーム全体で統一されたイディオムをそのまま使える状態が実現しました。
ES5への影響:
Prototype.jsが提供したeach()、map()、filter()、find()などの高階関数は、2009年のES5でArray.prototype.forEach()、Array.prototype.map()、Array.prototype.filter()として標準化されました。現代のJavaScript開発者が当たり前のように使うこれらのメソッドは、Prototype.jsが先駆けて普及させたものです。
設計上の問題:
一方で、Array.prototypeやObject.prototypeを直接拡張する設計は、他のライブラリとの競合問題を引き起こすこともありました。この経験が「グローバルを汚染しない」という現代のJavaScript設計原則につながっています。
Firebug (最初期の代表的なブラウザ開発者ツール)
| 項目 | 内容 |
|---|---|
| 登場年 | 2006年1月 |
| 開発者 | Joe Hewitt(Firefox開発者の一人) |
| 思想背景(何のために作られた技術なのか) | 限られたデバッグ手法しかなかった時代に、開発効率と可視性を大幅に向上させる仕組みが求められていた。 |
| 当初の目的 | Firefox拡張機能として、Webデバッグを「まとも」にする。DOM、CSS、JS、ネットワークを一画面で確認 |
| 解決した課題 | alert()デバッグからの解放、リアルタイムDOM編集、コンソールログ |
| 現在の位置づけ | 2017年に開発終了。Firefox内蔵の開発者ツールに機能統合 |
| 影響を与えたもの | Chrome DevToolsなど、現在のブラウザ開発者ツールの原型 |
開発者ツールの「ビフォー・アフター」
北條さんが「外部のツールを使ってメモリリークの原因を探った」と語るように、Firebug登場以前はブラウザ内部を観察する手段がほぼありませんでした。Firebugの登場により、console.log()でのデバッグ、DOMのリアルタイム編集、ネットワークリクエストの監視が可能になり、Web開発の生産性は劇的に向上しました。現在の開発者ツールはすべて、Firebugの遺産の上に成り立っています。
F12キーの起源もFirebug:
現在、どのブラウザでも「F12キーで開発者ツールを開く」のが当たり前ですが、この操作を最初に導入したのもFirebugでした。多くのブラウザがこの慣習を継承しています。
Rust
| 項目 | 内容 |
|---|---|
| 登場年 | 2006年頃(個人プロジェクトとして開始)/ 2015年5月15日(v1.0リリース) |
| 開発者・組織 | Graydon Hoare(Mozilla社員、個人プロジェクトとして開始)→ 2009年〜 Mozilla公式スポンサー → 2021年〜 Rust Foundation |
| 思想背景(何のために作られた技術なのか) | 従来のシステム言語で課題とされてきた領域に対し、言語仕様で安全性を担保するアプローチを追求する動きが背景にあった。 |
| 当初の目的 | C++並みの性能を維持しつつ、メモリ安全性を言語レベルで保証することを目指す |
| 解決を目指した課題 | ダングリングポインタ、データ競合、未定義動作といったC/C++で起こりがちなメモリ安全性の問題 |
| 現在の位置づけ | システムプログラミングの有力な選択肢。Linuxカーネル(v6.1〜)にも採用が始まっている |
| 影響を与えたもの | フロントエンドツールチェーン(SWC、Turbopack、Biome等)の高速化に貢献 |
「C++の息の根を止めに来た言語?」
北條さんが表現するように、RustはC++で長年課題とされてきたメモリ安全性の問題に対し、「所有権システム」という独自のアプローチで取り組んでいます。ガベージコレクションを使わずにコンパイル時点でメモリ安全性を検証する仕組みは、多くの開発者から注目されています。
なお、Rustでもメモリリークは起こりえます(循環参照など)。ただし、ダングリングポインタや未初期化メモリへのアクセスといった深刻なメモリ安全性違反は、unsafeブロックを使わない限り言語仕様上防がれるよう設計されています。
フロントエンド開発者にとっても、Rust製ツール(SWC、Turbopack、Oxc、Biome等)によるビルド速度の改善という形で恩恵を受けています。
年表サマリー
1995年 ─ JavaScript誕生(Brendan Eich、Netscape)
│
1997年 ─ ECMAScript (ES1) 標準化
│
1999年 ─ ECMAScript 3 (ES3) 標準化
│ └ XMLHTTP実装(IE5)
│
2001年 ─ Internet Explorer 6 リリース
│ └ 「悪夢の始まり」
│
2005年 ─ Prototype.js登場 / 「Ajax」命名
│
│
2006年 ─ Firebug登場
│ └ 開発者ツールの夜明け
│
2008年 ─ Chrome登場(DevTools内蔵)
│
2009年 ─ ECMAScript 5 標準化
│ └ 10年ぶりのメジャーアップデート
│
2015年 ─ Rust v1.0 / ES6 標準化
│
現在 ─── Rust製ツールがJSエコシステムを加速
⚠️ 免責事項
本記事は、社内イベントを基に作成したものです。以下の点にご留意ください:
- 記事内容は対談者個人の経験と見解に基づいており、所属組織の公式見解ではありません
- 技術的な情報については正確性の確保に努めておりますが、記憶に基づく内容も含まれるため、情報の正確性・完全性を保証するものではありません
-
JavaScriptや関連技術は日々進化しており、記事執筆時点での情報となります - 本記事の情報を利用して生じた損害について、執筆者および所属組織は一切の責任を負いかねます
- 正確な情報が必要な場合は、公式ドキュメントや一次情報源をご確認ください