{"id":1772,"date":"2013-10-09T22:11:17","date_gmt":"2013-10-09T22:11:17","guid":{"rendered":"http:\/\/www.sitekickr.com\/blog\/?p=1772"},"modified":"2013-10-12T10:30:51","modified_gmt":"2013-10-12T10:30:51","slug":"lazy-definition-load-javascript","status":"publish","type":"post","link":"https:\/\/www.sitekickr.com\/blog\/lazy-definition-load-javascript\/","title":{"rendered":"Using Lazy Definition to load JavaScript libraries on demand"},"content":{"rendered":"<p>I&#39;ve been told on more than one occasion not to spend too much time perfecting the performance on a website or app before gauging consumer interest. In other words, don&#39;t spend time hyper-optimizing something that hasn&#39;t yet proven it&#39;s worth. Only after a project has taken off does it warrant your valuable time for performance tuning.<\/p>\n<p>That is one philosophy. The other way of thinking is the &quot;now or never&quot; approach. If you don&#39;t optimize all your code as you go along, you may very well never afford the time to do it again. If your app takes off, you&#39;ll be too busy handling feature requests to revisit that old sloppy code you wrote just to get the project out the door faster.<\/p>\n<p>Regardless of the stance you take, some optimizations are so simple to implement and provide such a dramatic performance enhancement that they&#39;re hard to overlook, even in a time crunch.<\/p>\n<p>One optimization that fits this description is <strong>lazy definition<\/strong>. If you&#39;re already familiar with the term, then you may be wondering how it can improve performance in any significant way. This brings us to another concept called <strong>lazy loading<\/strong>. They sound similar, right? But, they&#39;re actually two different techniques that can work together to improve the load time of a website.<\/p>\n<p>&nbsp;<\/p>\n<h3>Lazy Definition<\/h3>\n<div class=\"post-aside\">\n<h4>Is Lazy the right word?<\/h4>\n<p>I&#39;m not one to argue with the terminology set forth by our computer science pioneers, but&#8230; When I think about the term lazy, poor coding practices or inefficient algorithms come to mind.<\/p>\n<p>I could just as easily call the old array <a href=\"http:\/\/en.wikipedia.org\/wiki\/Bubble_sort\" rel=\"nofollow\">bubble sorting<\/a> method &quot;Lazy Sorting&quot;. So, you could see how this terminology could easily confuse a programmer who is first hearing about this technique. The term &quot;Lazy Loading&quot; doesn&#39;t quite convey the fact that a function is redefining itself to execute in a more optimized way the next time it&#39;s called.<\/p>\n<p>A better term might be &quot;On-Demand Definition&quot;. It doesn&#39;t carry the same ring, but it&#39;s a little more accurate as to what&#39;s actually happening.<\/p>\n<\/div>\n<p>Because of JavaScript&#39;s liberal nature, you&#39;re actually able to let a function definite itself. It defines itself by replacing it&#39;s own code, once it executes for the first time. Let&#39;s demonstrate this with an example:<\/p>\n<pre class=\"prettyprint\" style=\"width: 300px;\"><code>myFunction = function () {\r\n    if (browser === &#39;IE&#39;) {\r\n        myFunction = function() {\r\n            return &#39;This is IE.&#39;;\r\n        }\r\n    }\r\n    else if (browser === &#39;Chrome&#39;) {\r\n        myFunction = function() {\r\n            return &#39;This is Chrome&#39;;\r\n        }\r\n    }\r\n}<\/code><\/pre>\n<p>So what&#39;s going on here when <em>myFunction <\/em>is executed?<\/p>\n<ol>\n<li>A conditional checks a variable which indicates which type of browser is being used.<\/li>\n<li>Depending on the result, myFunction is redefined, replacing the entire code within myFunction<\/li>\n<\/ol>\n<p>Essentially, once <em>myFunction <\/em>is called (let&#39;s say browser = &#39;IE&#39;), it is now defined as:<\/p>\n<pre><code>myFunction = function() {\r\n    return &#39;This is IE.&#39;;\r\n}<\/code><\/pre>\n<p>After a single call to the function, it self-optimizes by removing the unnecessary conditional.<\/p>\n<div>Okay, cool, I guess. But, how do we use that to improve page load time in a significant way? That&#39;s where <strong>lazy loading<\/strong> comes in.<br \/>\n\t&nbsp;<\/div>\n<div><a href=\"http:\/\/www.sitekickr.com\/blog\/wp-content\/uploads\/2013\/10\/function-lazy-definition.png\"><img loading=\"lazy\" alt=\"function lazy definition\" class=\"alignnone size-full wp-image-1816\" height=\"230\" src=\"http:\/\/www.sitekickr.com\/blog\/wp-content\/uploads\/2013\/10\/function-lazy-definition.png\" width=\"600\" srcset=\"https:\/\/www.sitekickr.com\/blog\/wp-content\/uploads\/2013\/10\/function-lazy-definition.png 600w, https:\/\/www.sitekickr.com\/blog\/wp-content\/uploads\/2013\/10\/function-lazy-definition-300x115.png 300w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/a><\/div>\n<div>&nbsp;<\/div>\n<h3>Lazy Loading<\/h3>\n<div class=\"post-aside\">\n<h4>When to use Lazy Loading<\/h4>\n<p>Lazy loading sounds so good that you might be tempted to use it as a rule, rather than when it makes the most sense. Here are a few tips that might help:<\/p>\n<h5>Use Lazy Loading when<\/h5>\n<ul class=\"checks\">\n<li>Only a small percentage of your visitors will require that the library be loaded<\/li>\n<li>The loading condition is based on a user&#39;s action, such as clicking a link<\/li>\n<li>The library to be loaded is large and will take time to load and execute (be sure to offer a spinner or other progress bar to your user)<\/li>\n<\/ul>\n<h5>Do not use Lazy Loading when<\/h5>\n<ul class=\"exes\">\n<li>The majority of your users will require a library<\/li>\n<li>Other portions of your code will require using the library, regardless of user action<\/li>\n<li>The library to be loaded is small and executes quickly. In this case, you should minify and merge it into your main JavaScript file.<\/li>\n<\/ul>\n<\/div>\n<p>If you&#39;ve read about lazy loading, you&#39;ll find that there are two definitions floating around. The first, which I consider to be inaccurate, refers to lazy loading as the act of loading a JavaScript library asynchronously and as late as possible. This implies that the library will always be loaded whether it&#39;s actually used or not.<\/p>\n<p>The second definition, which is more accurate, refers to loading the library only when it&#39;s needed. Another term to describe this is <strong>on-demand<\/strong>.<\/p>\n<p>This sounds great, doesn&#39;t it? Why wouldn&#39;t we do this for every library that we need to load? The reason is, loading a library requires an HTTP connection, which requires a lag time. If a user were to click a link, then have to wait for a library to load before something happened, that wouldn&#39;t be a good experience.<\/p>\n<p>Consideration should be taken when using lazy loading. Use it when a library is used only by a small percentage of your users. For instance, let&#39;s say have a link in the footer of your website which causes a lightbox to load. If this link is seldom used, and is the only link that requires a lightbox, you might consider lazy loading the lightbox library.<\/p>\n<p>&nbsp;<\/p>\n<h3>Combining Lazy Loading with Lazy Definition<\/h3>\n<p>So we now know that lazy loading can enhance performance, and through lazy definition we can &quot;improve&quot; a function&#39;s implementation when it&#39;s called for the first time. It&#39;s only natural to combine these two techniques into a powerful method for loading a JavaScript library on-demand.<\/p>\n<p>In the example below, I demonstrate this concept with <a href=\"http:\/\/www.jacklmoore.com\/colorbox\/\" rel=\"nofollow\" target=\"_blank\">Jack Moore&#39;s Colorbox jQuery plugin<\/a>. In this case, I have a link on the page which is not only seldom used, but is the only link which needs to open in a lightbox. Naturally, I don&#39;t want to load the lightbox library with every page load if it will only be used 1% of the time.<\/p>\n<p>Instead, I&#39;ll wrap the $.colorbox function in my own function, which on first call will load the library, then pass the parameters on to the $.colorbox function. Afterwards, the function redefines itself to simply call the $.colorbox function (essentially removing the AJAX call to load the library).<\/p>\n<p>&nbsp;<\/p>\n<pre class=\"prettyprint\"><code>myColorbox = function(args) {\r\n    $.ajax({\r\n         url: &#39;\/\/cdn.jsdelivr.net\/colorbox\/1.4.4\/jquery.colorbox-min.js&#39;,\r\n         cache: true,\r\n         dataType: &#39;script&#39;,\r\n         complete: function() {\r\n             $.colorbox(args);\r\n             myColorbox = function(args) {\r\n                 $.colorbox(args);\r\n             }\r\n         }\r\n    });\r\n}<\/code><\/pre>\n<p>&nbsp;<\/p>\n<p>Using this method, I never need to concern myself with whether or not the library is available, the function takes care of that for me by replacing itself using lazy definition. In any situation, I can simply call the function:<\/p>\n<pre><code>myColorbox( { href: &#39;http:\/\/www.sitekickr.com\/&#39;, \r\n              iframe: true, \r\n              width: 500, \r\n              height: 500, \r\n              opacity: .5 } );<\/code><\/pre>\n<p>All the work of loading the library first and prevent an attempt to load the library again is done when the function redefines itself on the first call.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>With the number of amazing JavaScript libraries out there, it&#8217;s tempting to overload our pages with http connections that load these scripts and immediately execute them. We can spare our user&#8217;s bandwidth and page load time by combining two popular techniques.<\/p>\n","protected":false},"author":1,"featured_media":1817,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"amp_status":""},"categories":[239,5,41],"tags":[218,151,128],"_links":{"self":[{"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/posts\/1772"}],"collection":[{"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/comments?post=1772"}],"version-history":[{"count":23,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/posts\/1772\/revisions"}],"predecessor-version":[{"id":1822,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/posts\/1772\/revisions\/1822"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/media\/1817"}],"wp:attachment":[{"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/media?parent=1772"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/categories?post=1772"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/tags?post=1772"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}