Forum How do I...?

Horrible JS performance. What's going on?

Hey, I'm having a huge problem with Prince. I'm manipulating a huge document with numerous tables inside it. The customer wanted some features that I could not implement without crawling through the entire document multiple times in JS. Once I got everything working I noticed that the generation time had increased by at least tenfold.

I did some benchmarking and found out that Chrome executes my scripts in the combined.html in 30 milliseconds. However for Prince it takes a whopping 39226 ms to execute the same scripts.

The documents are condifential for the time being so I can't attach them here yet. But I can say that the problematic part of the document consists of multiple tables with just over 10,000 table cells in total.

I understand that prince can be a little slower, but being over 1000 times slower seems weird! Does anyone have any idea what might be the problem?

Prince log:
charts.init:  0 ms.
buildTOC.init:  150 ms.
changeHeaderText:  7063 ms.
findPageBreaks:  24958 ms.
fixPdfUtils:  7055 ms.

Chrome log:
charts.init:  0 ms.
buildTOC.init:  18 ms.
changeHeaderText:  4 ms.
findPageBreaks:  7 ms.
fixPdfUtils:  1 ms.
  1. pdf-scripts.txt5.4 kB
Which version of Prince are you running?
Prince 10 rev 5
Would you be able to email me ( a sample script that demonstrates the problem? Then we can run some performance profiling.
It appears that the problem is due to getElementsByTagName, which has to handle live lists of DOM nodes and has not been heavily optimised yet. We may be able to address this in a future release of Prince.
Hey, thanks for the tips! I used querySelectorAll as you suggested and the performance boost was huge!

// Old

// New

charts.init:  0 ms.
buildTOC.init:  166 ms.
changeHeaderText:  24 ms.
findPageBreaks:  1843 ms.
fixPdfUtils:  12 ms.

From 39 seconds to just 2 seconds :)
That's great! We will shortly release an updated build that greatly improves the speed of getElementsByTagName and getElementsByClassName, but querySelectorAll is still the best option for most situations.
The new latest build with faster live node list methods is now available. :)