antonmedv / finder

CSS Selector Generator 🗺
MIT License
1.36k stars 96 forks source link

Consider caching/memoizing "unique" function #57

Closed pelmenept closed 1 year ago

pelmenept commented 2 years ago

First of all, thank you for the library! I think this is the best most robust CSS query generator. I use it in a lot of my projects.

For one of my project, I needed to generate css selector for ALL dom elements on the page. For this specific case, finder is also perfect, unfortunately if page is big, time taken to generate unique css selector for all dom elements can add up, up to 250 seconds, which is unusable for my use case.

After doing performance analysis, "unique" function is called a lot of times to figure out if selector is not unique, and it is called repeatedly with the same arguments. Caching this function drops execution time for that specific page (and other pages) from 250 seconds to under 1 second at the cost of memory.

something like this worked for me:

const cache = new Map();

  function unique(a) {
      const key = JSON.stringify(a);
      if (cache.has(key)) {
       return cache.get(key);
      } else {
        switch (rootDocument.querySelectorAll(selector(a)).length) {
            case 0:
                cache.set(key, !1);
                throw new Error(`Can't select any node with this selector: ${selector(a)}`);
            case 1:
                cache.set(key, !0);
                return !0;
            default:
                cache.set(key, !1);
                return !1;
        }
      }
  }
antonmedv commented 2 years ago

Thanks 😊

This can be added as a config option.

antonmedv commented 1 year ago

Added!