The aim of this javascript example is to demonstrate how you can achieve a form of real, practical and valuable Javascript Multi-threading using IFRAMEs. We will also have a look at a graph showing the speed increase you can get using a real life widget that uses this kind of multi-threading methodology. This is not about simulating multi-threading using javascript timeouts or some theoretical asynchronous bit of code.
Assumptions
This assumes that you have a little javascript knowledge. Beginner level is fine to understand the principle behind iframe based multi-threading. You don't need any prior knowledge to analyse the response times of the realworld example.
This article is broken into the 5 sections shown below. They are all on the same page.
Concept
A schematic of the code is show below. The basic idea is that a parent will load html/javascript into it's iframes. These html/javascript code will then run in the iframes and write the results back to the parent using parent.functionName. This way we can simulate multi-threading. This is very similar to how the linux fork works. There is an amazing performance advantage which we will see later on. This code is available at the end of this page (in the appendix) if you wish to save it on to your PC and try it out.
1. The html file loads for the first time. This is the parent as threadid==null.
2. It loads a copy of itself into each of the 5 IFRAMEs, with a url parameter x=1, x=2... for each of the IFRAMEs. These become children.
3. The children in the IFRAMEs do some work.
4. The child calls parent.ThreadCallback in the parent. Each of the children call this function when they have finished.
This is very similar to fork method in linux. We use an id passes through the url to identify what thread it is. This also allows us to identify the parent from the children.
Graphs and Discussion
Let us have a look at the graph generated using javascript iframe multi-threading. The widget used to create this graph, calls the twitter api to get approximately 100 statuses from a user and then makes a Yahoo context API call for each of those 100 statuses to extract the keywords. The number of threads in the graph represent the number of IFRAMEs used.
If you observe the graphs for firefox, you can see that as the threads increase, the total time to make all the API calls decreas up to a point, and then it doesn't decrease further. This is consistent with the behaviour of response times in multi-threaded environments and is the law of diminishing returns.
If you look at the vanilla IE (pink) graph, you will notice that after 2 threads the results are more or less constant regardless of the number of threads. This is because IE limits the number of simultaeneous connections to 2. Therefor having more IFRAMEs is not reducing the total response times.
The IE MaxConnectionsPerSever-64 Graph has the registry hack that sets the maximun number of concurrent connections in IE to 64. Now you can see that the total response times reduce dramatically as you increase the number of IFRAMEs, upto a certain point. After this point, increasing the IFRAMEs is not showing any benefit. You would have also noticed that the response times for both IE graphs are almost exact for 1 and 2 threads. This is as it should be, because both are the same IE.
Conclusion
The graph shows conclusively that using multiple IFRAMEs -for javascript code that uses repeated http or ajax calls to services- can dramatically cut down on your response times. This also show that IFRAME base multi-threading is not some theoretical artifact but is solid code that can be put into practice to yield tangiable results.
Example
Here is the real world example. This is a pure javascript widget that displays the extracted keywords from a twitter user's statuses. You will definitely notice a distinct difference between the two.
Lauch the widget using 2 threads
Lauch the widget using 5 threads
Launch the widget using 10 threads
Launch the widget using 15 threads
Please note that for the graphs in the previous section, a stripped down version of the widget was used, which was not embedded in a blog.
For more details on the widget and to download the source code please visit Funky Twitter Thoughts Widget
Appendix
The code discussed in the "concept"
1. <html> 2. <head> 3. <script> 4. /*Dont worry about this. This is just ot get the url parameters only*/ 5. function MyGetUrlParams(){ 6. var url_params = new Array(); 7. var urla = location.href.substring(location.href.indexOf('?')+1).split('&'); 8. for(i=0;i< urla.length ;i++){ 9. url_params[urla[i].substring(0,urla[i].indexOf('='))]= 10. urla[i].substring(urla[i].indexOf('=')+1); 11. } 12. return url_params; 13. } 14. 15. /*This is the callback that gets called when a thread finishes*/ 16. function ThreadCallback(tid, message){ 17. alert(tid+":"+message); 18. } 19. 20. /*This is a parameter that identifies a thread*/ 21. threadid = MyGetUrlParams()["x"]; 22. 23. </script> 24. </head> 25. <body> 26. Multi-threading test <br/> 27. <iframe style="width:50px;height:50px" id='div0'></iframe> 28. <iframe style="width:50px;height:50px" id='div1'></iframe> 29. <iframe style="width:50px;height:50px" id='div2'></iframe> 30. <iframe style="width:50px;height:50px" id='div3'></iframe> 31. <iframe style="width:50px;height:50px" id='div4'></iframe> 32. 33. <script> 34. if(threadid==null){ 35. /* Parent */ 36. for(i=0;i<5;i++){ 37. document.getElementById("div"+i).src="jsmultithreading.html?x="+i ; 38. } 39. } 40. else{ 41. /* do some work and return a message*/ 42. parent.ThreadCallback(threadid, "Phew! I have finished working"); 43. } 44. </script> 45. </body> 46. </html> |

8 comments:
Sorry, but if your Browser dont support threads all javascript and iframes runs in one thread! Only crome offers for every tab/iframe an extra thread. So you solution is the same like ajax solutions!
Hmmm... That works really well, you saved my day and it is 23h28 ^^. Thanks!
Christian Harms, I think we must check here how it really works in the different browsers implementation, but the examples here are working fast.
I tested the thing in a firefox, no threading at all in this browser. I do not know if others have. I generated some results in console and I compared them. I took ten iteration by thread, and gave a timestamp for each iteration and I bound this results to the thread id.
It clearly shows that the 5 thread are not executing themselves in a concurrent way.
My small csv to compare: http://lecbna.org/sys_lecbna/Documents/jsthread.csv
http://www.sedoparking.com/mooph.cz
You shouldn't call this multithreading, but multiconnecting.
Because you are using Iframes (which get their own alottment of browser connections) your twitter and yahoo requests get to run concurrently.
Normal code (non request oriented) like computation will see no increase in performance, as you are still on the main JS thread for this instance of the browser.
What is multi-threading? If you think of a CPU it's either on 100% or off. If you had a process that was only using CPU then multi-threading would be useless. The idea of threading is to do other stuff while I wait for my slice of CPU. Multi-connecting, multi-threading all boils down to the same thing
That's silly.
There is no multi-threading going on here. All iFrames run in the same thread. If you don't believe me try running an endless "while" loop in one of the iFrames which just grabs a div element and increments the value. If it were multithreaded, you would not experience thread starvation. So you would see your other frames getting executed while the endless loop just does its thing in the other frame. But what will happen is your whole browser will lock up, becuase one thread is being used for all the Javascript, and thread starvation will occur, because there is only 1.
Multithreading (in general) means that there are separate threads which are given time-slices of the same CPU based on a scheduling and locking algorithm.
So this example is not really Multithreading at all. Neither is using setTimeout. All you can hope to do is simulate multithreading. But if one of those iFrames goes ape-shit on you, your entire browser goes with it.
MarkToronto is correct.
Poster, you obviously have no clue what multi-threading is. Thank you for wasting my time.
Post a Comment