premailex icon indicating copy to clipboard operation
premailex copied to clipboard

CSS Inlining is slow when inlining wildcard styles on a large document

Open vlymar opened this issue 8 months ago • 0 comments

Hi @danschultzer, I've been investigating a scenario in which premailex takes a very long time to finish inlining CSS and I had some questions.

The scenario is that the input html has a number of font styles in the <head> that have * selectors, and the email body is large (thousands of tags). In this scenario Premailex takes ~30s to inline css. I generated a flamegraph of the inlining process for a much smaller doc (inlining a wildcard style) and saw that ~75% of the time is spent traversing the document.

I read through some of the code and saw that in this case a lot of the traversal is probably coming from this code.

I was wondering why use Util.traverse_until_first for every matching element rather than using something like Floki.find_and_update to match and update elements in one pass? The extra traverse_until_first ends up being very expensive when the selector is * as for every single element you have to re-traverse the document until you find it. In my quick test, switching to Floki.find_and_update made inlining ~7.5x faster for this particular scenario. I haven't dug super deep into the code so I could be totally wrong on the problem.

Is the issue that meeseeks doesn't support updating, so premailex needs to own the updating logic to remain compatible with both Floki and Meeseeks?

Thanks for your time!

vlymar avatar Jun 03 '24 22:06 vlymar