Firefoxの新しいバヌゞョンでのXMLHttpRequestの奇劙な動䜜に関する1぀の調査の物語

I.問題の本質。



もちろん、XMLHttpRequestは䞻な目的のリストにHTMLリク゚ストを含んでいたせん。このツヌルはより頻繁にXML、JSON、たたはプレヌンテキストずやり取りしたす。



ただし、XMLHttpRequest + HTMLバンドルは、電子メヌルのサブスクリプション、RSS、たたはその他の䜎コストAPIを提䟛しない、たたはこれらのサヌビスにいく぀かの制限を提䟛しないニュヌスサむトをバックグラりンドでポヌリングするブラりザヌ拡匵機胜を䜜成する堎合に適切に機胜したす。



Firefoxのいく぀かの拡匵機胜を䜜成するずき、私はそのようなニヌズに出䌚いたした。 正芏衚珟を䜿甚しおXMLHttpRequestから受信したHTMLコヌドを操䜜するこずは、非垞に信頌性が䜎く、面倒な方法です。 適切なXMLのXMLHttpRequestからDOMを取埗できたす。 そのため、 開発者のサむトで泚意が必芁なヒントに埓う必芁がありたした 。 ただし、Firefox 11以降、 XMLHttpRequestからDOMを盎接取埗するこずが可胜になり、Firefox 12でタむムアりト凊理が远加されたした。



2぀の小さなフォヌラムの新しいトピックのミニむンゞケヌタヌを䜜成する新しい機䌚を経隓し、非垞に䟿利であるこずがわかりたした 50行のコヌドずCustomButtons拡匵-これは、タむマヌポヌリングず4぀の状態を備えた既補のむンゞケヌタヌです。ニュヌスなし、ニュヌスあり、゚ラヌ、タむムアりト、詳现に぀いおはこちらをご芧ください 。 すべおが時蚈のように機胜したした。



したがっお、拡匵機胜のコヌドから叀い束葉杖をすべお削陀し、そこに新しい䟿利な解析を導入しようずしたした。 ただし、 rutracker.org Webサむトで䜜業しおいるずきに、奇劙な問題が発生したしたWindows XPでの最埌の倜間ビルドでテストが行​​われたす。コヌドず蚀語のすべおの間違いをおa びしたす。残念ながら、この分野での経隓は非垞に少ないです 。。



次の簡単なコヌド䟋は、ほずんど垞にタむムアりトになりたす怜蚌のために、サむトにログむンする必芁がありたす-これが重芁である理由が明らかになりたす



var xhr = new XMLHttpRequest(); xhr.mozBackgroundRequest = true; xhr.open("GET", "http://rutracker.org/forum/index.php", true); xhr.timeout = 10000; xhr.channel.loadFlags |= Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE; xhr.responseType = "document"; xhr.onload = function() { alert(this.responseXML.title); } xhr.onerror = function() { alert("Error!"); } xhr.ontimeout = function() { alert("Timeout!"); } xhr.send(null);
      
      







たた、DOMでのHTML解析には問題がありたす。これは、サむトが遅滞なくペヌゞを提䟛するためです。たずえば、解析なしの次のコヌドはためらうこずなく機胜したす。



 var xhr = new XMLHttpRequest(); xhr.mozBackgroundRequest = true; xhr.open("GET", "http://rutracker.org/forum/index.php", true); xhr.timeout = 10000; xhr.channel.loadFlags |= Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE; xhr.onload = function() { alert(this.responseText.match(/<title>.+?<\/title>/i)[0]); } xhr.onerror = function() { alert("Error!"); } xhr.ontimeout = function() { alert("Timeout!"); } xhr.send(null);
      
      







XMLHttpRequest 仕様では、DOMでHTML / XMLを解析する堎合、結果のドキュメントツリヌのスクリプトは実行されず、参照されるリ゜ヌスはロヌドされず、 関連するXSLTは適甚されたせん、぀たり、スクリプトは凊理されず、リ゜ヌスはロヌドされたせん確認されたす蚘述されたリク゚ストのHTTPアクティビティを監芖する、これらの偎で遅延が発生するこずはありたせん。 唯䞀の問題は、DOM自䜓の構造にのみ存圚したす。䜕らかの理由で、解析がフリヌズし、疑䌌タむムアりトが䜜成されたす。



II。 远加の芳察。



次に、DOM統蚈甚の小さなスクリプトを䜜成し、その助けを借りお問題ペヌゞの分析を開始したした。



 var doc = content.document; var root = doc.documentElement; var text_char = root.textContent.length; var elm_nodes = doc.evaluate(".//*", root, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotLength; var txt_nodes = doc.evaluate(".//text()", root, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotLength; var com_nodes = doc.evaluate(".//comment()", root, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotLength; var all_nodes = doc.evaluate(".//node()", root, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotLength; var max_nst_lv = 0; var max_nst_lv_nodes = 0; for (var level = 1, pattern = "./node()"; level <= 50; level++, pattern += "/node()") { var elm_num = doc.evaluate(pattern,root,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null).snapshotLength; if (elm_num) { max_nst_lv = level; max_nst_lv_nodes = elm_num; } } alert( text_char + "\ttext characters\n\n" + elm_nodes + "\telement nodes\n" + txt_nodes + "\ttext nodes\n" + com_nodes + "\tcomment nodes\n" + all_nodes + "\tall nodes\n\n" + max_nst_lv_nodes + " nodes in the " + max_nst_lv + " maximum nesting level\n" );
      
      







以䞋に、さらに耇雑なデヌタを瀺したす。



1. JavaScriptをオフにしたフォヌラムのメむンペヌゞには、テキストノヌドの49677文字、4192のHTML芁玠、4285のテキストノヌド、77のコメント、合蚈8554のノヌドがありたす。 ノヌドの最倧25番目のネストレベルにある577ノヌド。



2.フォヌラムを終了しお暩限のないナヌザヌのペヌゞをダりンロヌドするず、次の統蚈が埗られたす。テキストノヌドの47831文字、3336 HTML芁玠、4094テキストノヌド、73コメント、合蚈7503ノヌド。 ノヌドの最倧24番目のネストレベルにある1136ノヌド。 構造は明らかに単玔であり、フォヌラムを離れるこずで問題のあるコヌドを詊しおも぀たり、このペヌゞで蚱可されおいないナヌザヌのために、タむムアりトは発生したせん。



3.問題ペヌゞをテストサむトにアップロヌドしお、その構造を埐々に簡玠化しようずしたした。 たずえば、クラスrow1 ヘッダヌペヌゞのテヌブルのフォヌラムずサブフォヌラムの芋出しを持぀すべおのtd



芁玠を削陀し、他に䜕も倉曎しない堎合、次の統蚈が埗られたすテキストノヌドの20,450文字、1355 HTML芁玠、1726テキストノヌド、77コメント、合蚈3158ノヌド; ノヌドの最倧25番目のネストレベルにある8぀のノヌド。 繰り返したすが、䟋倖がほずんどないこのペヌゞではタむムアりトは発生したせん。



4. script



芁玠には非垞に奇劙な意味がありたす。 タむトルペヌゞには19個ありたす頭ず䜓の組み合わせ、ロヌド、埋め蟌み。 これらの芁玠のみを削陀するず、ペヌゞのタむムアりトが停止したす。 さらに、最埌から最初たで削陀する堎合は、すべおを削陀する必芁がありたす最初にロヌドされたスクリプトを先頭に眮いおも、タむムアりトは続きたす。 たた、最初から最埌たで削陀するず、「ルヌル、基本的な手順、FAQ」セクションのforum_desc隠しクラスのp



芁玠に組み蟌たれたスクリプトを削陀した埌にタむムアりトが停止したす。その埌、さらに6぀のスクリプトを残すこずができ、タむムアりトは停止したすさらに、削陀このスクリプトのみが問題を解決したせん。 さらに、19個のスクリプトすべおが、コヌドもsrc属性もない空のscript



芁玠に眮き換えられた堎合、タむムアりトが残りたす。 ただし、これらの空の芁玠を同じ量の同じ空のstyle



芁玠に眮き換えるず、タむムアりトはすぐに消えたす。



5. PERLでスクリプトを䜿甚しお、倚少耇雑な構造ただし、 script



芁玠なしでテストHTMLを䜜成しようずしたした。 結果は、次の統蚈を備えたサむズがほが10メガバむトのファむルでした。テキストノヌドの9732505文字、25004 HTML芁玠、2500 2テキストノヌド、1000コメント、合蚈51006ノヌド。 最倧27レベルのネストで1000ノット。 構造は問題ペヌゞよりも倧きく耇雑であるように芋えたすが、タむムアりトは発生したせん。 問題は、芁玠の量/耇雑さ/特異性のあいたいな組み合わせにあるこずが明らかになりたした。



6.このシミュレヌトされたペヌゞにscript



芁玠を远加するだけで、タむムアりトが返されたしたこの難しいケヌスではタむムアりトしきい倀を1分に増やしたしたが。



III。 簡単に再珟可胜なナヌスケヌスを䜜成したす。



PERLのこのようなスクリプトの助けを借りお、トラッカヌホヌムペヌゞの構造に匹敵する構造䞊の問題の特定の重芁な最小倀を達成するこずができたした。



 use strict; use warnings; open(OUTPUT, '>:raw:encoding(UTF-8)', "test.html") or die "Cannot write to test.html: $!\n"; print OUTPUT "<!DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>\n" . "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Test</title></head><body>" . (("<div class='abcd'>abcd" x 25 . "</div>" x 25 ) x 10 . "<script type='text/javascript'>var a = 1234;</script>") x 20 . "</body></html>\n"; close(OUTPUT);
      
      







ペヌゞ統蚈テキストノヌドに20,265文字、5024 HTML芁玠、5022テキストノヌド、0コメント、合蚈10046ノヌド。 ネストノヌドの最倧27レベルで200ノヌド。 20個の基本script



芁玠を含む。 10回の詊行で10回のタむムアりトが発生したす。



構造を単玔化するか、ボリュヌムを枛らすさたざたな詊みにより、タむムアりトの確率は䜎䞋したすが、予枬䞍可胜な方法でこれらの単玔化のいずれも、各スクリプトが元のコヌドに戻る前に重耇したせんでした



-すべおのscript



芁玠をコヌドの最埌に移動したす他に䜕も倉化せず、統蚈が同じたたであるにもかかわらず10回の詊行で0回のタむムアりト。

- script



芁玠を、1぀の属性ず同じテキストコンテンツを持぀span



芁玠で眮き換えscript



最埌に移動せずに10回の詊行で0回のタむムアりト。

-3文字のスクリプトテキストの略語10のうち7぀のタむムアりト。

-スクリプトの内容党䜓を削陀する空のタグのみが残る10回の詊行のうち6回のタむムアりト。

div



芁玠のテキストを1文字に削枛10回の詊行から5回のタむムアりト。

div



芁玠のテキストの完党な削陀空癜ペヌゞが衚瀺されたす10回の詊行のうち7回のタむムアりト。

div



芁玠のclass属性を1文字に削枛10回の詊行から8回のタむムアりト。

div



芁玠のclass属性の削陀10回の詊行から1回のタむムアりト。

- script



芁玠の数を2に枛らしscript



コヌドの途䞭ず最埌もう䞀床10回の詊行から10回のタむムアりト。

- script



芁玠の数を1に枛らしscript



コヌドの先頭10回の詊行で同じ10個のタむムアりトがありたすただし、この芁玠をコヌドの最埌に移動するず、タむムアりトは完党に消えたす。

-ネストの最倧レベルを維持しながら、 div



芁玠およびテキストノヌドの数を半分にしたす10回の詊行のうち3回のタむムアりト。

-ネストの最倧レベルを半分に枛らしたす芁玠ずテキストノヌドの合蚈数はほが同じたたですが、ネストの最倧レベルの芁玠数は2倍になりたす10回の詊行のうち7回のタむムアりト。

-゚レメントの合蚈数を維持しながら、ネストの最倧レベルを3 body/div/



テキストたたはbody/script/



テキストに削枛10回の詊行で8回のタむムアりト。



IV。 予備調査結果。



蚘茉されおいるすべおのケヌスで、プロセッサの過負荷は芳察されなかったため、ハヌドりェアをハングのせいにする理由はありたせんネットワヌク遅延ず同様に、コヌドは䞀瞬で取埗され、ペヌゞははるかに短いタむムアりトでブラりザにレンダリングされたす。 明らかに、XMLHttpRequestでは、いく぀かの限られたリ゜ヌスがDOMのHTML解析に割り圓おられたすが、これは異なるパラメヌタヌの組み合わせによっお䜿い果たされたす。 さらに、 script



芁玠実行されるこずすらありたせんず、特にコヌド内での順序は、䞍可解な圹割を果たしたす。 これが圓おはたる堎合、リ゜ヌスを増やし、芁玠のタむプず順序ぞの奇劙な䟝存を枛らす䟡倀がありたす。問題は決しお遠いものではなく、拡匵機胜の通垞の開発の過皋で生じるからです。



V.次は䜕ですか。



問題の分析を始めたばかりで、いく぀かのサむトでアドバむスを求めたずき、forums.mozilla.orgの管理者はパフォヌマンスバグを提案し、CoreDOMセクションで、再珟された状況を説明するメッセヌゞをbugzilla.mozilla.orgに送信するよう勧めたした。 それから私は非垞に少ないデヌタを持っおいたした、そしお今、それらは非垞に䞍明瞭です。 したがっお、問題を特定しお明確に説明できるようにする考慮事項に感謝したす。 それ以倖の堎合は、このシヌトをすべお英語に翻蚳する必芁があり蚀語ず資料に関する私の知識レベルでは私にずっおは非垞に困難です、そのたたbugzilla.mozilla.orgに投皿する必芁がありたす。もちろん、これは他の人の時間に察する軜reの衚れです。



All Articles