8

いつ DOM ベースの生成と .innerHTML を使用するか、JQuery の .append メソッドを使用して文字列を追加するかを考えていましたか? ここで関連する投稿を読みます。HTML を DOM に追加するには、innerHTML を使用するか、新しい要素を 1 つずつ作成する必要がありますか? しかし、私はまだ各方法のユースケースについて確信が持てません.私が常にどちらか一方を選択するのは単にパフォーマンスの問題ですか?

formが任意の変数であるとしましょう:

DOM 生成

            var div = document.createElement("div"),
            label = document.createElement("label"),
            input = document.createElement("input");

            div.appendChild(label);
            div.appendChild(input);

            form.appendChild(div);

JQuery

           $(form).append("<div><label></label><input></input></div>")
4

3 に答える 3

5

2つ目はより読みやすくなっていますが、innerHTMLが機能するjQueryからのものです。バニラJSでは、次のようになります。

form.insertAdjacentHTML("beforeend", "<div><label></label><input></input></div>");

...これはjQueryよりも優れていると思います。ただし、パフォーマンスについて心配する必要はありません。パフォーマンスは常に挿入するノードの量に依存します。単一のノードの場合、HTMLパーサーはノードを直接作成するよりも遅くなります。大きなHTML文字列の場合、ネイティブパーサーはスクリプトよりも高速です。パフォーマンスについて本当に心配している場合は、テスト、テスト、テストを行う必要があります(そして、アプリに何か問題があると思います)。

ただし、2つの方法には大きな違いがあります。#1では、DOM要素を参照する3つの変数があります。たとえば、入力にイベントリスナーを追加したい場合は、すぐに追加でき、querySelectorを呼び出す必要はありませんform。これは非常に低速です。もちろん、innerHTMLを使用して非常に多くの要素を挿入する場合は、実際のパフォーマンスを向上させるために委任されたイベントを使用するため、これを行う必要はまったくありません。

jQueryを使用してメソッド#1をワンライナーに短縮することもできることに注意してください。

var div, label, input;
$(form).append(div=$("<div/>").append(input=$("<input/>"),label=$("<label/>")));

私の結論:

  • 少数の要素のみを作成する場合、DOMアプローチはよりクリーンです。
  • ほとんどの場合、html文字列の方が読みやすくなっています。
  • 標準的な状況では、2つのうちどちらも高速ではありません。ベンチマークの結果は大きく異なります。

innerHTML個人的には、いくつかの理由で(直接)好きではありません。これらの 2つの回答と、ここでもよく説明されています。また、IEにはテーブルに関するバグがあります(IEのtbodyにinnerHTMLを設定できないを参照) 。

于 2012-07-18T21:40:53.727 に答える
2

一般的に言えば、DOM を繰り返しヒットすることは、HTML の大きなブロックを innerHTML と交換することよりもはるかに遅くなります。これには2つの理由があると思います。1つはリフローです。ブラウザは、多種多様な要素の潜在的なレイアウトへの影響を再計算する必要があります。もう1つは、私が間違っている場合は誰かが私を訂正してくれると信じていますが、レンダリングとレイアウトの状態がオブジェクトに処理されているブラウザのコンパイル後の実行環境で起こっていることを翻訳することに少しオーバーヘッドがあるということです。 JavaScript で使用できます。DOM は常に変化する状況下にあることが多いため、あらゆる種類の結果をキャッシュする機会がほとんどない状態で毎回プロセスを実行する必要があります。おそらく、追加せずに新しい要素を作成するだけの場合でも (

DOM メソッドを使用すると、実際のドキュメント レイアウトに影響を与えることなく、ドキュメント フラグメントを構築し、HTML 要素を作成してフラグメントに追加できるため、不要なリフローを回避できます。

しかし、ここからが奇妙になります。

  • 何も入っていないノードに新しい HTML を挿入する - タイまたは何かの近くにある innerHTML は通常、多くの (ほとんどが古い) ブラウザーではるかに高速です。

  • 大量の HTML コンテンツを置き換える - これは実際には、パフォーマンスが呼び出しに近すぎない場合に DOM メソッドが勝つ傾向があるものです。

基本的に、innerHTML が悪臭を放つとすれば、大規模なスワップが発生しているティアダウン プロセスで悪臭を放つ傾向にあります。DOM メソッドはティアダウンには優れていますが、新しい HTML の作成や、大きな違いがまったくない場合に何も置換せずに直接挿入するのは遅くなる傾向があります。

実際には、必要なときにパフォーマンスのために非常に素晴らしいことを実行できるハイブリッド メソッドが存在します。私は 1 年以上前に 1 つを使用しましたが、innerHTML のみを使用する場合と比較して、大量の HTML コンテンツを遅延読み込みグリッドに交換する場合の応答時間の改善にかなり感銘を受けました。これを理解し、ウェブ上で綴った功績に値する人へのリンクを見つけられたらいいのにと思います(著者は、正規表現もたくさん書いています-私の人生ではグーグルできませんでした)。

スタイルとパフォーマンスの問題として、実際の DOM ノード構造を繰り返し微調整することは避けるべきだと思いますが、事前にドキュメント フラグメントで HTML を構築するか、innerHTML を使用するかは、ほとんど判断の問題です。JS には、データを HTML 対応の文字列にすばやく変換できる強力な文字列メソッドが多数あるため、個人的には innerHTML が大部分気に入っています。例えば:

var htmlStr = '<ul><li>' + arrayOfNames.join('</li><li>') + '</li></ul>';

そのワンライナーは、innerHTML に直接割り当てることができる UL です。適切なデータ構造と単純な while ループを使用して完全なテーブルを構築するのは、ほぼ同じくらい簡単です。次に、DOM API を使用して、arrayOfNames の長さと同じ数の LI を持つ同じ UL を作成します。自分自身にそれをする正当な理由はあまり思いつきません。innerHTML は、最終的に HTML 5 仕様に採用される前に、何らかの理由でデファクト スタンダードになりました。DOM API のノードベースの htmlElement オブジェクト調整アプローチには合わないかもしれませんが、強力であり、コードを簡潔で読みやすく保つのに役立ちます。ただし、innerHTML を使用して既存のコンテンツを編集および置換することはおそらくしないでしょう。古い HTML を参照して属性の innerHTML 文字列の解析を開始するよりも、データから作業し、構築し、新しい HTML に交換する方がはるかに安全です。

あなたの主なパフォーマンスの懸念は、おそらくDOMの「ライブ」部分を叩くことを避けることですが、残りはHTML生成に関するスタイルとテストの問題として人々に任せます。ただし、innerHTML は HTML5 ワーキング ドラフトにあり、現在も何年もの間、最新のブラウザー間でかなり一貫しています。また、それ以前の数年間は事実上の仕様であり、Chrome が新しくなる前からオプションとして完全に実行可能でしたが、IMO ですが、それは現時点でほとんど行われている議論です.

于 2012-07-19T00:00:04.463 に答える
-2

それは単なるパフォーマンスの問題です。最適なものを選択してください。

jsPerf は、次のようなパフォーマンス テストでいっぱいです

于 2012-07-18T21:22:15.137 に答える