Prevent browser blocking with javascript

I have JavaScript that does a lot of calculations, as well as reading / writing values ​​from / to the DOM. The page is huge, so it often ends with a browser lock for a minute (sometimes longer with IE) with 100% CPU usage.

Are there any resources to optimize JavaScript to prevent this from happening (all I can find is how to disable the Firefox script warning)?

+52
javascript
Mar 23 '09 at 9:45
source share
7 answers

if you can turn your computational algorithm into something that can be called iteratively, you could cancel browser control at frequent intervals using setTimeout with a short timeout value.

For example, something like this ...

function doCalculation() { //do your thing for a short time //figure out how complete you are var percent_complete=.... return percent_complete; } function pump() { var percent_complete=doCalculation(); //maybe update a progress meter here! //carry on pumping? if (percent_complete<100) { setTimeout(pump, 50); } } //start the calculation pump(); 
+48
Mar 23 '09 at 10:00
source share

Use timeouts.

By placing the contents of your loop (s) in separate functions and calling them from setTimeout () with a timeout of 50 or so, javascript will give control of the flow and will return after some time, allowing the user interface to get the look.

There will be a good study here .

+8
Mar 23 '09 at 9:59
source share

I once wrote about browser performance , but let me briefly outline the ones that are related to the DOM for you here.

  • Update the DOM as little as possible. Make your changes to the DOM objects in memory and add them only once to the DOM.
  • Use innerHTML. This is faster than DOM methods in most browsers.
  • Use event delegation instead of normal event handling.
  • Know what challenges are and avoid them. For example, in jQuery, the value of $ ("div.className") will be more expensive than $ ("# someId").

Then some of them are related to JavaScript itself:

  • Loop as little as possible. If you have one function that collects DOM nodes and the other handles them, you loop twice. Instead, pass an anonymous function to a function that collects nodes and processes nodes as they are collected.
  • Use built-in functionality if necessary. For example, for all iterators.
  • Use setTimeout to let the browser breathe once in a while.
  • For expensive features that have idempotent outputs, cache the results so you don't have to compromise it.

There are several more on my blog (link above).

+3
Mar 23 '09 at 13:19
source share

It still bleeds a little, but Firefox 3.5 has things called web workers, but I'm not sure if they support other browsers.

Mr. Resig has an article about them here: http://ejohn.org/blog/web-workers/

And Simulated Annealing is probably the simplest example if you notice that the rotating Firefox logo does not freeze when workflows fulfill their requests (thus not freezing the browser).

+2
Aug 14 '09 at 18:17
source share

You can try to do long-term computations in threads (see JavaScript and topics ), although they are not very portable.

You can also try using some kind of Javascript profiler to find performance bottlenecks. Firebug supports javascript profiling.

+1
Mar 23 '09 at 9:51
source share

My experience is that manipulating the DOM, especially in IE, is much more important for performance than the "core" JavaScript (loop, etc.).

If you create nodes, in IE it is much faster by creating an HTML string and then setting innerHTML in the container than using DOM methods like createElement / appendChild.

+1
Aug 14 '09 at 18:27
source share

You can try to shorten the code.

  $(xmlDoc).find("Object").each(function(arg1) { (function(arg1_received) { setTimeout(function(arg1_received_reached) { //your stuff with the arg1_received_reached goes here }(arg1_received), 0) })(arg1) }(this)); 

or for for loops try

 for (var i = 0 ; i < 10000 ; i = i + 1) { (function(arg1_received) { setTimeout(function(arg1_received_reached) { //your stuff with the arg1_received_reached goes here }(arg1_received), 0) })(arg1_to_send) } 

I had the same problem and my clients reported it as a "Kill Page" error. But now I got the best solution for this. :)

0
Jun 13 '14 at 7:24
source share



All Articles