SitePoint Sponsor

User Tag List

Results 1 to 7 of 7
  1. #1
    SitePoint Guru
    Join Date
    Dec 2005
    Posts
    982
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [jQuery] Speeding up document.ready()

    I have a script on a website that uses some non-obtrusive javascript to ajaxify some product information (basically you give it a widget in black, it will show you the widget in black, white and red).

    The unfortunate thing is that since the script patiently waits for the DOM to be ready, sometimes it takes a couple seconds before it gets to run (I have a third party script that is laggy on occasion). This becomes a problem when a user starts to interact with the screen before it has "changed".

    My first question is if there a way that I can safely run this script without waiting for the DOM to load completely?

    My second question is since I have identified this third party script as making this problem worse, is there a way to make that script wait to load? Currently I inject that script using the .ready() as well, but it seems to fire off first in the .ready() "list".

    Some code to show what I mean:
    Code JavaScript:
    //this is somewhere in the middle of the <body> tags
    jQuery(document).ready(init_product_information);
     
    //this is the last thing before the </body>
    jQuery(document).ready(function() {
    jQuery('#footer-seals').html('<iframe src="..."></iframe>');
    });
    The only thing hard to show here is that init_product_information() calls another function (product_load_colors()) which is loaded via an external js that is technically after the "problem script".



    P.S. I would gladly show you my site since this is getting kind of harder to explain, but it has to be via PM because I don't want my account linked to the website.
    MySQL v5.1.58
    PHP v5.3.6

  2. #2
    SitePoint Enthusiast
    Join Date
    Sep 2008
    Posts
    26
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Couple of things -- first great you are using jQuery... your life is already better...

    1. If your "Ajaxification" - as you call it - does not ALTER exiting DOM elements - then you can safely run your script before DOM ready. To to this - I usually put the script right at the end of my document - before the closing </body> tag - so most of the DOM is in fact loaded... and run the script there.

    NOTE - since you'll be firing off an AJAX call you may need to set a timer on your success callback?

    Again - if you modify the DOM before DOM ready - YOU WILL CRASH Internet Explorer... not a good outcome.

    2. To your second question - YES you can tame that 3rd party script! (Usually)... If it is an Ad Display Code - then you have it easy... Just load the Ad into and IFRAME... and your main document will not consider this to be a "hold up" for ONDOMREADY any more...

    Note - if the script is for Google Ads... you may get public service ads for a while if you put it in an IFRAME - this is because it will at first not get the "context" of what page it is on... You can put keyword content on the Iframe page (out of sight), or just wait... Google will catch on in time...

    If it is for other non contextual ads - then you are home free... check the code provider - they may even provide IFRAME enabled tags for you to use.

    Another Note - if the script is a real library of functions - that you need to use - like a plug in or something, try hosting it elsewhere - or host it yourself to speed up your site...

    Finally - don't host jQuery yourself... let Google do that for you - 1 less HTTP request to your web server... use a tag like this to load it...

    <script type="text/javascript" src="url to jquery on google/jquery/1.2.6/jquery.min.js"></script>


    Hope that helps!

  3. #3
    SitePoint Guru
    Join Date
    Dec 2005
    Posts
    982
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    1. The ajaxification does (heavily) alter the DOM. I know that firing it off before the DOM was finished can crash IE, but I wasn't sure if there was a way to make it cut in line so that it is the first thing fired off once the page is ready. Maybe that's a clearer way to phrase that first post?

    2. The 3rd party script is a site seal (SSL), and I have already tried really hard to tame it, but it hasn't worked. Currently, I use js to inject the iframe which loads the ext js file (so the code goes like this: jQuery('#ele').html('<iframe ... ></iframe>'); . and the iframe has really simple html including the <script src=...> tag. Unfortunately, in IE and FF, it is affecting the DOM! (and it's pretty easy to see that because this script can take 2+ seconds to run on bad days)

    We host our own js library because I don't want to be reliant on google code being up for our site to work. 1 additional request on our dedicated server shouldn't be a problem
    MySQL v5.1.58
    PHP v5.3.6

  4. #4
    SitePoint Enthusiast
    Join Date
    Sep 2008
    Posts
    26
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    A few more thoughts:

    1. For the site seal - can you simply delay loading it? Is it critical to have the site seal visible instantly? I would just set a timer and use jQuery $.getScript() to load it. If it uses document.write() to emit the seal - then you could still inject it in the IFRAME. Just include an $.documet.ready() function in the document loaded in the iframe - then in that ready function.... set a timer of a few seconds (play with it), something like this:

    Code:
    $(init);
    function init() 
    { 
       setTimeout(loadSeal,3000);
    }
    function loadSeal()
    {
         $.getScript(urlOfScript, callback);
    }
    That would all be on the document loaded in the iframe - then the iframe should fire "Loaded" quickly - and your Main document should fire "Loaded" quickly...


    2. On the Ajaxification - if you use $.documet.ready() or the shortcut $(readyFunction)... it should fire that function right away when the Dom is loaded... you should not see much delay unless you run some other very intensive script before you fire off the Ajax call.

    3. On the browser crash - you can try to avoid it -- If instead of $(functionReady). you put a setTimeout(functionReady,100) -- or other small delay - and include the script right before your closing </body> tag -- the parts of your DOM that you modify with the results of the AJAX will be fine... and the browser wont crash. Only thing to realize is it is not an absolute guarantee... some users - especially with slower computers or slow connections, could run into a problem. So the finesse may work for 80% of your users 80% of the time, but you may or may not be ok with that. Up to you...

    On the Google code... all i can say is wow... if you run more reliable servers than google then hats off to ya
    Last edited by kburb23; Sep 24, 2008 at 09:01. Reason: added code tags

  5. #5
    SitePoint Enthusiast
    Join Date
    Sep 2008
    Posts
    26
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If the $.getScript() does not work after the timer in the document loaded by the IFRAME... you might try simply setting the "scr" attribute of the IFRAME after a delay in your main document script... (or setting it's HTML if you prefer). So this time in your main document.

    Code:
    $(init)
    function init()
    {
        // do your Ajaxification first
        setTimeout(loadSeal,3000);
    }
    
    function loadSeal()
    {
          $("#iframElementId")[0].src = "url of the script";
          or
          $("#iframeElementId").html("<iframe src='url of script'></iframe>");
    }

    and of course if the Seal Script uses document.write() then you would have to do all of this inside the IFRAME document, to avoid blowing away your main document.
    Last edited by kburb23; Sep 24, 2008 at 09:02. Reason: code tags

  6. #6
    SitePoint Guru
    Join Date
    Dec 2005
    Posts
    982
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You're a genius and I appreciate the code. Here's what I went with (in the iframe page):
    Code JavaScript:
    //<![CDATA[
    if(typeof window.jQuery == "function") {
    	jQuery(document).ready(function() { 
    		setTimeout(function() {
    				jQuery.getScript(slowSiteSealUrl);
    			}
    			, 1000);
    	});
    }
    //]]>
    So far 1 second seems like plenty of time. I may up it to 1500 just to be save, I haven't decided yet.

    Thank you very much

    EDIT: As usual, I got excited too soon. It seems that anytime I use setTimeout(), the browser hangs after the timeout function is called. Even if I don't use the timeout to include a file, the browser reaches "ready", waits, fires the timeout, and then stays in the loading stage indefinitely. I tried using clearTimeout, but the only way to stop the browser is to hit Esc. Is there something off with my code? I seem to remember having this problem before, but I don't know what fixes this.
    MySQL v5.1.58
    PHP v5.3.6

  7. #7
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,702
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    One of the best practices for speeding up your web site is to place scripts at the bottom. Not only does this improve page loading performance, but it also means that you can immediately work with the DOM.

    Code html4strict:
    <html>
    <head>
    </head>
    <body>
    ...
    <script>
    </script>
    </body>
    </html>
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •