DOMおれおれAdvent Calendar 2015 – 01日目

2015-12-01

HTML文字列からががーっと生成する場合は el.innerHTML=htmlText と書くのが普通だと思うんですが、 insertAdjacentHTML() というAPIもあります。

var el = document.querySelector('div#out');
var html = '<b>BOLD</b>';
var position = 'afterbegin';

el.insertAdjacentHTML(position, html);
// -> <div><b>BOLD</b></div>

"position" はHTML文字列を挿入する位置を指定します。以下のいずれかです。

  • "beforebegin"
  • "afterbegin"
  • "beforeend"
  • "afterend"

それぞれ開始タグの前後、終了タグの前後へ挿入する指定です。外側にも指定できるのが便利そうね。

<!-- beforebegin -->
<div id="target">
  <!-- afterbegin -->

  <span>既存の内容……</span>

  <!-- beforeend -->
</div>
<!-- afterend -->

「挿入位置を指定する」という表現から、既存の内容自体が破壊されるわけではない事に気付くかと思います。

これは挿入先の要素を再度パースするものでなく、即ち既存の要素や要素内部の破壊を伴いません。余分なシリアル化のステップを回避出来る分、 innerHTML への代入による直接的な操作よりもはるかに高速な動作となります。

(via element.insertAdjacentHTML – Web API インターフェイス | MDN)

はるかに高速らしい。やったぜ。

というわけで過去にちょっと「innerHTMLから移行しよう!」みたいな機運もあったんですが、最近めっきり下火な印象です。今はもう innerHTML の最適化が進んで、むしろこっちの方が高速?

これ↓を試してみたらEdgeではまだ insertAdjacentHTML() の方が高速でしたが、Chromeでは同じ、Firefoxでは逆転していました。

insertAdjacentHTML vs innerHTML
innerHTMLの方が早い

ちなみにjQueryでは使われていません。色々あるみたい。

結局、要素構築を高速化するには

処理にかかる時間は大きい順に、画面の再描画、要素ツリー操作、HTML文字列生成まわり、という感じなので[要出展]、要素構築処理の前後も含めて見てやると良いのかなと思いました。

参考