Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QT: Javascript execution slow (unless I log to the console)

Tags:

javascript

qt

In QT 4.8.4 I have some arbitrary Javascript being executed via a callback in the c++:

myWebElement->evaluateJavaScript( myScript );

Now, the test script was:

$(this).css('border', 'solid 10px #000')

which worked, but it took a few seconds to run, and ran up the CPU 100%.

Then while testing I added "; console.log('X')" while debugging the script to see pinpoint the hangup... And it executed instantly!

I've found that as long as I'm logging to the console, the scripts work efficiently as expected. As soon as I remove the console logging the performance slows to a crawl. It doesn't matter if I log directly in the script, or add the log in the C++.

Any ideas? I'd hate to have a hack like below floating around in my program.

myWebElement->evaluateJavaScript( myScript + "; console.log('X')" );

UPDATE:

Looks like this bug is affected by the number of elements on the page. There's a table, in instances where there's only one or two rows there's no CPU run-up. When there's 600 rows there's several seconds of maxed-out CPU usage. Again though, as soon as there's a console.log command on the end there's no CPU run-up even with 600 rows.

(also added version info to the question)

UPDATE 2:

After testing, I don't need to pass anything into the console for the hack to work, I don't even need to call log. I can append "; console;" to the script and it will still work instantly. I've also tested adding a return statement to the end, which didn't work.

like image 280
Kver Avatar asked Oct 21 '13 21:10

Kver


1 Answers

The issue is that Qt is evaluating the return value of the last statement in Javascript and converting it to a QVariant. It became time consuming because jQuery was returning the jQuery object, which was being evaluated in its entirety by Qt - and recursively at that. This also consumed RAM too.

It wasn't console.log that was fixing the issue, it was the "null" value it returned. I tested, and stapling "null" at the end of the script also worked. Below is the updated code.

myWebElement->evaluateJavaScript( myScript + "; null" );

like image 180
Kver Avatar answered Oct 01 '22 18:10

Kver