Currently one of the bottlenecks of Node::querySelector() and Node::querySelectorAll() is to create a CSSParser object every time. PassRefPtr<Element> Node::querySelector(const String& selectors, ExceptionCode& ec) { CSSParser parser(document()); // This is a bottleneck! CSSSelectorList querySelectorList; parser.parseSelector(selectors, querySelectorList); ...; } We can avoid creating a CSSParser object by caching the CSSParser object on Document. I'll upload a couple of proposed patches for performance comparison. After that I'll post some comments on the patches.
Created attachment 144745 [details] Patch [A]
Created attachment 144747 [details] Patch [B]
Created attachment 144751 [details] Patch [C]
CSSParser has so far not been reusable. There might be state left from the previous runs that affect the results of the next runs. I think you should try caching SelectorQueries first. That would avoid the need to spin up the parser repeatedly in the first place.
(In reply to comment #4) > CSSParser has so far not been reusable. There might be state left from the previous runs that affect the results of the next runs. > > I think you should try caching SelectorQueries first. That would avoid the need to spin up the parser repeatedly in the first place. Sounds reasonable. Caching SelectorQueries would solve the CSSParser construction problem.