浏览器控制台JS文本替换性能优化及上标识别需求
优化浏览器控制台文本替换代码:提升速度并保留格式
原代码的核心问题
- 反复修改
document.body.innerHTML:每次循环重写整个页面HTML,触发多次重渲染,不仅速度慢,还会破坏DOM元素状态(如事件绑定),同时可能误解析上标等标签内容,导致格式丢失。 - 词库存在重复条目:多个重复的匹配规则(如多次出现的"Father"、"Daughter")会执行无效替换,浪费资源。
- 正则无边界处理:容易出现部分单词匹配(比如"Son"可能匹配到单词内部的字符片段)。
- 多次正则替换:每个规则单独执行替换,效率低下。
优化方案
- 仅遍历文本节点:使用
TreeWalker高效遍历页面纯文本节点,避免修改HTML结构,自然保留上标(<sup>)等格式。 - 整理词库:去重并按匹配字符串长度从长到短排序,确保长短语优先匹配(比如先匹配"THE LORD"再匹配"LORD",避免短匹配覆盖长匹配)。
- 单一正则批量替换:将所有匹配规则合并成一个正则表达式,一次性完成所有替换,减少执行次数。
优化后的代码
// 整理词库:去重并按匹配字符串长度降序排序 const rawWords = [ {"name": "GOD", "value": "GOD"}, {"name": "SAVIOR", "value": "SAVIOR"}, {"name": "LORD", "value": "LORD"}, {"name": "CHRIST", "value": "CHRIST"}, {"name": "EMMANUEL", "value": "EMMANUEL"}, {"name": "IMMANUEL", "value": "IMMANUEL"}, {"name": "THE LORD", "value": "THE LORD"}, {"name": "HOLY", "value": "HOLY"}, {"name": "THE SON OF GOD", "value": "THE SON OF GOD"}, {"name": "LAMB", "value": "LAMB"}, {"name": "THE HOLY SPIRIT", "value": "THE HOLY SPIRIT"}, {"name": "THE (.*)HOLY SPIRIT", "value": "THE HOLY SPIRIT"}, {"name": " HOLY SPIRIT ", "value": " HOLY SPIRIT "}, {"name": "THE SPIRIT", "value": "THE SPIRIT"}, {"name": "THE SPIRIT Of TRUTH", "value": "THE SPIRIT Of TRUTH"}, {"name": "SPIRIT ", "value": "SPIRIT "}, {"name": "THE COMFORTER", "value": "THE COMFORTER"}, {"name": "aCOMFORTER", "value": "COMFORTER"}, {"name": "COMFORTER", "value": "COMFORTER"}, {"name": "MESSIAH", "value": "MESSIAH"}, {"name": "GOSPEL", "value": "GOSPEL"}, {"name": "THE GOSPEL", "value": "THE GOSPEL"}, {"name": "GabriEL", "value": "GabriEL"}, {"name": "Life", "value": "Life"}, {"name": "AngEL", "value": "AngEL"}, {"name": "AngELs", "value": "AngELs"}, {"name": "Husband", "value": "Husband"}, {"name": "Wife", "value": "Wife"}, {"name": "Father", "value": "Father"}, {"name": "Mother", "value": "Mother"}, {"name": "Children", "value": "Children"}, {"name": "Child", "value": "Child"}, {"name": " Son", "value": " Son"}, {"name": " Daughter", "value": " Daughter"}, {"name": " Thee ", "value": " Thee "}, {"name": " Thine ", "value": " Thine "}, {"name": " Thy ", "value": " Thy "}, {"name": " Him ", "value": " Him "}, {"name": " His ", "value": " His "}, {"name": " He ", "value": " He "}, {"name": " Her ", "value": " Her "}, {"name": " Hers ", "value": " Hers "}, {"name": " People ", "value": " People "}, {"name": " We ", "value": " We "}, {"name": "Vision", "value": "Vision"}, {"name": "Reveal ", "value": "Reveal "}, {"name": "Revealed ", "value": "Revealed "}, {"name": "Faith ", "value": "Faith "}, {"name": "Faithful", "value": "Faithful"}, {"name": "Save", "value": "Save"}, {"name": " Son ", "value": " Son "}, {"name": " Sons ", "value": " Sons "}, {"name": " Daughter ", "value": " Daughter "}, {"name": " Daughters", "value": " Daughters"}, {"name": " Life ", "value": " Life "}, {"name": " Love ", "value": " Love "}, {"name": "Tribe", "value": "Tribe"}, {"name": "Priest", "value": "Priest"}, {"name": "Priesthood", "value": "Priesthood"}, {"name": "Elder", "value": "Elder"}, {"name": "Brother", "value": "Brother"}, {"name": "Sister", "value": "Sister"}, {"name": "Daughter", "value": "Daughter"}, {"name": "Calling", "value": "Calling"}, {"name": "IsraEL", "value": "IsraEL"}, {"name": "Transfigure", "value": "Transfigure"}, {"name": "Birth", "value": "Birth"}, {"name": "Prophet", "value": "Prophet"}, {"name": "Prophets", "value": "Prophets"}, {"name": "HOLY Ghost", "value": "HOLY SPIRIT"}, {"name": "perdition", "value": "perdition"}, {"name": "lucifer", "value": "lucifer"}, {"name": "satan", "value": "satan"}, {"name": "adversary", "value": "adversary"} ]; // 去重并按匹配字符串长度降序排序 const uniqueWords = Array.from(new Map(rawWords.map(item => [item.name, item])).values()) .sort((a, b) => b.name.length - a.name.length); // 构建替换映射和正则表达式 const replaceMap = new Map(); const regexPatterns = []; uniqueWords.forEach(word => { // 转义正则特殊字符,保留分组括号用于规则匹配 const escapedName = word.name.replace(/[.*+?^${}()|[\]\\]/g, match => { if (match === '(' || match === ')' || match === '.' || match === '*') return match; return `\\${match}`; }); regexPatterns.push(escapedName); replaceMap.set(word.name.toLowerCase(), word.value); }); // 构建全局不区分大小写的正则,使用边界确保完整匹配 const combinedRegex = new RegExp(`\\b(${regexPatterns.join('|')})\\b`, 'gi'); // 使用TreeWalker遍历所有文本节点 const treeWalker = document.createTreeWalker( document.body, NodeFilter.SHOW_TEXT, null, false ); let textNode; while ((textNode = treeWalker.nextNode())) { // 仅替换文本节点内容,不修改HTML结构 textNode.nodeValue = textNode.nodeValue.replace(combinedRegex, match => { return replaceMap.get(match.toLowerCase()) || match; }); }
关键优化点说明
- TreeWalker遍历:精准定位纯文本节点,完全保留页面原有标签结构(包括上标),避免innerHTML带来的DOM重构问题。
- 词库整理:去重减少无效操作,长字符串优先匹配避免短匹配覆盖长匹配(比如"THE LORD"不会被拆成"THE"和"LORD"分别替换)。
- 批量正则替换:一次性完成所有匹配替换,大幅减少正则执行次数,提升处理速度。
内容的提问来源于stack exchange,提问作者DennisWPaulsenJR
相关产品推荐
相关产品推荐

