2

免責事項: you-can't-parse-html-with-regexブラインドマントラが始まる前に-疑問の利益を私に与えて、この質問を最後まで読んでください(+私はその正規表現についてすでに知っていると仮定します-HTMLはあなたを夢中にさせ、HTMLを解析するCthulhu Way


HTMLに一致する正規表現に関する不満のほとんどは、HTMLが緩く形成されており、正規表現がさまざまな問題やユーザーエラー+再帰などの他の問題に一致するのが難しいという事実から来ています。

ただし、HTMLが実際に有効なXHTML(またはよりXMLに似たもの)であり、制御された環境(一般的なユーザー生成のHTMLドキュメントではなく、クライアント側のテンプレートエンジンで使用するHTMLフラグメントテンプレートなど)から発生した場合はどうなりますか? )そして、手動でエラーをチェックし、何度も検証しましたか?


なぜ興味があるのか​​説明させてください。私はJavascriptでさまざまなString2DOM手法の速度ベンチマークを行っており、innerHTML、outerHTML、insertAdjacentHTML、createRange、DOMParser、doc.write(iFrame経由)、さらにはJohn RiesigsHTMLtoDOMJSライブラリまですべてをテストしました。

そして、もっと速く行く方法があるかどうか知りたいです。

createElement / appendChild(+ setAttributeおよびcreateTextNode)は、JavascriptでDOM要素を作成するための最速の方法です。正規表現は、大きな文字列をトラバースするための最速の方法です。これらの2つのメソッドを組み合わせて、DOMStringフラグメントをDOMに解析するさらに高速な方法を作成することはできませんか?

HTML文字列の例:

<div class="root fragment news">

    <div class="whitebg" data-name='Freddie Mercury'>
        <div id='myID' class="column c2">
            <h1>This is my title</h1>
            <p>Vivamus urna <em>sed urna ultricies</em> ac<br/>tempor d </p>
            <p>Mauris vel neque sit amet Quisque eget odio</p>
        </div>      

        <div class="nfo hide">Lorem <a href='http://google.com/'>ipsum</a></div>
    </div>

</div>

したがって、理想的には、コードは、正規表現がXHTMLスープを解析し、createElement / appendChild(+ setAttribute / createTextNode)を使用して要素を入力するdocumentFragmentを返します。(似ていますが、まだ完全ではありません例はHTML2DOMです

私(およびその他の国々)は、JSでDOMStringからDOMを生成する際に、そのようなものが古き良きinnerHTMLを打ち負かすことができるかどうかに非常に興味を持っています。できますか?

そのようなものを作る彼らの知識を試すゲームは誰ですか?そして、Stackoverflowの年代記で彼らの場所を主張しますか?:)


EDIT2:これまで盲目的に反対票を投じた人は誰ですか?少なくとも、質問で間違っていると感じることを説明してください。私はこの主題にかなり精通しており、その背後にあるロジックを提供し、このシナリオの違いを説明し、同様の解決策を提供するいくつかのリンクを投稿しています。あなたはどうですか?

4

1 に答える 1

0

まず、パフォーマンス指向のすべての質問に対する答えは、「ベンチマークするだけ」です。コードを書きたい場合はコードを書くことができ、そのパフォーマンスはそれ自体を物語っています。

そうは言っても、Web ブラウザーの動作に関する私の知識からあなたの質問に答えて、工数を節約できる可能性があるようにしようと思います。

いいえ、カスタム Javascript 駆動の HTML パーサーは、「JS で DOMString から DOM を生成する際に古き良き innerHTML を打ち負かす」ことはできませんでした。理論的には、同等のパフォーマンスが得られる可能性がありますが、その結果はほとんどありません。

その理由は、Javascript がインタープリター言語だからです。理想的なJS インタープリターは、ブラウザー API 呼び出しのネイティブの同等のシーケンスまで JS コードを最適化します。したがって、最良の場合、プラットフォーム ネイティブ コードと同等の処理を行う JS コードを記述しても、同等のパフォーマンスが得られます。JS コードは、内部でネイティブ呼び出しを行う必要があるため、同等のネイティブ コードよりも優れたパフォーマンスを発揮することはできません。

ここでのタスクは、DOM ツリーの作成です。innerHTML要素のを設定すると、次のようになります。

JS: ブラウザ、HTML を表示してくれ! これは Javascript 文字列オブジェクトです。

ブラウザ: parse_html_and_create_dom_objects()

ブラウザ: notify_javascript_of_dom_creation()

ここで、パーサーを Javascript で駆動するとどうなるかを示します。

JS: scan_string_for_next_token()

JS: ブラウザ、ここに DOM 要素を追加してください!

ブラウザ: create_dom_object()

JS: scan_string_for_next_token()

JS: ブラウザ、ここに DOM 要素を追加してください!

ブラウザ: create_dom_object()

JS: ブラウザ、作成した DOM ツリーをこの画面上に表示されている DOM ツリーに追加してください!

ブラウザ: refresh_page_view_and_notify_js()

ネイティブ バージョンでは、ブラウザーに返される一連の JS 呼び出しをすべてまとめてバッチ処理し、事前に最適化された純粋な C で実行できます。

ブラウザーの内部よりも JS で解析を行う方が速いと思われる理由は、一部の Web ブラウザーがチャンクにcreateElement設定するよりも繰り返し呼び出す時間が短いことがわかったためだと思います。これは、これら 2 つの呼び出しが同じ量の作業を実行していないためです。を呼び出すときは、文字列処理を行っていません (トークン化も字句解析も行いません)。あなたが電話するとき、あなたはそうです。したがって、一連の呼び出しよりも速いかどうかは、JS から要素を 1 つずつ取得する累積的なオーバーヘッドが、HTML 文字列を解析するコストを上回るかどうかによって異なります。言い換えれば、あなたはごまかしました: あなたのベンチマークは同じ量の作業を測定していません。innerHTMLcreateElementinnerHTML = <string>innerHTMLcreateElementcreateElementどの要素を作成するかを事前に知っている必要があります。

HTML 文字列の解析JS からの個別の要素の作成の両方が、ブラウザー内で両方を行うよりも高速なる可能性はほとんどありません。ブラウザの内部よりも優れた JS コードを書くことができた場合は、上流のブラウザの作成者に提出してください: Web ブラウザのパフォーマンスの改善はすべての人を助けます。開発者はネストされたインタープリタ内から優れたパフォーマンスを得ることの皮肉を高く評価すると確信しています。その通訳者の外で達成できる最高のものよりも。

于 2012-06-23T08:46:32.803 に答える