0

divJavaScriptで作成されたものにデータを入力しようとすると、少し不便な「ラグ」に直面します。

var el = document.createElement("div");
el.innerHTML = '<insert string-HTML code here>'

ただし、これはHTMLコードの範囲のために自然なことです。場合によっては300,000文字を超え、GM_xmlHttpRequestから派生します。GM_xmlHttpRequestは完了までに1000ミリ秒(giveまたはtake)かかり、さらにDOM化によって500ミリ秒かかります。

私は使用して大量のテキストを取り除くことを試みましたsubstr(私に起こり得る最善のアイデアではありませんでした)、そしてそれは驚くほどほとんどの部分で機能しましたが、特定の時間に要素がHTMLコードを受け入れることができませんでした(おそらく比類のない) <*。?>)。

内部に保存されているごく少量のテキストにアクセスするだけで済みます。正規表現は問題外であり、これが最良のアプローチであると考えました。

編集:DOMの解析の定義が過小評価されていることに言及する傾向があります。つまり、この「テキスト」は、私が変更するかなりの数の要素のtextContentでした。したがって、正規表現はオプションではありません。

4

3 に答える 3

3

他の回答者はあなたの望み(文字列操作なしでDOMを解析する)が理にかなっているかどうかを推測することに焦点を当てていますが、私はこの答えを合理的なDOM解析方法の比較に捧げます。

<body>公平に比較​​するために、解析されたDOMの要素(ルートコンテナーとして)が必要であると想定します。http://jsperf.com/domparser-vs-innerhtml-vs-createhtmldocumentでベンチマークを作成しました。

var testString = '<body>' + Array(100001).join('<div>x</div>') + '</body>';

function test_innerHTML() {
    var b = document.createElement('body');
    b.innerHTML = testString;
    return b;
}
function test_createHTMLDocument() {
    var d = document.implementation.createHTMLDocument('');
    d.body.innerHTML = testString;
    return d.body;
}
function test_DOMParser() {
    return (new DOMParser).parseFromString(testString, 'text/html').body;
}

最初の方法は現在の方法です。すべてのブラウザでサポートされています。
2番目の方法には完全なドキュメントを作成するオーバーヘッドがありますが、最初の方法に比べて大きな利点があります。リソース(画像)が読み込まれません。ドキュメントのオーバーヘッドは、最初のドキュメントの潜在的なネットワークトラフィックと比較してわずかです。

最後の方法は、-執筆時点で-Firefox 12以降でのみサポートされており(GreaseMonkeyスクリプトを作成しているため、問題ありません)、このジョブに固有のツールです(前の方法と同じ利点があります)。名前が示すように、これはDOMパーサーです。

ベンチマークは、元のメソッドが最速の4.64 Ops / sであり、次にDOMParserメソッド4.22 Ops/sであることを示しています。最も遅い方法は、3.72 Ops/sのcreateHTMLDocument方法です。ただし、違いはごくわずかなので、前述の理由から、をお勧めします。DOMParser


あなたがGM_xmlhttprequestデータの取得に使用していることを知っています。ただし、XMLHttpRequest代わりに使用できる場合は、次の方法を試してみることをお勧めします。応答としてプレーンテキストを取得する代わりに、応答としてドキュメントを取得できます。

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://www.example.com/');
xhr.responseType = 'document';
xhr.onload = function() {
    var bodyElement = xhr.response.body; // xhr.response is a document object
};
xhr.send();

Greasemonkeyスクリプトが単一のページで長時間アクティブになっている場合でも、CORSをサポートしていない他のドメインでこの機能を使用できます。ドメインが他のドメインと等しいドキュメントにiframeを挿入し(例http://example.com/favicon.ico)、プロキシとして使用します(このページのGMスクリプトもアクティブにします)。iframeを挿入するオーバーヘッドは重要であるため、このオプションは1回限りのリクエストには実行できません。

同一生成元の要求の場合、このオプションが最適な場合があります(ベンチマークはされていませんが、中間の文字列操作の代わりにドキュメントを直接返すとパフォーマンスが向上すると主張できます)。DOMParser+ text / htmlメソッドとは異なり、responseType="document"Chrome 18以降、Firefox 11以降、IE10以降などのより多くのブラウザでサポートされています。

于 2012-10-07T21:05:57.343 に答える
0

アプリケーションについてもう少し知る必要がありますが、それだけ多くのHTMLコンテンツを処理している場合は、を使用することをお勧めしますiframe。これは非同期であり、JSコードを停止させることはなく、潜在的なデバッグの問題を多数引き起こすこともありません。

xmlhttprequest主に潜在的なXSSの脆弱性と、修正が不可能に近いHTMLの不具合が原因で、要素にから生のHTMLを入力するのは危険な場合があります。可能であれば、テンプレートを使用して(JQueryはある種のテンプレートソリューションを提供すると思います)、少量のXML / JSON/etcをロードすることを検討してください。ただし、を使用することが問題外の場合にのみ実行してくださいiframe

于 2012-10-07T20:39:06.097 に答える
0

私はあなたが大量のHTMLを持っていて、DOMを入れるのに長い時間がかかり、あなたはそれのほんの一部が欲しいだけです、それをより速くする方法は次のとおりです:

  1. サーバーに、実際に必要なHTMLの部分のみを提供するようにします。これにより、ネットワーク転送時間とDOM解析時間の両方を節約できます。

  2. サーバーを変更できない場合は、HTMLの一部を手動で解析して、不要な部分を削除する必要があります。これにより、DOMに多くが配置されなくなります。正規表現は、巨大な文字列を検索するのに時間がかかる方法の1つであるため.indexOf()、可能であれば、ターゲットとする一般的な領域を特定するようなものを使用することをお勧めします。一意のIDまたはクラスがあり、HTMLの一般的な形式がわかっている場合は、そのような高速なアルゴリズムを使用してターゲット領域を特定できます。ただし、解析する実際のHTMLを開示しない限り、それ以上の詳細を提供することはできません。

于 2012-10-07T20:49:09.380 に答える