DevTools で「プロファイル」を使用してアプリをデバッグしているときに、「分離された DOM ツリー」が蓄積していることがわかりました。これらの切り離されたノードには、主に関数で構成される保持ツリーがあります ( jQuery内のシズルcheckContext
から来ています- v1.10.1)。
これをどのように進めればよいかわかりません。この結果は何を意味するのでしょうか?
Sizzle は、コンパイルされたセレクターをセレクター キャッシュに保存します。デフォルトでは、最大 50 のエントリが保存されます。選択を行う前に設定を試して$.expr.cacheLength = 1
みて、それらがなくなるかどうかを確認してください。
これがドキュメントhttps://github.com/jquery/sizzle/wiki/Sizzle-Documentation#-internal-apiです。内部のように見えるので、実際の製品コードに依存しないでください。
これは実際にはバグです。Sizzle がコンテキスト ノードにハングアップする必要がある理由はありません。一時変数を設定した後、クリーンアップされていないため、Sizzle がハングアップしているだけです。問題を提出し、修正し、すべてのシズル テストを実行し、プル リクエストを行いました。
jQuery または Sizzle の既存のコピーにパッチを適用する場合:
jQuery または Sizzle ファイルを開きます
matcherFromTokens
関数を検索する
その中で次のコードを見つけます (上部近く):
matchers = [ function( elem, context, xml ) {
return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
(checkContext = context).nodeType ?
matchContext( elem, context, xml ) :
matchAnyContext( elem, context, xml ) );
} ];
を に変更しreturn
、無名関数の最後にandvar rv =
を追加します。例:checkContext = undefined;
return rv;
matchers = [ function( elem, context, xml ) {
var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
(checkContext = context).nodeType ?
matchContext( elem, context, xml ) :
matchAnyContext( elem, context, xml ) );
// Release the context node (issue #299)
checkContext = null;
return ret;
} ];
注:明らかにそれが彼らのスタイルであるため、そのコードはに割り当てnull
られます。checkContext
私だったら、undefined
代わりに割り当てます。
プル リクエスト / マージ プロセス中に発生した修正に問題がある場合は、回答を更新します。
jQueryはコンパイルされたセレクターをイベント委譲で使用し、関連するイベントが発生するたびにマッチャー関数を再解析して再構築する必要がないため、セレクターをSizzleキャッシュのままにしておくことをお勧めします。それに合わせます。
残念ながら、jQuery がコンパイル済みセレクターの要素を保持する場所はこれだけではありません。それが行う各場所は、おそらく修正を使用できるバグです。私は他の1つを追跡する時間しかありませんでした。これも報告して修正しました(プルリクエストが上陸するのを待っています):
「潜在的に複雑な疑似」を検索すると、:not
疑似セレクターの次のものが見つかります。
pseudos: {
// Potentially complex pseudos
"not": markFunction(function( selector ) {
// Trim the selector passed to compile
// to avoid treating leading and trailing
// spaces as combinators
var input = [],
results = [],
matcher = compile( selector.replace( rtrim, "$1" ) );
return matcher[ expando ] ?
markFunction(function( seed, matches, context, xml ) {
var elem,
unmatched = matcher( seed, null, xml, [] ),
i = seed.length;
// Match elements unmatched by `matcher`
while ( i-- ) {
if ( (elem = unmatched[i]) ) {
seed[i] = !(matches[i] = elem);
}
}
}) :
function( elem, context, xml ) {
input[0] = elem;
matcher( input, null, xml, results );
return !results.pop();
};
}),
:
問題は、条件演算子の後の関数にあります。
function( elem, context, xml ) {
input[0] = elem;
matcher( input, null, xml, results );
return !results.pop();
};
クリアされないことに注意してくださいinput[0]
。修正は次のとおりです。
function( elem, context, xml ) {
input[0] = elem;
matcher( input, null, xml, results );
// Don't keep the element (issue #299)
input[0] = null;
return !results.pop();
};
現時点で追跡する時間があるのはそれだけです。