繁体   English   中英

如何使 jQuery replaceWith() “非阻塞”(异步)?

[英]How can I make jQuery replaceWith() “non-blocking” (async)?

我正在使用 function replaceStr()替换正文标记中的一些字符串。 如果 html 页面较小,则更换不明显。 但是,如果 html 页面更大更复杂,您会注意到它。 替换正在阻止浏览器。 我的问题,如何使替换非阻塞 替换对页面并不重要,因此它可以在浏览器不忙时在后台发生。 我尝试使用asyncawait ,但我认为replaceWith() function 无法处理 Promises ,这就是它不能与async/await一起使用的原因。 但是你怎么能做到呢?

function replaceStr(myStrArr) {
  const container = $('body :not(script)');
  myStrArr.map((mystr) => {
    container
      .contents()
      .filter((_, i) => {
        return i.nodeType === 3 && i.nodeValue.match(mystr.reg);
      })
      .replaceWith(function () {
        return this.nodeValue.replace(mystr.reg, mystr.newStr);
      });
  });
}

谢谢您的帮助。

您当前的实现有几个地方可以在进行异步路由之前进行优化。 例如,您可以摆脱jQuery依赖项。 它对您的情况没有多大帮助,但会增加开销。

然后,目前您正在映射您的替换项和所有候选节点的每个节点,每次都替换nodeValue 这可能会触发每次重绘。

相反,您可以使用TreeWalker快速迭代相关节点,并且只更新一次nodeValues


在我的测试中,以下代码的运行速度大约比您当前的代码快 16 倍。 也许这已经足够了?

function replaceStr_upd(replacements) {
    // create a tree walker for all text nodes
    const it = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, {
        // but skip SCRIPTs
        acceptNode: node => node.parentNode.nodeName === 'SCRIPT'
                            ? NodeFilter.FILTER_REJECT
                            : NodeFilter.FILTER_ACCEPT
    });

    // a helper function
    const applyReplacements = initial => replacements.reduce((text, r) => text.replace(r.reg, r.newStr), initial);

    // iterate over all text node candidates
    while (it.nextNode()) {
        // but only update once per node:
        it.currentNode.nodeValue = applyReplacements(it.currentNode.nodeValue);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM