Save 37% off PRO during our Black Friday Sale! »

How late is later? A lazy loading solution on the edge between very clever and incredibly mad.

How late is later? A lazy loading solution on the edge between very clever and incredibly mad.

Reducing the loading time of a web application is a well known problem. Developers need to make sure the browser only downloads the code that is strictly necessary to bootstrap the application and leave the rest for later. This is what we commonly call lazy loading.

But when is later? When is the right time to lazy load?

When users interact with our applications there is a good chance they won't use all the provided features. Why lazy load code that is not needed then? Front-end code can be logically split into 3 sets:

Code required to bootstrap.
Code needed for the core functionality. It should be lazy loaded as soon as the bootstrap code has been delivered and parsed.
Code that may not even be necessary, or that is required only when a particular feature is used, and is therefore strictly dependent on the actions users perform within the context of the application. This means that this code can/should be loaded on demand.
This talk shows how JavaScript code - functions and objects - can be delivered to the browser on demand, thus reducing the perceived loading time of a web application.

Video here: http://www.ustream.tv/recorded/25243564

Aa41c3413b4416a280e0516cae4ceb7b?s=128

Massimiliano Marcon

September 07, 2012
Tweet

Transcript

  1. How late is later?

  2. A lazy loading solution on the edge between very clever

    and incredibly mad." " Massimiliano Marcon" @mmarcon" " frontendconf.ch • September 7th 2012
  3. What I do at Nokia Maps

  4. I " LAZY " LOADING

  5. WTF !!1!!<script!type="text/javascript"!src="jquery.min.js"></script>! !! !!2!!<script!type="text/javascript"!src="jquery:ui.min.js"></script>! !! !!3!!<script!type="text/javascript"!src="externals/jquery.fupload.js"></script>!! !!4!!<script!type="text/javascript"!src="externals/json.support.js"></script>! !! !!5!!<script!type="text/javascript"!src="externals/extend.native.js"></script>!!! !!6!!<script!type="text/javascript"!src="externals/jquery.tiptip.min.js"></script>!!!

    !!7!!<script!type="text/javascript"!src="externals/jquery.fancytabs.js"></script>!! !!8!!<script!type="text/javascript"!src="api/objects.js"></script>! !! !!9!!<script!type="text/javascript"!src="editor.js"></script>! !! !10!!<script!type="text/javascript"!src="urlcreator.ext.js"></script>! !! !11!!<script!type="text/javascript"!src="parsers.js"></script>! !! !12!!<script!type="text/javascript"!src="main.js"></script>!!! !13!!<script!type="text/javascript"!src="messages.js"></script> !!
  6. Not good either !1!<script!type="text/javascript"!src="my_whole_app_is_packed_here.js"></script>! !!

  7. The problem The amount of code the browser loads affects

    performance and influences the perceived loading time.
  8. LESS CODE TO LOAD

  9. Is all that code really necessary? NO!

  10. THE STORY OF A HAPPY USER

  11. I, as a user… Open my browser and start typing

    a URL in my address bar.
  12. Bootstrap ASAP 1!

  13. Dude, that was fast!

  14. 2! Enrich the Experience

  15. 3! Load remaining code on demand

  16.  Load shims on demand

  17. 1!Bootstrap ! 2!Enrich! 3!On Demand!

  18. WHERE EVERYTHING BEGAN

  19. None
  20. …possibly load UI components on demand •  What does on

    demand mean?
  21. “In distributed computing, code on demand is a general term

    for any technology that sends executable software code from a server computer to a client computer upon request from the client's software” ― Wikipedia
  22. HOW CAN WE DO IT?

  23. Require.js Modules ON DEMAND Dependencies

  24. callback-require !1!!require(['require',! !! !2!!!!!!!!!!!'modules/3rd:party/jquery'],!function(require,!$)!{! !! !3!!!!!!$('button').on('click',!function(e){! !! !4!!!!!!!!!!require(['modules/dialog'],!function(dialog){! !! !5!!!!!!!!!!!!!!dialog.create($('<p>Hello!world</p>'),!'My!Dialog');!

    !! !6!!!!!!!!!!});! !! !7!!!!!!});! !! !8!!});!!
  25. callback-require for shims !!1! !require(['require',! !! !!2! !!!!!!!!!!'modules/3rd:party/jquery'],!function(require,!$)!{! !! !!3!

    !! !! !!4! !!!!!var!SUPER_DUPER_APP!=!function(JSON){! !! !!5! !!!!!!!!!//Do!some!fancy!stuff!here!with!my!application.! !! !!6! !!!!!!!!!//At!this!poit!all!JSON.parse/JSON.stringify!will!be!available!for! !! !!7! !!!!!!!!!//ALL!browsers.!Isn't!that!cool?!! !! !!8! !!!!!};! !! !!9! !! !! !10! !!!!!if(typeof!JSON.parse!===!'function')!{!!! !11! !!!!!!!!!//Oh,!we've!got!native!JSON!support! !! !12! !!!!!!!!!SUPER_DUPER_APP(JSON!/*Native!one*/);! !! !13! !!!!!}! !! !14! !!!!!else!{! !! !15! !!!!!!!!!//Uhmm...!I!smell!IE!<!8! !! !16! !!!!!!!!!require(['shims/json'],!function(){! !! !17! !!!!!!!!!!!!!//No!need!to!use!parameters,!this!shim!just!creates! !! !18! !!!!!!!!!!!!!//a!global!JSON!object.! !! !19! !!!!!!!!!!!!!SUPER_DUPER_APP(JSON!/*Shimmed!one*/);! !! !20! !!!!!!!!!});! !! !21! !!!!!}! !! !22! !}); !!
  26. CLEVERNESS or MADNESS?

  27. Custom solution !1!!$(function(){! !! !2!!!!!!$('button').on('click',!function(e){! !! !3!!!!!!!!!!$.onDemand.use('dialog').done(function(dialog){! !! !4!!!!!!!!!!!!!!dialog.create($('<p>Hello!world</p>'),!'My!Dialog');! !!

    !5!!!!!!!!!!});! !! !6!!!!!!});! !! !7!!});!!
  28. How does this work? !!1! !OnDemand.prototyte.firstLoad!=!function(fn,7args,7context){! !! !!2! !!!!!var!script,!deferred!=!$.Deferred(),!rv;!!! !!3!

    !! !! !!4! !!!!!if!(isFn(that._proxy[fn]))!{! !! !!5! !!!!!!!!!rv!=!that._proxy[fn].apply(context,!args);! !! !!6! !!!!!!!!!deferred.resolve(rv);! !! !!7! !!!!!}! !! !!8! !!!!!else!if(isObj(that._proxy[fn]))!{! !! !!9! !!!!!!!!!deferred.resolve(that._proxy[fn]);! !! !10! !!!!!}! !! !11! !!!!!else!{! !! !12! !!!!!!!!!script!=!this.fn2script(fn);! !! !13! !!!!!!!!!if!(!script)!{! !! !14! !!!!!!!!!!!!!return;! !! !15! !!!!!!!!!}! !! !16! !!!!!!!!!$.getScript(script).done(function(){!!! !17! !!!!!!!!!!!!!var!rv;! !! !18! !!!!!!!!!!!!!if!(isFn(that._proxy[fn]))!{! !! !19! !!!!!!!!!!!!!!!!!rv!=!that._proxy[fn].apply(context,!args);! !! !20! !!!!!!!!!!!!!}! !! !21! !!!!!!!!!!!!!else!if!(isObj(that._proxy[fn]))!{! !! !22! !!!!!!!!!!!!!!!!!rv!=!that._proxy[fn];! !! !23! !!!!!!!!!!!!!}! !! !24! !!!!!!!!!!!!!deferred.resolve(rv);! !! !25! !!!!!!!!!}).fail(function(){! !! !26! !!!!!!!!!!!!!deferred.reject('OnDemand!failed!to!load!script!'!!+!script);! !! !27! !!!!!!!!!});!!! !28! !!!!!}! !! !29! !!!!!return!deferred.promise();! !! !30! !};! !!4! !!!!!if!(isFn(that._proxy[fn]))!{! !! !!5! !!!!!!!!!rv!=!that._proxy[fn].apply(context,!args);! !!6! !!!!!!!!!deferred.resolve(rv);! !! !!7! !!!!!}! !! !!8! !!!!!else!if(isObj(that._proxy[fn]))!{! !! !!9! !!!!!!!!!deferred.resolve(that._proxy[fn]);!!! !10! !!!!!}!! !16! !!!!!!!!!$.getScript(script).done(function(){! !! !17! !!!!!!!!!!!!!var!rv;! !! !18! !!!!!!!!!!!!!if!(isFn(that._proxy[fn]))!{! !! !19! !!!!!!!!!!!!!!!rv!=!that._proxy[fn].apply(context,!args);!!! !20! !!!!!!!!!!!!!}! !! !21! !!!!!!!!!!!!!else!if!(isObj(that._proxy[fn]))!{! !! !22! !!!!!!!!!!!!!!!!!rv!=!that._proxy[fn];! !! !23! !!!!!!!!!!!!!}! !! !24! !!!!!!!!!!!!!deferred.resolve(rv);! !! !25! !!!!!!!!!})!
  29. PERFORMANCE

  30. “0.1 second is about the limit for having the user

    feel that the system is reacting instantaneously…” ― Nielsen, Usability Engineering
  31. Let’s relax the definition of" on demand •  On demand

    is not strictly on click. •  On demand is right before we expect the code to be needed.
  32. BEYOND MADNESS

  33. window.performance !1! !//!returns!a!duration!in!milliseconds! !! !2! !function!getUserPerceivedLoadingTime()!{! !! !3! !!!return!!! !4!

    !!!!!window.performance.timing.loadEventStart!!! !5! !!!!!!:!window.performance.timing.navigationStart;! !! !6! !}; !! http://j.mp/w3c-window-performance
  34. Q&A

  35. DO IT. DO IT WISELY.

  36. If you are interested in these slides and some other

    material related to this presentation just follow @mmarcon." Feedback: http://j.mp/rate-mmarcon
  37. Thank you.