微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

javascript – jQuery / Sizzle checkContext内存泄漏

在DevTools中使用“Profiles”调试我的应用程序时,我发现“已分离的DOM树”已累积.这些分离的节点具有主要由checkContext函数组成的保留树(来自 jQuery – v1.10.1中的 sizzle).

我不知道如何进行这个.这个结果什么意思?

解决方法

这实际上是一个错误,没有理由Sizzle需要挂在上下文节点上,它只是在设置临时变量后不清理它.我提交了一个 issue for it,修改它,运行所有的Sizzle测试,并做了一个拉请求.

如果您要修补现有的jQuery或Sizzle副本:

>打开你的jQuery或Sizzle文件
>搜索matcherFromTokens函数
>查找此代码(靠近顶部):

matchers = [ function( elem,context,xml ) {
    return ( !leadingrelative && ( xml || context !== outermostContext ) ) || (
        (checkContext = context).nodeType ?
            matchContext( elem,xml ) :
            matchAnyContext( elem,xml ) );
} ];

>将返回值更改为var rv =,并添加checkContext = undefined;然后返回rv;在匿名功能结束时,例如:

matchers = [ function( elem,xml ) {
    var ret = ( !leadingrelative && ( xml || context !== outermostContext ) ) || (
        (checkContext = context).nodeType ?
            matchContext( elem,xml ) );
    // Release the context node (issue #299)
    checkContext = null;
    return ret;
} ];

注意:该代码为checkContext分配null,因为这显然是他们的风格.如果是我,我不会分配未定义的.

如果在拉取/合并过程中提出的修复有任何问题,我将更新答案.

最好继续让Sizzle缓存选择器,因为jQuery使用编译的选择器事件与事件委托,并且你不希望它每次发生相关事件时必须重新分析和重建匹配器函数,以便它能够确定元素是否匹配它

这不是jQuery对编译选择器中元素的唯一的地方,不幸的是.它所做的每个地方可能是一个可以使用修复的bug.我只有时间跟踪另一个,我也已经报告和修复(等待拉出请求登陆):

如果您搜索“潜在复杂的伪造”,您会发现:for:not pseudo-selector:

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,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,xml ) {
                input[0] = elem;
                matcher( input,results );
                return !results.pop();
            };
    }),

问题是在函数之后:在条件运算符中:

function( elem,xml ) {
    input[0] = elem;
    matcher( input,results );
    return !results.pop();
};

请注意,它不会清除输入[0].这是修复:

function( elem,results );
    // Don't keep the element (issue #299)
    input[0] = null;
    return !results.pop();
};

这就是我现在有时间跟踪.

原文地址:https://www.jb51.cc/jquery/152897.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐