jQuery / JavaScript - Loading iframe with Ajax slows down page - javascript

I'm loading a iframe with $.ajax():
$("#iframe_wrapper").each(function(){
$.ajax({
type: "post",
url: "http://site.com",
data: { action: 'get_the_iframe' },
context: this,
success: function(html){
$(this).html(html);
$(this).show();
$('#theiframe').load(function(){
// do stuff with the iframe...
});
}
});
});
the iframe is inside a function that gets called if $_POST['action'] is 'get_the_iframe':
<iframe id="theiframe" name="theiframe" src="http://site.com/page/"></iframe>
it works, but the problem is that the browser seems to display the entire page really slow, it seems like it waits for the iframe to load before displaying the entire content on the page, which is not supposed to happen because it's done trough ajax. This is exactly what I was trying to avoid...
Any ideas what's wrong here?

I think the key to the answer is where, or more specifically, when your jQuery fragment that performs the ajax post is being run by the browser.
I suspect the jQuery code to load the page happens sometime before the full page has loaded. And maybe your browser doesn't support asynchronous loads from the same domain.. This was the case with IE for a long time. So what's going on is the browser starts loading and processing the iframe somewhat in-step with the rest of the requests that your normal (outer) page is doing.
If this is not the case yet try putting the code that starts the ajax post in a document ready handler.
Also, check in other browsers to see if the problem occurs across the board.

The reason why you are seeing this is because IFrame is blocking element, especially in IE. IFrames are the most costly element to create in a browser, and it also will block execution of JavaScript when it's being created. There's also resource blocking rule regarding IFrame as well. If you have CSS files in your page, IFrame will not load until response for each and every CSS file is received by the browser (IE) or in Firefox, all IFrame's resources will be blocked until response is received for all resources on the main page.
Just as an example, I had a standard spinner control, that would display running snake whenever I do AJAX call to the server (to give user some feedback that something is happening). I also was create IFrame element at the body level, to overlay all dropdown elements on the page for IE6/7 bleed through bug. At some point I noticed that my web-service calls where about twice slower in IE then they were in FF. After some investigation, I realized that creation of the IFrame element is blocking everything in the browser, including code that receives response from the server.
I don't think there's a way around it, except for not using IFrames...

Related

Ajax form, .load() method doesn't work on Safari Mobile

I've created an Ajax Login form and once the user correctly inserts the right credentials, the page should refresh (without reload) just only the top bar (which is different in case of logged-in or guest users). So I've just inserted this piece of code on success:
success: function(data){
$("#navigation").load(location.href + " #header");
}
which represents the #navigation area inside the #header block to refresh.
Now, in my case .load() is correctly working cross all browser except for Safari Mobile. EDIT: My problem is that in Safari Mobile it gets stuck. I don't see the block refreshing but if I reload the page I'm actually logged. So I suppose that there is a problem with the .load() method.
Is there something missing or should I use another method?
PS. I'm not using jQuery mobile because basically the website was already built. I've tried to implement it but I should fix a lot of issues in case. So I'd avoid that solution, not for now at least.

Why might an ajax-based page load be slower than a full load?

I've been working for a few months on loading most pages of our website with ajax, using jQuery and history.js (https://github.com/browserstate/history.js). Technically this has been working very well, there are no serious issues. The basic process is:
bind handlers to clicks
on clicks, prevent default and do a History.pushState
Then on statechange:
scroll to top, showing a loading animation
hide the main content div, then erase it's contents with a .empty()
run the ajax request ($.post to the target URL)
when data is received, put it in the main content div, show that div, and hide the loading animation
Note that I'm specifically changing the request to a post instead of a get, because I need to send a post flag telling the server that this is an ajax request, so it knows to only return the necessary content.
However, google analytics reports that the page load times are, on average, about 1 second longer for users with ajax browsing turned on (I'm doing a 50/50 split test).
For a while I assumed this was just inaccurate reporting, because I've read that google's speed reports can get very screwed up by one or two visitors from across the globe who get longer load times.
Today I opened two browser windows side by side (chrome and chrome incognito) and clicked around the site, and sure enough the window using ajax did have somewhat slower load times. It wasn't consistent, sometimes it was faster, but never by a lot. When it was slower, it was significantly slower. Usually this happened when the ajax request just seemed to be slow (the loading animation remained visible for an extra second or so). Meanwhile the full load window had consistent load times.
I can't imagine why this would be the case. The ajax request should always be faster. Anyone encounter this before and discover the same thing?

image load event on IE

I am developing a site, and I have to set the src of the not found images, to an error image.
the methods .load() and .error() works always except in IE.
I have been searching, and I have found this:
Issue with IE not calling JQuery .load() function on page refresh - traced to image caching
Adding the query string to the image, always loads it from server, and .load() and .error() methods works properly, however the site is quite too big, and I really can't load all images in site every time from server, without loading it from cache.
Any ideas of how make work this methods, without load from server every time the images for IE, or other way to check if image has been loaded correctly or not that work in IE?
Thanks in advance
This is a very old bug that actually was fixed in all modern browsers except IE.
They didn't trigger onload event if image was obtained from cache.
But there is a workaround that is well-known by every person who tried to create an image gallery in javascript a couple of years ago:)
Image DOM element has a property .complete that indicates whether image was loaded or not. You can check this property on script load. If image is in the cache img.complete will return true right after page loaded:
$('img').each(function(){
//this code will not run in IE if image is in the cache
$(this).on('load', function(){
checkImage(this);
});
//this code will run if image is already in the cache
if (this.complete) checkImage(this);
});
function checkImage(){
//your code for checking image
}
Do you have access to the server? A better method may be using .htaccess to rewrite all requests for images to a PHP script, and then if the image is not found, serve the image not found image

Do <iframes> and images loaded via AJAX delay window.onload?

I'm trying to make the window.onload event fire sooner so that Google will think my page loads faster (this is a frustrating task since how long it takes to get to window.onload is basically irrelevant from the user perspective, but I digress)
However, I don't know what delays the onload event! Specifically:
If I load a Facebook likebox on my page in an <iframe>, does its loading delay the onload event? What about if the likebox iframe has to load a bunch of profile pics; does onload wait until they fully load?
Suppose that on document ready I do an async AJAX request for an HTML blob and inject it into the page. If this HTML blob contains a bunch of <img> tags, does the onload event wait for all of these to load?
In general, how does the browser know when to fire the onload event? What sorts of things block onload, and what sorts of things don't?
a) You can't control window.onload except by reducing the page "weight". Its up to the browser to decide when its going to declare that event.
b) Google doesn't have a clue about the window.onload event because its not parsing JavaScript.
1) You can completely eliminate the Facebook payload by using XFBML version of the like button and asynchronous loading of the Facebook JavaScript SDK (http://developers.facebook.com/docs/reference/javascript/FB.init/). Do note that it will work only if JavaScript is enabled.
2) Everything that is going to dramatically increase the weight of your web page should be loaded asynchrouniusly, preferably after the window.onload event has fired.
If you look at the waterfall, in firebug or chrome inspector, iframe and ajax calls does affect the onload event. I ran into similar problem with facebook considerably slowing down site. Yes, while looking at pageload time in webmaster tool, it shows the lag.
My solution was to dynamically append facebook iframe when the page is completely loaded. and for ajax calls, i only trigger them on load.
This brought my page load time from 7 seconds with embedded facebook iframe, to 2.6 seconds with dynamically appending it.

How to trigger click-to-call with javascript (iphone)

I have a link in a mobile webpage that needs to track an advertiser clickTag and then activate click-to-call.
I've got the tracking working but I don't know how to trigger the tel:1800123456; with javascript. Any ideas? This is not a web app; it's a standard html page. I can use jQuery.
Update
Just calling window.open("tel:num"); after adding a tracking iframe on click was not reliable enough because sometimes the call dialog box would open before the iframe had finished loading.
window.open("tel:num"); also opens a new window then opens the call dialog box, which isn't a great user experience on iphone 3gs/4.
Do you have any control over the tracking iframe? If so, you could call a function which makes the window.location call once it's loaded. Something like
$(document).ready(function() { window.iframe_loaded(); });
in the iframe code (if it has jQuery), and a function in your main script called iframe_loaded which does the window.location call.
If you can't set the code within the iframe but can edit the iframe container code, then you could do this...
<iframe id="whatever" onload="iframe_loaded();" width="400" height="200"></iframe>
...so the onload calls iframe_loaded() which does window.location...
If you don't have control over the iframe or its content, then easy kludge would be to just wrap the window.location call in a timeout, i.e.
setTimeout('window.location="tel:18001234567";', 500);
The 500 at the end will delay it by half a second. (Increase it if your iframe is slow to load.) It's not as elegant, but might work fine and users probably won't notice a small delay!
Have you tried window.open(url); where the url is "tel:18001234567" ?
Seems like that should work, right?

Categories