Optimizing my web application using Flash, Javascript and JSP - 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

Related

JavaScript code runs 3-4 secs and disables browser during that

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.

Save and load entire web page state (Visual HTML, And javascript Variables)

So lately I've been working on this project, which will end at the end of January (end of this week).
http://www.nikollr3.three.axc.nl/ (this is a preview of the program a few months ago, but u get an idea)
We have started testing the website and noticed that it was sometimes making Firefox crash.. since Firefox' error or crash reports were never of any use (no useful information found), I have no idea how to fix this error. And a possible solution would be to have a save / load button on the web page, which can save or load a state (and for example autosave state untill it crashes) then when it crashes you would be able to reload the last state and continue working on the project. By saving a 'state' I mean recreating the EXACT moment as to when the save button was clicked, thus same javascript variable values and same HTML looks.
I have found little things about this on the internet, the only one relevant being for android phones,.. Any ideas or implementations?
write all your variables and "HTML looks" (attributs) to a XML-file. load (if (exist(XML)pseudo-code) all necessary data onPageLoad

Can I put impose a time limit on JavaScript (e.g., using an iframe)?

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.

Google AdSense JavaScript causing multiple page-loads?

Update
Ok - I now know where the multiple page loads are coming from! (However, the mystery is not yet solved).
It seems that immediately after a request is made to a page containing AdSense ads, Google makes a request for exactly the same URL (one or more times)
e.g. this is what the logs look like (note requests from Mediapartners-Google):
2011-07-20 09:50:20 xxx.xxx.xxx.xxx GET /requestedURL/ 80 - xxx.xxx.xxx.xxx Mozilla/5.0+(Browserstring removed) 200 0 0 1140
2011-07-20 09:50:20 xxx.xxx.xxx.xxx GET /requestedURL/ 80 - 66.249.72.52 Mediapartners-Google 200 0 64 218
2011-07-20 09:50:22 xxx.xxx.xxx.xxx GET /requestedURL/ 80 - 66.249.72.52 Mediapartners-Google 200 0 0 171
(I should have paid more attention to the IIS logs, rather than my own application logs - it just didn't occur to me that these multiple, identical, simultaneous request could have been coming from different sources). This also explains why I couldn't find anything strange when analysing the request with WireShark, and why fiddler didn't show anything strange.
So the question for the bounty now becomes:
Why is google making these requests so quickly after the page is requested? (I know they need to asses the page for content, but immediately after, and multiple times sees like abuse to me.)
What can I do to stop this?
And out of interest:
Has anyone else seem something similar in their logs? (or is this something weird with my AdSense account)
Ok, I'll apologise in advance for the length!...
This question is realted to this one, regarding Google Adsense Javascript code causing errors. (of the form Unable to post message to googleads.g.doubleclick.net. Recipient has origin something.com)
I won't duplicate all of the information there, but the conclusion seems to be that the AdSense JS is buggy. (please read the question for background if you have time).
I knew about this problem for some time, but decided to live with the JS errors rather than pulling AdSense from the site.
However, Recently I noticed that in my ASP.NET MVC2 application, Controller Actions seemed to be called twice per page request (sometimes even 3 times). Odly, it was only happening on the production server. After some thought I relalised that one difference between the Dev and Production environments was that the AdSense javscript was only active in production.
To test this I removed all adsense code from one of the production pages, and lone behold, the multiple-page-load problem went away!
I thought that perhaps it was the fact that there were general JS errors on the page that was causing the problem, so to test this I introduced some simple errors into my own JS code, however this did not cause the multiple-page-load problem to reappear.
One known situation where pages can be called multiple times per request is when there are image tags with empty src attributes, or external resource references with empty src attributes. Crucially, The most upvoted answer to the AdSense JS Bug question notes that:
"The targetOrigin argument in this call, this.la is set to
http://googleads.g.doubleclick.net. However, the new iframe was
written with its src set to about:blank."
This seems eerily similar to the empty src issue.... This seems too much of a co-incidence, and currently I'm of the opinion that this is the problem.
[EDIT: This was a red herring]
However, I've no idea wehre to go from here. These multiple action calls are causing real problems (I'm having to use code blocking, serialised transactions, and all sorts of nasty hacks to limit adverse effects). Of course, I could be barking up the wrong tree entirely - I'm puzzled that I can't find any other references to this, given the ubiquity of AdSense, and the nature of the problem (but then again the conclusions of the AdSense JS Bug question are also surprising). I would love this to turn out to be a stupid mistake on my part, so I need a sanity check.
I'd like to ask the community:
Has anyone else experienced this problem?, or can anyone who is using AdSense replicate and confirm it? [See note below]
Assuming the problem is what it seems, what can I do? (other than pulling AdSense of course)
If not, then what might be causing this?
To Sumarise:
- My actions are being executed 2 (sometimes 3) times per page request.
THIS ONLY HAPPENS WHEN GOOGLE ADSENSE ADS ARE PRESENT
I removed all AdSense JS and introduced an error into my own JS : Actions are called only once...
A similar problem can happen when empty src properties are present on the page
An answer to a previous question sumarises that the AdSense JS sets a src="about:blank" on an iFrame
I have come to the conclusion that the src="about:blank" from the AdSense code is the most likely source of the problem.
If I disable JavaScript on the browser, the problem goes away
Just to document the things I have ruled out:
This is happening across browsers: Chrome(12) Firefox(5) and IE(8).
I have dissabled all plugins on browsers (YSlow, Firebug etc...)
There are no empty src (src=""/src="#") for images, or other external resources in the html in my code
There are no empty url references in the css ( url('') )
It's unlikely to be server side code/config problem, as it doesn't happen in Dev (and of the few differences between dev and production is the absence of AdSence JS in Dev)
Note: For anyone looking to replicate this, it should be noted that, strangely, when the multiple action calls happen Fiddler shows only one request being sent to the server. I have no idea why this should be the case, but the server logging doesn't lie :) Perhaps someone who has prior experience with this problem when caused by empty src attributes in img tags can say whether they have seen the same behaviour with Fiddler.
Requested extra information
HTML (#Ivan)
Here's how I'm implementing the Adsense (ids removed)
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<div class="ad">
<%if (!HttpContext.Current.IsDebuggingEnabled) { %>
<script type="text/javascript"><!--
google_ad_client = "ca-pub-xxxxxxxxxxxxxxx";
/* xxxxxxxxxxxxxxx */
google_ad_slot = "xxxxxxxxx";
google_ad_width = 728;
google_ad_height = 15;
//-->
</script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<%} else { %>
<img src="/Content/images/googleAdMock728x15_4_e.gif" width="728" height="15" />
<%} %>
</div>
This is being inserted by a RenderPartial in the View:
<% Html.RenderPartial("AdSense_XXXXXX"); %>
TCP Logging (#Tomas)
So far I have done a wireshark capture:
on client when requesting page on production with problem
on client when requesting page on production without problem (i.e. Adsense Removed)
I can't really see a significant difference between the two (although my network skills are not great). One thing to note is that they both seem to have a TCP retransmittion of the HTTP request immediately after the initial request - I don't know the significance of that. I can confirm though that in case 1 the server logs reported 2 executions, and in case 2 only one execution.
Next I will try TCP logging on the server side in both cases, and post results here.
Mediabot is the name given to the web crawler that Google uses to crawl webpages for purposes of analysing the content so Google AdSense can serve contextually relevant advertising to the page.
In my experience, it is impredictable and, yes , it can be pretty heavy and annoying.
If you don't want Mediapartner bot to access a specific page, you can disallow it in your robots.txt with:
#
# disallow adsense bot
#
User-agent: Mediapartners-Google
Disallow: path to your specific page
This will have the drawback of service untargeted ads from that specific page.
If you are seeing this pattern always on the same page with different query string, adding the canonical rel could ease the pain.
If you can't resolve this issue, and you see it as an abuse, don't esitate to ask help in the Crawling Indexing and Ranking Google support.
Given that the behaviour that you are observing appear to be hard to avoid, can we rather focus on workarounds?
Can you differentiate requests based on UserAgent, and thus filter out requests.
Could that be a viable approach for you?
If so then you could probably base upon this approach: http://blog.flipbit.co.uk/2009/07/writing-iphone-sites-with-aspnet-mvc.html
Here they detect iPhones, but the consept is the same for Mediapartners-Google bot.
Aside from the embedding of the AdSense code itself, there are two things related to AdSense that differ in your two test cases:
What else happens when !HttpContext.Current.IsDebuggingEnabled? This appears to be the de-facto production flag; maybe there is some other nuance somewhere that is happening that depends on this same flag.
Is it possible that Html.RenderPartial("AdSense_XXXXXX") is somehow causing your Controller to jump back to the beginning of its execution?
From your description, it seems like the execution is happening twice on the server but only one request is being sent from the client. This implies a server error, and these two lines are the crux of your AdSense triggering. To further narrow it down, try embedding the AdSense partial directly instead of calling Html.RenderPartial(). If that doesn't change the result, it might be worth a sanity check on what else switches on HttpContext.Current.IsDebuggingEnabled.
Failing that, it might be helpful to know whether your server-side logging takes place as the request is received, before the response is sent, or after the response is sent.
Yes, I just detected this during a TeamView session with my partner. On my box my main page ONLY for my site loads once per request.
Then by coincidence while using Fiddler my partner is getting 4 requests to the sample page. It is a 1.5 MB page with big scripts and lotsa other dependencies so this was truly a WTF moment as I have never seen anything like this in 15 years of web development.
If google is doing this I must say they should realize today's sites might have very big pages and very big audiences. That could mean they are jacking bandwidth by a factor of 4 per request. Like I said, WTF?????
I wish this Q&A had a more definitive resolution.
I do use Google Translate widget but this is only occurring on his box and for the main page. The other pages also use the translate widget and I do request my JQUERY via the google CDN. Could anything Google be doing this.

HTML Offline Application Cache, Listing Downloaded Files

As part of a loading screen for an offline-enabled web application I'm building (using a cache manifest), I'd like to display an accurate progress bar that lets users know which files has thus far been downloaded and which are still pending. Something like the following:
Loading...
/assets/images/logo.png: loaded
/assets/images/splashImage.png: pending
I know that I can use the cache "pending" event, but I don't see that the event arguments have any data associated with them.
Is there any way to do this?
There is a progress event that gets triggered when each file downloads, however its payload does not include the file name in any browser that I've tested with (Chrome, Safari, FF beta). Chrome displays the file name in the Console (though as far as I know it's inaccessible to JS), but neither Safari nor FF even go that far. And from what I've seen, the files do not download in the same order that they're listed in the manifest, so there's not even a way to generate an ordered list then knock them off one at a time.
So in answer to your question, no, there isn't any way to do this right now. It's possible that in the future the progress event will include the filename - at least in some browsers - but right now this isn't possible.
I should add that in Chrome (not in Safari or FF) you can at least get a count of files to be downloaded, allowing you to at least calculate an accurate progress bar. To get this in Chrome you'd use the following:
function downloadProgress(e) {
totalfiles = Number(e.total);
}
window.applicationCache.addEventListener("progress", downloadProgress, false);
However this will error out in other browsers, so you need to wrap a try/catch or some other method (typeof(e.total)) to avoid the error.
This is a few years late, but maybe it'll help someone else who's researching this.
It doesn't list the files or anything, but it shows an accurate(ish) progress bar based on the total number of files loaded. It may still need a little work...
https://github.com/joelabeyta/app-cache-percent-bar

Categories