antonmedv/finder

Consider caching/memoizing "unique" function

pelmenept opened this issue · 2 comments

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;
        }
      }
  }

Thanks 😊

This can be added as a config option.

Added!