[Web] append vs insertAdjacentHTML のパフォーマンス比較【実測結果と考察】
WebでのDOM操作時に利用できる「append
」(appendChild
)と「insertAdjacentHTML
」について、パフォーマンス面での比較を考察しています。
1. はじめに
JavaScriptでDOMを操作する際にはさまざまな手法がありますが、特にappend
(またはappendChild
)とinsertAdjacentHTML
は用途が似ており、選択に迷うことがあります。本記事では、measurethat.netのベンチマークを参考に、これら2つの手法のパフォーマンスに注目して比較します。
2. 比較対象のDOM操作手法
- append / appendChild: JavaScriptでDOMノードを生成して追加
- insertAdjacentHTML: HTML文字列を指定位置に挿入しDOMを生成
append と appendChild は前者が新しいAPIである分若干多機能になっていますが、性能の差はほとんどありません。
3. 実験条件とベンチマーク元
以下のベンチマークは measurethat.net 上で公開されているものです。1000個の要素をDOMに追加する処理の速度を比較しています。
※ 上記リンクのページ内にある「Suite status」横の「Run tests」をクリックすると、お使いのブラウザーでテストすることができます。
appendのコード:
var newElement = document.createElement("div");
newElement.id = "testing"
for (i = 0; i < 1000; i++) {
var newElementPart = document.createElement("div");
newElementPart.classList.add("testClass");
newElement.append(newElementPart);
}
document.getElementById("test").append(newElement);
insertAdjacentHTMLのコード:
html = "<div id='testing'>"
for (i = 0; i < 1000; i++) {
html += "<div class='testClass'></div>";
}
html += "</div>";
document.getElementById("test").insertAdjacentHTML("beforeend", html);
4. ベンチマーク結果の概要
執筆時点(2025年5月)での最新結果は以下のようになっていました。(※ ops/sec は「1秒間の処理回数」であり、数値が大きいほど速いことを示します。)
ブラウザー | append | insertAdjacentHTML | 参照リンク |
---|---|---|---|
Chrome | 489.1 ops/sec | 1770.7 ops/sec | measurethat.net 596251 |
Firefox | 735.2 ops/sec | 1703.3 ops/sec | measurethat.net 606868 |
少なくとも1年以内の結果はほぼ「insertAdjacentHTML の方が速い」という結果になっていました。
5. なぜinsertAdjacentHTMLの方が速い?
以下の要因が考えられます。
- HTML文字列を一括でパースし、最適化されたDOMフラグメントとして構築できるため
- ブラウザの内部エンジン(特に Chromium 系)でHTMLパーサー(解析)の処理が極めて高速化されている
- ループ内でDOMノードを逐次生成・追加するよりも、構造全体を文字列として一括で挿入する方が再描画のコストが抑えられることがある
結果として、特に大量の要素を一括追加する場合にはinsertAdjacentHTML
の方が高パフォーマンスになる傾向があることがベンチマークでも示されています。
6. どちらを使うべき?
上記結果から、どちらを使うべきかを簡易的にまとめたのが以下です。
用途 | 使うもの |
---|---|
大量ノードのバッチ追加 | insertAdjacentHTML |
静的テンプレートの簡易的な挿入 | insertAdjacentHTML |
ユーザー入力の安全な挿入 | appendChild + textContent |
ユーザー入力の安全な挿入 | append (appendChild) + textContent (createTextNode でも可) |
イベントバインド(ハンドリング)が必要 | createElement + addEventListener |
7. まとめ
近年のベンチマーク結果では、insertAdjacentHTMLの方が高速であるケースが多く報告されています。性能だけでなく、記述の簡潔さや柔軟性、セキュリティの観点も考慮し、用途に応じた適切な手法を選択することが重要です。
8. その他
- ここでは「innerHTML」については触れていませんでしたが、これについては「innerHTMLを更新するたびにDOMの破棄(既にあった場合)→HTML文字列のパース→DOM構築、のコストがかかる」という理由から、逐次追加の用途としては基本的には使用を避けるのが良いと考えられます。
- これは「
innerHTML += ""
」という記述だけでも発生します。安易に「+=」は使わないのがベターです。 - 空のDOM要素に対してinnerHTMLを単純にセットするだけであれば特に問題はありません。
- これは「
- append/appendChildとinsertAdjacentHTML以外にも、
DocumentFragment
やRange#createContextualFragment
を使った方法も存在します。特に複数のノードを一時的にまとめてからDOMに追加する場合にはDocumentFragment
が便利で、再描画の回数を減らすことで性能向上が見込めます。また、createContextualFragment
を使うことで、HTML文字列をパースして安全にフラグメントとして挿入することができます。