Text finds and replaces chrome extensions - how do they work so fast?

In my chrome extension, I try to get every text element on the page, check what it is, and replace it if that is the thing. Here is my first approach:

function textNodesUnder(el){
    var n, a=[], walk=document.createTreeWalker(el,NodeFilter.SHOW_TEXT,null,false);
    while(n=walk.nextNode()) a.push(n);
    return a;
}

const nodes = textNodesUnder(document.getElementsByClassName("content")[0]);

    for (let i = 0; i < nodes.length; i++) {
        // replace text
        for (let k in whatToReplace) {
            nodes[i].nodeValue = nodes[i].nodeValue.replace(new RegExp(k, "gi"), whatToReplace[k])
        }

It works, but very, very slowly - 5-10 seconds to process the page. I'm more of a server side / Golang developer, so I understand that I can sneak up on the wrong tree here, but ... how do most texts find and replace style chrome extensions so quickly? Is this somewhere like Network Worker coming in handy?

+4
source share
2 answers

, , , . , node, , , , .

, , RegExp

const whatToReplace = {
  ipsum: 'IPSUM',
  'Vivamus|vehicula': 'VROOM!',
  '^Donec': 'donut',
  'eros': 'lust',
  'semper': 'always'
};

, RegExp .

const whatToReplace = [
  [/ipsum/gi, 'IPSUM'],
  [/Vivamus|vehicula/, 'VROOM!'],
  [/^Donec/, 'donut'],
  [/eros/, 'lust'],
  [/semper/, 'always']
];

for...of for...in :

const whatToReplace = [
  [/ipsum/gi, 'IPSUM'],
  [/Vivamus|vehicula/gi, 'VROOM!'],
  [/^Donec/gi, 'donut'],
  [/eros/gi, 'lust'],
  [/semper/gi, 'always']
];

const contentNode = document.querySelector(".content");

let walk = document.createTreeWalker(contentNode,NodeFilter.SHOW_TEXT,null,false);
let node;
while((node = walk.nextNode())) {
  // replace text
  for (let [rx, replacement] of whatToReplace) {
    node.nodeValue = node.nodeValue.replace(rx, replacement);
  }
}

, node, , , . .content, querySelector getElementsByClassName, , .

, , , :

let whatToReplace = {
  ipsum: 'IPSUM',
  'Vivamus|vehicula': 'VROOM!',
  '^Donec': 'donut',
  'eros': 'lust',
  'semper': 'always'
};

// convert whatToReplace into an array like the one in the previous example
whatToReplace = Object.entries(whatToReplace).reduce(function (acc, [key, value]) {
  acc.push([new RegExp(key, 'gi'), value])
  return acc;
}, []);

const contentNode = document.querySelector(".content");

let walk = document.createTreeWalker(contentNode,NodeFilter.SHOW_TEXT,null,false);
let node;
while((node = walk.nextNode())) {
  // replace text
  for (let [rx, replacement] of whatToReplace) {
    node.nodeValue = node.nodeValue.replace(rx, replacement);
  }
}

, DOM. , node, / . . , DOM, , , DOM, DOM:

const whatToReplace = [
  [/ipsum/gi, 'IPSUM'],
  [/Vivamus|vehicula/gi, 'VROOM!'],
  [/^Donec/gi, 'donut'],
  [/eros/gi, 'lust'],
  [/semper/gi, 'always']
];

const contentNode = document.querySelector(".content");
const parent = contentNode.parentNode;
const placeholder = document.createElement('div');

// remove it from the DOM and replace it with a placeholder
parent.replaceChild(placeholder, contentNode);

let walk = document.createTreeWalker(contentNode,NodeFilter.SHOW_TEXT,null,false);
let node;
while((node = walk.nextNode())) {
  // replace text
  for (let [rx, replacement] of whatToReplace) {
    node.nodeValue = node.nodeValue.replace(rx, replacement);
  }
}

// swap our altered element back into the DOM
parent.replaceChild(contentNode, placeholder);

, , Chrome, DOM, , , , . Firefox, . , DOM, -, 5% - Edge, - RegExp - .

+1

:

  • . .

  • regexp . .

  • , . , , / .

  • node . treeWalker.

0

Source: https://habr.com/ru/post/1695671/


All Articles