- 「jQueryは遅い」は本当にjQueryのせいなのか
- DOM操作はJavaScriptではない
- jQueryは何をしているのか
- なぜ昔は問題にならなかったのか
- 状況を変えたのはJavaScriptエンジン
- セレクタがボトルネックになる理由
- ループで顕著に現れる
- さらに影響が大きかった変更
- 「遅い」と言われ始めた本当のタイミング
- jQueryを使うと必ず遅いのか
- それでもjQueryが使われ続けた理由
- 最後に
「jQueryは遅い」は本当にjQueryのせいなのか
結論から言うと、jQueryが急に遅くなったわけではありません。
ブラウザとJavaScriptエンジンが高速化した結果、jQueryの抽象化コストが見えるようになったのが実態です。
つまり、昔は「jQueryが速かった」のではなく、
「素のJavaScript(ネイティブDOM)が遅すぎて比較対象にならなかった」のです。
jQueryのDOM操作が遅いと言われ始めたのは、jQueryの劣化ではなく、Webプラットフォーム側の進化による“逆転現象”でした。
DOM操作はJavaScriptではない
まず重要な前提があります。
多くの人が誤解していますが、DOM操作は純粋なJavaScript処理ではありません。
DOMはブラウザの機能であり、JavaScriptはそれを呼び出しているだけです。
つまり次のコードは単なる変数操作ではありません。
document.getElementById("box").textContent = "hello";
これは内部的に
- JavaScriptエンジン(V8など)
- ブラウザエンジン(Blinkなど)
- レンダリングエンジン
をまたぐ処理になります。
ここには言語境界のコストが存在します。
昔はこのコストが非常に大きく、ネイティブDOM API自体が重かったのです。
jQueryは何をしているのか
では、jQueryのDOM操作は何をしているのでしょうか。
$("#box").text("hello");
たった1行ですが、内部では次の処理が行われます。
- CSSセレクタの解析
- 要素探索
- jQueryオブジェクト生成
- コレクションラップ
- メソッドチェーン対応
- クロスブラウザ変換
- DOM書き込み
つまりjQueryはDOM操作の「ラッパー」です。
ネイティブDOMを直接触るのではなく、安全な共通インターフェースを挟んでいるのです。
この構造自体がオーバーヘッドになります。
なぜ昔は問題にならなかったのか
ここが最も重要なポイントです。
2008年前後のブラウザでは、以下のコードはとても遅かったのです。
document.getElementById("box").innerHTML = "hello";
つまり
ネイティブDOM:遅い
jQuery:やや遅い
という関係でした。
差が小さいため、jQueryのコストは実質ゼロに近く見えていました。
さらにjQueryは次の利点を持っていました。
- ブラウザ差異を吸収
- 例外回避
- 安定したイベント処理
結果として「遅いけど安全」ではなく
安全で、しかも十分速いと評価されていたのです。
状況を変えたのはJavaScriptエンジン
2010年代に入ると状況が一変します。
- Google ChromeのV8
- FirefoxのSpiderMonkey高速化
- JITコンパイルの進化
これにより、ネイティブDOM APIが劇的に高速化しました。
すると関係が変わります。
ネイティブDOM:非常に速い
jQuery:抽象化コスト分だけ遅い
ここで初めて、jQueryのラップ処理のコストが顕在化しました。
セレクタがボトルネックになる理由
特に差が出たのがセレクタです。
document.getElementById("box");
これはIDハッシュテーブル検索です。
ほぼO(1)です。
一方、jQueryはこうです。
$("#box");
内部ではSizzleというセレクタエンジンが動きます。
CSSセレクタを解析し、ブラウザAPIへフォールバックします。
つまり
- パース
- 判定
- 互換処理
- ラップ生成
が追加されます。
1回では誤差でも、ループ内では明確な差になります。
ループで顕著に現れる
例えば以下のコードです。
for (let i = 0; i < 1000; i++) { $("#box").addClass("active"); }
これは毎回
- セレクタ解析
- 要素取得
- オブジェクト生成
を繰り返します。
ネイティブなら
const el = document.getElementById("box"); for (let i = 0; i < 1000; i++) { el.classList.add("active"); }
要素取得は1回です。
この差が「jQueryは遅い」という評価の正体です。
さらに影響が大きかった変更
もう1つの要因があります。
ブラウザがquerySelectorを実装したことです。
document.querySelector("#box");
これはCSSセレクタをネイティブ実装で検索します。
つまり、jQueryの存在意義の1つだった「CSSセレクタ検索」がブラウザ標準機能になりました。
ここで、jQueryの優位性が消えます。
「遅い」と言われ始めた本当のタイミング
jQueryが遅いと言われ始めたのは、スマートフォン普及の時期です。
PCでは問題にならなかった処理が、モバイルCPUでは顕著に現れました。
特に影響が出た処理:
- スクロールイベント
- アニメーション
- 大量DOM更新
この頃から、jQueryは「便利だが重い」と評価が変化します。
jQueryを使うと必ず遅いのか
ここで誤解があります。
jQueryを使うと遅くなるわけではありません。
問題になるのは以下です。
- ループ内セレクタ
- 不必要なラップ生成
- 頻繁なDOMアクセス
例えばこれは問題ありません。
$("#menu").addClass("open");
しかしこれは危険です。
$(".item").each(function(){ $(this).height(); });
DOM読み取りを大量に発生させ、レイアウト計算が繰り返されます。
つまり「jQueryが遅い」のではなく、
DOMのコストが表面化しやすい書き方になりがちなのです。
それでもjQueryが使われ続けた理由
jQueryはパフォーマンスのためのライブラリではありませんでした。
目的は「安定動作」です。
企業サイトや古いシステムでは、今でもjQueryが残っています。
理由は単純で、
速さより壊れないことの方が重要だからです。
最後に
jQueryが遅いと言われ始めたのは、jQueryの失敗ではありません。
ブラウザが成熟し、Webがアプリケーションに近づいた証拠でした。
かつてjQueryは「ないと困る技術」でした。
そして現在は「なくても困らない技術」になりました。
役目を終えたというより、
WebがjQueryの役割を吸収した、と考える方が実態に近いでしょう。