Personal blog written from scratch using Node.js, Bootstrap, and MySQL. https://jrtechs.net
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

185 lines
5.8 KiB

  1. # Background
  2. The concept of lazy loading is a design pattern where you only download the required scripts/content when the client needs it rather than when the page is loaded.
  3. The most iconic example is the "infinite" feed that social media sites like Instagram use.
  4. Rather than dump a ton of content to the client at once, Instagram dynamically loads more content once you reach the end of the page.
  5. This allows websites to save bandwidth by only sending the client what they need when they need it.
  6. When a youtube video is embedded into a website, it pulls a ton of scripts which are required to play the video.
  7. However, when you embed a youtube video on a blog post, most people are not going to watch that video.
  8. Even if the visitor wanted to watch that video, there is no reason why all the scripts should be loaded when you initially land on the page.
  9. Rather than embed the video normally, you can instead simply have a the thumbnail of the video with a play button on it.
  10. When the client clicks the play button, the youtube scripts are then loaded.
  11. # Performance Without Lazy Loading
  12. ![Before Performance Score](media/youtubeLazyLoading/beforeTable.png)
  13. ![Before Table Analysis of embedded youtube videos](media/youtubeLazyLoading/before3.png)
  14. A very basic blog post with two Youtube videos is **1.5 MB** in size.
  15. That is a rather large page for a client to download and render.
  16. Notice that 65% of the content by size is from Youtube and 29 requests were from Google domains.
  17. # Performance with Lazy Loading
  18. ![After Performance Score](media/youtubeLazyLoading/afterTable.png)
  19. ![After Table Analysis of embedded youtube videos](media/youtubeLazyLoading/after2.png)
  20. After lazy loading Youtube videos I was able to reduce the size of this blog post by nearly 1 MB.
  21. This also decreased the page load time by 75%.
  22. Additional tests show's that each embedded youtube video consumes around 500 KB.
  23. Using the lazy loading method you can slash that 500 KB to a mere 100 KB-- size of just the thumbnail.
  24. # Code Used
  25. ## Javascript
  26. This is some basic JavaScript code which selects all of the "youtube" embedded videos on our page and adds a play button handler.
  27. When the button is clicked, it updates the div to have an Iframe with the appropriate embedded youtube video.
  28. If you are already using jQuery, you could use that but, I did not since the **goal** of this is to optimize the page load time.
  29. The [jQuery library](https://mathiasbynens.be/demo/jquery-size) is nearly 50 KB.
  30. ```javascript
  31. <script>
  32. ( function() {
  33. var youtube = document.querySelectorAll( ".youtube" );
  34. for (var i = 0; i < youtube.length; i++) {
  35. var source = "https://img.youtube.com/vi/"+ youtube[i].dataset.embed +"/sddefault.jpg";
  36. var image = new Image();
  37. image.src = source;
  38. image.addEventListener( "load", function() {
  39. youtube[ i ].appendChild( image );
  40. }( i ) );
  41. youtube[i].addEventListener( "click", function() {
  42. var iframe = document.createElement( "iframe" );
  43. iframe.setAttribute( "frameborder", "0" );
  44. iframe.setAttribute( "allowfullscreen", "" );
  45. iframe.setAttribute( "src", "https://www.youtube.com/embed/"+ this.dataset.embed +"?rel=0&showinfo=0&autoplay=1" );
  46. this.innerHTML = "";
  47. this.appendChild( iframe );
  48. } );
  49. };
  50. } )();
  51. </script>
  52. ```
  53. ## CSS
  54. This CSS defines how the embedded youtube video looks before you click the play button.
  55. ```CSS
  56. .wrapper {
  57. max-width: 680px;
  58. margin: 60px auto;
  59. padding: 0 20px;
  60. }
  61. .youtube {
  62. background-color: #000;
  63. margin-bottom: 30px;
  64. position: relative;
  65. padding-top: 56.25%;
  66. overflow: hidden;
  67. cursor: pointer;
  68. }
  69. .youtube img {
  70. width: 100%;
  71. top: -16.82%;
  72. left: 0;
  73. opacity: 0.7;
  74. }
  75. .youtube .play-button {
  76. width: 90px;
  77. height: 60px;
  78. background-color: #333;
  79. box-shadow: 0 0 30px rgba( 0,0,0,0.6 );
  80. z-index: 1;
  81. opacity: 0.8;
  82. border-radius: 6px;
  83. }
  84. .youtube .play-button:before {
  85. content: "";
  86. border-style: solid;
  87. border-width: 15px 0 15px 26.0px;
  88. border-color: transparent transparent transparent #fff;
  89. }
  90. .youtube img,
  91. .youtube .play-button {
  92. cursor: pointer;
  93. }
  94. .youtube img,
  95. .youtube iframe,
  96. .youtube .play-button,
  97. .youtube .play-button:before {
  98. position: absolute;
  99. }
  100. .youtube .play-button,
  101. .youtube .play-button:before {
  102. top: 50%;
  103. left: 50%;
  104. transform: translate3d( -50%, -50%, 0 );
  105. }
  106. .youtube iframe {
  107. height: 100%;
  108. width: 100%;
  109. top: 0;
  110. left: 0;
  111. }
  112. ```
  113. ### Example
  114. <youtube src="DoDaHmyIPvQ" />
  115. ## HTML
  116. Rather than use the embed code that youtube provides, you have to use the following code to integrate with the CSS and JS written.
  117. All you need from the youtube video is the ID which appears in the link associated with that video.
  118. ```HTML
  119. <div class="wrapper">
  120. <div class="youtube" data-embed="DoDaHmyIPvQ">
  121. <div class="play-button"></div>
  122. </div>
  123. </div>
  124. ```
  125. ## Node Templating Stuff
  126. When witting blog posts in Markdown, it is not convenient to include 5 lines of HTML to embed a video.
  127. On my node server I wrote some code to convert a simpler "youtube tag" into the 5 lines of HTML shown above.
  128. This is completely optional.
  129. ```javascript
  130. //regular expression to detect custom youtube video tag
  131. //<youtube src="" />
  132. var re = /\<youtube .*?>/;
  133. //result is a string which contains a HTML document
  134. while (result.search(re) != -1)
  135. {
  136. var ytid = result.substring(result.search(re) + 14, result.search(re)+ 11 + 14);
  137. var youtubeHTML = "<div class=\"wrapper\">\n" +
  138. "\t<div class=\"youtube\" data-embed=\"" +
  139. ytid +
  140. "\" />\n" +
  141. "\t\t<div class=\"play-button\"></div>\n" +
  142. "\t</div>\n" +
  143. "</div>\n";
  144. var original = "<youtube src=\"" + ytid + "\" />";
  145. result = result.split(original).join(youtubeHTML);
  146. }
  147. ```