Sunday, May 1, 2011

Lazy Load techniques .. another one hack ..

We have already seen few lazy load techniques here and here.  If we have large set of HTML , it takes so much time to load page.


Here is a trick that allows you to bundle all of your modules into a single resource without having to parse any of the JavaScript. Of course, with this strategy, there is greater latency with the initial download of the single resource (since it has all your JavaScript modules), but once the resource is stored in the browser's application cache, this issue becomes much less of a factor.

To combine all modules into a single resource, we wrote each module into a separate script tag and hide the code inside a comment block (/* */). When the resource first loads, none of the code is parsed since it is commented out. To load a module, find the DOM element for the corresponding script tag, strip out the comment block, and eval() the code. If the web app supports XHTML, this trick is even more elegant as the modules can be hidden inside a CDATA tag instead of a script tag. An added bonus is the ability to lazy load your modules synchronously since there's no longer a need to fetch the modules asynchronously over the network.

200k of JavaScript held within a block comment adds 240ms during page load, whereas 200k of JavaScript that is parsed during page load added 2600 ms. That's more than a 10x reduction in startup latency by eliminating 200k of unneeded JavaScript during page load! Take a look at the code sample below to see how this is done.



<html>
...
<script id="lazy">
// Make sure you strip out (or replace) comment blocks in your JavaScript first.
/*
JavaScript of lazy module
*/
</script>

<script>
  function lazyLoad() {
    var lazyElement = document.getElementById('lazy');
    var lazyElementBody = lazyElement.innerHTML;
    var jsCode = stripOutCommentBlock(lazyElementBody);
    eval(jsCode);
  }
</script>

<div onclick=lazyLoad()> Lazy Load </div>
</html>

2 comments:

  1. This may be one kind of lazy loading but may not be the best way to do it, better way is to keep the script in external file and attach it to the head node of html

    Eval is evil and better to avoid for following reasons,
    1.Improper use of eval opens up your code for injection attacks
    2.Debugging can be more challenging (no line numbers, etc.)
    3.eval'd code executes more slowly (no opportunity to compile/cache eval'd code)

    ReplyDelete
  2. @Jayasim:Thanks for comment. Actually here i am not posting best way of lazyloading. see my earlier posts where i explain another tricks about lazyloading js into HTML page. I agree that generate a script element and append it to document is best way but consider other cases as well where we served alot of external files on a page or we have alot of inline js legacy code in page etc also bandwidth cost,responsiveness. See following links ...

    http://ravirajsblog.blogspot.com/2010/12/another-hack-to-render-heavy-html-pages.html

    http://ravirajsblog.blogspot.com/2010/12/few-more-thoughts-on-script-loaders-in.html

    http://ravirajsblog.blogspot.com/2010/12/peoples-misguiding-behavior-about-front.html

    Now come to Eval. Yes you are right. See my post i have written in 2009. http://ravirajsblog.blogspot.com/2009/03/eval-is-evil.html
    (also read Ashish jain comments there :P) I think you forgot to mention why Eval slow actually eval() runs the interpreter/compiler in middle of run time.my opinion is that if you're parsing the formula, you might as well compute the result during the parse rather than run another parser (the one inside eval()). But it may be easier to code using eval(), and the performance hit will probably be unnoticeable. It looks like eval() in this case is no more evil than any other function that could possibly save you some time. here i presumed that you have written code in such way that you can filter "rm -rf something-important" such string literals.

    ReplyDelete