I'm just wondering why my code takes so long with Internet Explorer 11. I have a PHP page which calls a function. That function returns a very long string. The string is actually JavaScript code which has 400 rows.
Let's assume the returned string is like this:
<script>
document.getElementById('pka1').innerHTML = 'gddgdgd gsdg gdsgs';
document.getElementById('pka2').innerHTML = 'gg gdsgdsggg gsg';
document.getElementById('pka3').innerHTML = 'fdfd ffdsf dfss ff';
...
document.getElementById('pka398').innerHTML = 'hfhhfd hdhfh fhdfd';
document.getElementById('pka399').innerHTML = 'ggjggfgjgh h ffhfh';
document.getElementById('pka400').innerHTML = 'fssfs ffsafsa eefg';
</script>
When that string has been returned, I use jQuery to run the code. The returned string is stored to variable named as data. So, I run the following command:
$('#pka').html(data);
After that Internet Explorer and other browsers will run the previous JavaScript code which consists of 400 rows and modifies the HTML code of 400 divs.
Mozilla Firefox does this very fast, but Internet Explorer spends too much times - even 3-4 seconds. While the script is running, the webpage is disabled (I do not know why) and I cannot click hyperlinks while the script is running. When using Firefox this takes 0.5 secs, but IE is very slow.
How could I speed up the process and make the page not to be disabled when a browser runs the JavaScript code from the div which id is pka?
While the script is running, the webpage is disabled (I do not know why) and I cannot click hyperlinks.
Simply because that's how it works.. Java script execution model makes the a function or code block runs to complete before it can process other..
So if there is a long one, user interaction will be blocked..
How could I speed up the process
Well, you have to rethink about the 400 divs.. this is too much.
Also try to divide the change into functions as each function is processed alone. it will make it less laggy.
I am not sure about using web workers in manipulating the dom, if it's beneficial or even possible.
Related
I started to make a simple js debugger, and I was wondering if there is a way to stop an already running script if either it isn't responding or I want to stop it's setInterval() loop where we don't know the id of the loop.
I've noticed in the Chrome DevTools that every document has it's own script collection under document.scripts, but I couldn't find anything like a list of intervals (eg:window.intervals) or any response if any function is running,so I can't really determine if a function needs to be killed.
This could be useful when you want a webpage scanner extension or a debugger thet can refresh the page when the script is frozen.
Edit:
The list of intervals has already been asked and solved in How can I get all timers in javascript question.
Now the only question remains is: How can I determine if a script is frozen so it or the page can be killed?
I'd like to run some external JavaScript with a time restriction, so that if it takes more than N seconds it will be stopped.
Some browsers, e.g. Firefox, already do this with a dialog that asks if you want to allow a script to keep running. However, I'm looking for a bit more:
I want to set my own time limit rather than use the browser's default (e.g., I believe Chrome's is much longer than Firefox's).
I want to be able to do this on a per-script basis, not per-page. One page may contain multiple scripts that I want to restrict in this way (hence my idea to use <iframe> elements).
I was thinking it would be very convenient if there were simply an attribute I could attach to an <iframe>—e.g., something like js-time-limit="5000" (I just made that up)—but I haven't been able to find anything like that.
Is this possible? To put a configurable time limit on JavaScript execution in a browser?
If the iframe is doing computation work and doesn't need to access the DOM, then use web workers: https://developer.mozilla.org/en-US/docs/Web/Guide/Performance/Using_web_workers
Here is also a library that can abstract away the hard parts for you! http://adambom.github.io/parallel.js
Important parts:
Dedicated Web Workers provide a simple means for web content to run scripts in background threads.
If you need to immediately terminate a running worker, you can do so by calling the worker's terminate() method: myWorker.terminate();
Browser compatibility
Chrome Firefox (Gecko) Internet Explorer Opera Safari (WebKit)
3 3.5 (1.9.1) 10 10.60 4
For posterity: my original goal was to allow users of a website to submit JS code and run it in the background with a time limit so that, e.g., infinite loops don't wreak havoc on the CPU.
I created a library called Lemming.js using the approach Joe suggested. You use it like this:
var lemming = new Lemming('code to eval');
lemming.onTimeout(function() {
alert('Timed out!');
});
lemming.onResult(function(result) {
alert('Result: ' + result);
});
lemming.run({ timeout: 5000 });
You can check out the GitHub repo for more details.
Is there a way to do something? :-)
Long press me!
<script type="text/javascript">
// do something to open context menu of anchor element
</script>
To run a javascript on a UIWebView you have
- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script
Parameters
script
The script to run.
Return Value
The result of running script or nil if it fails.
Discussion
JavaScript execution time is limited to 10 seconds for each top-level entry point. If your script executes for more than 10
seconds, the web view stops executing the script. This is likely to
occur at a random place in your code, so unintended consequences may
result. This limit is imposed because JavaScript execution may cause
the main thread to block, so when scripts are running, the user is not
able to interact with the webpage.
JavaScript allocations are also limited to 10 MB. The web view raises
an exception if you exceed this limit on the total memory allocation
for JavaScript.
I have a web app that I am trying to speed up. It looks like this:
+------+
| |
| |
+------+
+------+
| |
| |
+------+
+------+
| |
| |
+------+
Each box is an iFrame containing a Flash SWF and some javascript. The SWF downloads a thirdparty SWF that is used to display information. I have found that the load time for the webapp is:
LoadTime = (4 seconds) * numberOfBoxes + (3 seconds)
When I just imbed the 3rd party swf directly (without our swf or the javascript) the load time is:
LoadTime = (1 second) * numberOfBoxes + (2.5 seconds)
I am trying to find where the extra 3 seconds is being used so that I can speed up our webapp. I think that the candidates are:
Serverside processing (jsp)
Download
Javascript
Flash
Other?
Download
Below is an image of the downloads taken from firebug. I have replaced the file names with what their type is. None of the downloads are taking especially long after the first time.
One place of interest however is marked in red. The red area is a 3 second gap between when My SWF is loaded and when two gif files are loaded followed by the Third Party SWF. I think this pause is caused by processing on the client (is this true?).
Note: The red bars in the graph are not part of the diagram. I added them to highlight the gap where nothing is occurring on the .net panel.
I think that I can conclude from this that I have a client side processing issue which implies either Flash or Javascript. Question 1: Is this correct?
Edit: I added up the total non-concurrent download time:
When there is 1 iframes the download time is 1.87 seconds
When there is 2 iframes the download time is 2.29 seconds
When there is 5 iframes the download time is 8.57 seconds
When there is 10 iframes the download time is 10.62 seconds
When there is 21 iframes the download time is 17.20 seconds
Javascript
I used the profiler in firebug to profile the javascript. Here are the results when there are four components on the page:
This means that the javascript is running for about .25 second/chart. This seems reasonable to me.
Question 2: Am I reading these results correctly?
This leaves about 3.5 seconds/chart of processing for something else.
Flash
I inserted some trace statements in the AS3 code. We are listening to an event called something like "done loading". I put a trace in the first initialize method and in the "done loading" method. The flash is only eating up .2 second/chart between those two trace statements.
Question 3: Is there a better way to to profile the flash? Could it be the flash loading or something like that that is eating up the extra time?
Other
I am not sure if there are other things other than:
Serverside processing (jsp)
Download
Javascript
Flash
Question 4: Is there something that I am missing that could be eating up time?
Next Steps
I am not sure what my next step should be. I know that something is taking about 1.5 - 3 seconds/chart but I cannot figure out what it is. I suspect that it is something related to my swf.
Question 5: How should I find that missing time?
Update: Time Summary
I have graphed all of the times for each thing that could be taking time.
The X-axis is the number of charts that are being used.
The Y-axis is the about of time loading all of the charts takes.
The last graph is possibly the most important graph. The blue dots is the amount of total loading time (measured using a stop watch). The red dots are the amount of time that I have accounted for (Javascript, download time and flash time).
Update: Browser Wars
I am targeting IE and Firefox (although it is a nice bonus if other browsers work). All of the results presented so far are with Firefox with firebug running. Just for fun I thought I would try in other browsers. I don't think that this brings me closer to a solution but interesting to see how much IE sucks.
Note: Before running tests for Firefox I cleared the cookies and cache. I did not do this for IE or Chrome
Update: Flash Loading
I have been sprinkling console.log statements though my code trying to sandwich the slow code. (The results get pushed out to the Firebug console).
One thing that I have noticed that seems suspicious to me me is that there is a 2.5 second gap between when my last javascript log gets printed and when my first flash log gets printed.
17:08:29.973 - Javascript code
Time difference: 2510 ms
17:08:32.483 - Flash- myComponent.init()
Does flash need to setup a virtual machine for each swf? Does it compile the actionscript on the client?
What happens between when I <embed> my swf and when the creationComplete event in my main .mxml?
Just some ideas:
Can you eliminate the middle man, in this case, the third party swf?
Where is the third party swf located? If it is on a remote server, you should just have to download it once and then place it on your local server with your other files. That could eliminate download times.
Can you use something like a flash decompiler to decompile the third party swf's code and put the code directly into your swf? (this is probably against the rules)
What happens if you don't put the content in iframes, rather, just put them in divs?
As another option -- try to disable firebug. Is time changes somehow?
Also try the same in chrome -- with and without dev tools.
To understand whether this jsp, that called from your swf or just your swf you can do this:
instead of your normal swf, provide just it mock without any calls -- just empty
also instead of your js in frame provide just empty file
Do this partly and check the difference.
Also try to profile all newtwork events, that oocurs. May be your SWF calls some method in 3rd party, that calls then some remote method. Here I think we cann't improve this. Only may be if method in 3rd party could be cached somehow. So in your profile we see only loading of files -- we dont' see any other requests -- ajax or something like this.
As per my undertanding, There are three possibilities which the suspects.
Firebug profiler. Try on other browser and see how much time it takes.
The Red component which is taking time after that other component might be loaded.
SWF file creating connection with other application through your server instead of direct connection.
Are the iframes coming from HTML response from server? Or, are the iframes added to DOM dynamically via javascript?
You will have better performance by waiting until DOM is ready and inserting iframes into the DOM after page load.
I think the problem is that Flash is blocking script execution while the local SWF downloads the 3rd party SWF. You probably need to figure out how to do a concurrent, non-blocking, asynchronous download of 3rd party SWF using ActionScript.
I created a helloWorld SWF and embedded it into a web page.
On the browsers that I was testing on it takes a long time for the swf to load. When there is just one swf on a page this is not noticeable (~ 3 second loading time) however when there are 10 swfs on a page there is a noticeable pause (~3 seconds/chart * 10 charts = 30 seconds).
Here are the browsers that I tested on:
IE 7 - Very slow. Takes about 37 seconds to load 16 "Hello World" applications
IE 8 - Seems mostly ok. Only tested for a brief period
Firefox 3.6.17 - Very slow. As slow as IE 7
Chrome 12.0.742.91 - Fast
I have posted my hello world application in another question. If anyone one knows how to speed up the loading of a very simple swf you can answer here:
Flash: Many identical SWFs on same Page
I'm adding some <script> tags dynamically to the head element after page load. I understand the scripts are loaded asynchronously, but can I expect them to be parsed in the order they are added?
I'm seeing the expected behaviour in Firefox, but not in Safari or Chrome. Looking at the document in Chrome developer tools and Firebug, both show the following -
<html>
<head>
...
<script type="text/javascript" src="A.js"></script>
<script type="text/javascript" src="B.js"></script>
</head>
...
</html>
However looking at the resource loading view, chrome seems to parse whichever is returned first from the server, while firebug always loads them in the order the script tags were added, even when B is returned first from the server.
Should I expect Chrome/Safari to parse the files in the specified order? Using Chrome 5.0.375.29 beta on OS X 10.6.3
EDIT (10/5/10): When I say parse, I mean execute - can see many benefits of aggressive parsing - thx rikh
EDIT (11/5/10): Ok so I put together a test along the lines of that by juandopazo below. However I have added a combination of things, including
Adding the script element to the head directly with javascript. (Tests A -> D)
Adding the script element to the head using jquery's append() method. (Tests E -> H)
'Loading' the script with jquery's getScript() method. (Tests I -> L)
I also tried all combination of the 'async' and 'defer' attributes on the script tags.
You can access the test here - http://dyn-script-load.appspot.com/, and view source to see how it works. The loaded scripts simply call the update() function.
The first thing to note, is that only the 1st and 3rd methods above operate in parallel - the 2nd executes requests sequentially. You can see a graph of this here -
Image 1 - Graph of Request Lifecycle
Request lifecycle Graph http://dyn-script-load.appspot.com/images/dynScriptGraph.png
It's also interesting that the jquery append() approach also blocks getScript() calls - you can see that none of them execute until all of the append() calls are complete, and then they all run in parallel. Final note on this is that the jQuery append() method apparently removes the script tags from the document head once they have executed. Only the first method leaves the script tags in the document.
Chrome Results
The results are that Chrome always executes the first script to return, regardless of the test. This means all the test 'fail', except the jQuery append() method.
Image 2 - Chrome 5.0.375.29 beta Results
Chrome Results http://dyn-script-load.appspot.com/images/chromeDynScript.png
Firefox Results
On firefox, however, it appears that if the first method is used, and async is false (i.e. not set), then the scripts will reliably execute in order.
Image 3 - FF 3.6.3 Results
FF Results http://dyn-script-load.appspot.com/images/ffDynScript.png
Note that Safari seems to give varied results in the same manner as Chrome, which makes sense.
Also, I only have a 500ms delay on the slow script, just to keep the start->finish time down. You may have to refresh a couple of times to see Chrome and Safari fail on everything.
It seems to me that without a method for doing this, we are not taking advantage of the ability to retrieve data in parallel, and there is no reason why we shouldn't (as firefox shows).
Sorry for answering my own question, but its been a while and we did come up with a solution. What we came up with was to load the javascript concurrently as text contained in a json object, and then used eval() once they were all loaded to execute them in the correct order. Concurrent load plus ordered execution. Depending on your use case you may not need the json. Roughly, here is some code that shows what we did -
// 'requests' is an array of url's to javascript resources
var loadCounter = requests.length;
var results = {};
for(var i = 0; i < requests.length; i++) {
$.getJSON(requests[i], function(result) {
results[result.id] = result;
...
if(--loadCounter == 0) finish();
});
}
function finish() {
// This is not ordered - modify the algorithm to reflect the order you want
for(var resultId in results) eval(results[resultId].jsString);
}
As I understand it, they are meant to be executed in the order they appear in the document. Some browser might be able to perform some parsing out of order, but they would still have to be executed in the correct order.
No, you cannot expect that all browsers will defer execution of both scripts until both are loaded (**especially when you are adding them dynamically).
If you want to execute code in B.js only after A.js is loaded then your best bet is to add an onload callback to A.js that sets a variable and another one to B.js that checks to see if that variable has been set, then it executes the necessary function in B.js if it has (and if A.js has not loaded, it starts a timer that periodically checks until it has loaded).
The download order and the execution order is not the same thing. In your page, even if B.js is downloaded first, the browser's engine will wait for A.js to continue processing the page.
The scripts are definitely processed, not only in the order they appeared in the document, but also at the place they appeared.
Imagine if it wouldn't be like that, there would be many errors if your little script that uses jQuery is downloaded and processed before the jQuery library.
Also, when you do a "document.write" in a js file, it appears where the script has been declared. You can't access DOM objects that are appearing after the script declaration neither.
This is why there are recommendations to put scripts at the very bottom of the page, to prevent their execution too soon and decrease the "perceived load time" of the page, because the browser's rendering engine is stopped as soon as a script is processed.
Mike
EDIT: if they are added dynamically with javascript, I think they are processed in the order they were added in time.
You could load b.js from a.js to be 100% sure ... although I'd like the definitive answer to this question myself, especially with sync ajax loading of scripts.
I was investigating this while working on a little library that loads modules dynamically like YUI 3. I created a little test here that loads two scripts that just insert content into divs. One is a common JS file and the other is a PHP file that waits 3 seconds to execute.
http://www.juandopazo.com.ar/tests/asyn-script-test.html
As you can see, scripts are executed when they finish loading, and not in the order in which you append them to the DOM, in every browser.