{"id":1045,"date":"2019-12-12T10:25:43","date_gmt":"2019-12-12T03:25:43","guid":{"rendered":"https:\/\/lab.wptips.dev\/?p=1045"},"modified":"2020-08-12T09:44:36","modified_gmt":"2020-08-12T02:44:36","slug":"lazyload-without-plugin","status":"publish","type":"post","link":"https:\/\/pixelstudio.id\/blog\/lazyload-without-plugin\/","title":{"rendered":"Implement Lazy-Loading without Plugin"},"content":{"rendered":"\n<p class=\"has-background has-light-yellow-background-color\"><strong>Update 11 Aug 2020<\/strong>: WordPress 5.5 introduced native lazy loading by adding <code>loading=\"lazy\"<\/code> attribute to all images. So you no longer need to create your own.<\/p>\n\n\n\n<p>Lazy-load is a way to prevent images from loading <strong>before we scroll past it<\/strong>. There are many plugins that help you with this, some themes even have a built-in lazy-load function.<\/p>\n\n\n\n<p>Here we will show you that it&#8217;s not hard to implement it yourself.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 1: Replace SRC Attribute<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"html\" class=\"language-html\">&lt;!-- Convert this -->\n\n&lt;img src=\"..\" srcset=\"...\">\n\n&lt;!-- into -->\n\n&lt;img data-src=\"...\" data-srcset=\"...\"><\/code><\/pre>\n\n\n\n<p>When an image has <code>src<\/code> or <code>srcset<\/code> attribute, it will always load no matter what. So our first step is to temporarily prefix them with <code>data-<\/code>.<\/p>\n\n\n\n<p>In WordPress, we can filter the content and replace them with regex:<\/p>\n\n\n\n<pre title=\"functions.php\" class=\"wp-block-code\"><code lang=\"php\" class=\"language-php\">add_filter( 'the_content', 'my_lazyload_content_images' );\nadd_filter( 'widget_text', 'my_lazyload_content_images' );\nadd_filter( 'wp_get_attachment_image_attributes', 'my_lazyload_attachments', 10, 2 );\n\n\/\/ Replace the image attributes in Post\/Page Content\nfunction my_lazyload_content_images( $content ) {\n  $content = preg_replace( '\/(&lt;img.+)(src)\/Ui', '$1data-$2', $content );\n  $content = preg_replace( '\/(&lt;img.+)(srcset)\/Ui', '$1data-$2', $content );\n  return $content;\n}\n\n\/\/ Replace the image attributes in Post Listing, Related Posts, etc.\nfunction my_lazyload_attachments( $atts, $attachment ) {\n  $atts['data-src'] = $atts['src'];\n  unset( $atts['src'] );\n  \n  if( isset( $atts['srcset'] ) ) {\n    $atts['data-srcset'] = $atts['srcset'];\n    unset( $atts['srcset'] );\n  }\n\n  return $atts;\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 2: Add Scroll Listener<\/h2>\n\n\n\n<p>When the image reaches your viewport, it should replace <code>data-src<\/code> into <code>src<\/code>, that way the image will start loading.<\/p>\n\n\n\n<pre title=\"js\/lazyload.js\" class=\"wp-block-code\"><code lang=\"javascript\" class=\"language-javascript\">( function() { 'use strict';\n  let images = document.querySelectorAll('img[data-src]');\n              \n  document.addEventListener('DOMContentLoaded', onReady);\n  function onReady() {\n    \/\/ Show above-the-fold images first\n    showImagesOnView();\n\n    \/\/ scroll listener\n    window.addEventListener( 'scroll', showImagesOnView, false );\n  }\n  \n  \/\/ Show the image if reached on viewport\n  function showImagesOnView( e ) {\n    \n    for( let i of images ) {\n      if( i.getAttribute('src') ) { continue; } \/\/ SKIP if already displayed\n      \n      \/\/ Compare the position of image and scroll\n      let bounding = i.getBoundingClientRect();\n      let isOnView = bounding.top >= 0 &amp;&amp;\n      bounding.left >= 0 &amp;&amp;\n      bounding.bottom &lt;= (window.innerHeight || document.documentElement.clientHeight) &amp;&amp;\n      bounding.right &lt;= (window.innerWidth || document.documentElement.clientWidth);\n      \n      if( isOnView ) {\n        i.setAttribute( 'src', i.dataset.src );\n        if( i.getAttribute('data-srcset') ) {\n          i.setAttribute( 'srcset', i.dataset.srcset );\n        }\n      }\n    }\n  }\n              \n})();<\/code><\/pre>\n\n\n\n<div class=\"wp-block-button aligncenter\"><a class=\"wp-block-button__link has-text-color has-black-color has-background has-yellow-background-color\" href=\"https:\/\/codepen.io\/hrsetyono\/pen\/LawrXW\" target=\"_blank\" rel=\"noreferrer noopener\">View the Demo in Codepen \u00bb <\/a><\/div>\n\n\n\n<p>Don&#8217;t forget to enqueue the script:<\/p>\n\n\n\n<pre title=\"functions.php\" class=\"wp-block-code\"><code lang=\"php\" class=\"language-php\">add_action( 'wp_enqueue_scripts', 'my_lazyload_assets', 10 );\nfunction my_lazyload_assets() {\n  $js_dir = get_stylesheet_directory_uri() . '\/js';\n  wp_enqueue_script( 'my-lazyload', $js_dir . '\/lazyload.js', [], '', true );\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 3: Add Animation<\/h2>\n\n\n\n<p>You can customize the animation purely with CSS. For example, here&#8217;s a simple fade-in effect:<\/p>\n\n\n\n<pre title=\"style.css\" class=\"wp-block-code\"><code lang=\"css\" class=\"language-css\">img[data-src] {\n  opacity: 0;\n  transition: opacity .25s ease-in-out;\n  will-change: opacity;\n}\n\n\/* appear animation *\/\nimg[data-src][src] {\n  opacity: 1;\n}<\/code><\/pre>\n\n\n\n<p>Feel free to change the transition timing to your taste and play around with  <code>translate<\/code>.<\/p>\n\n\n\n<hr class=\"wp-block-separator is-style-dots\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>Lazyload has become a necessity in all blogs and corporate websites. You don&#8217;t have to worry about SEO because Google themselves has confirmed that they can detect lazy-load.<\/p>\n\n\n\n<p>There&#8217;s nothing wrong with using a plugin for this feature, but it&#8217;s good to know how it&#8217;s done. You can also customize it to your needs like customizing the animation and adding a delay.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>If this code doesn&#8217;t work for you, please let us know in the comment below. It might clash with your themes or some plugins.<\/p><\/blockquote>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Update 11 Aug 2020: WordPress 5.5 introduced native lazy loading by adding loading=&#8221;lazy&#8221; attribute to all images. So you no longer need to create your own. Lazy-load is a way to prevent images from loading before we scroll past it. There are many plugins that help you with this, some themes even have a built-in lazy-load function. Here we will show you that it&#8217;s not hard to implement it yourself. Step 1: Replace SRC Attribute When an image has src or srcset attribute, it will always load no matter what. So our first step is to temporarily prefix them with\u2026<\/p>\n","protected":false},"author":1,"featured_media":1055,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[21,32],"class_list":["post-1045","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-frontend","tag-css","tag-javascript"],"blocksy_meta":{"page_structure_type":"default","page_enable_vertical_spacing":"yes","has_hero_section":"default","hero_section":"type-1","hero_alignment1":"left","hero_alignment2":"center","hero_height":"230px","page_title_bg_type":"color","02a8fa6fa9876ba502c3202f6b27ad07":"","custom_hero_background":{"attachment_id":null},"parallax":{"desktop":false,"tablet":false,"mobile":false},"5b8d22ec51745ed9aec4f44d54666ee4":"","single_meta_elements":{"author":true,"date":true,"categories":true,"comments":true,"updated":false,"tags":false},"has_meta_label":"yes","date_format_source":"custom","single_meta_date_format":"M j, Y","988b35874608d92291f1905aa170ac40":"","page_excerpt_visibility":{"desktop":true,"tablet":true,"mobile":false},"pageTitleFont":{"family":"Default","variation":"Default","size":{"desktop":"32px","tablet":"30px","mobile":"25px"},"line-height":"1.3","letter-spacing":"CT_CSS_SKIP_RULE","text-transform":"CT_CSS_SKIP_RULE","text-decoration":"CT_CSS_SKIP_RULE"},"pageTitleFontColor":{"default":{"color":"var(--paletteColor4)"}},"pageMetaFont":{"family":"Default","variation":"n6","size":{"desktop":"12px","tablet":"12px","mobile":"12px"},"line-height":"1.3","letter-spacing":"CT_CSS_SKIP_RULE","text-transform":"uppercase","text-decoration":"CT_CSS_SKIP_RULE"},"pageMetaFontColor":{"default":{"color":"CT_CSS_SKIP_RULEDEFAULT"},"hover":{"color":"CT_CSS_SKIP_RULEDEFAULT"}},"pageExcerptFont":{"family":"Default","variation":"n5","size":"CT_CSS_SKIP_RULE","line-height":"CT_CSS_SKIP_RULE.65","letter-spacing":"CT_CSS_SKIP_RULE","text-transform":"CT_CSS_SKIP_RULE","text-decoration":"CT_CSS_SKIP_RULE"},"pageExcerptColor":{"default":{"color":"CT_CSS_SKIP_RULEDEFAULT"}},"pageTitleOverlay":{"default":{"color":"rgba(41, 51, 60, 0.2)"}},"pageTitleBackground":{"default":{"color":"#EDEFF2"}},"5f8df4c48cd19093954a61d50db5dea2":"","8d8e3f260d203baa2aa5b722a1a32d7a":"","52da68576660da253aff2a33bf5f6d32":"","3a47c6acab67e788f48f928dfe8e7b4a":"","b16b8a2b3e50722cd89102ca04c5bf14":"","d8bc2d07d0a0e1fd76d931dfefdf512c":"","8a2feecddf56563a9519b2c24677c7f8":"","964e362cb16b959c0e66237d899d13fa":"","0e29092977bf8a2c10cef8d17c0f3bac":"","9fbb5cdda1f48376a22511c676fef27b":"","03a88afe547f064768068b66694155bf":"","49af1f85efc554c79dfbdf07f089ecef":""},"_links":{"self":[{"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/posts\/1045","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/comments?post=1045"}],"version-history":[{"count":10,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/posts\/1045\/revisions"}],"predecessor-version":[{"id":1852,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/posts\/1045\/revisions\/1852"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/media\/1055"}],"wp:attachment":[{"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/media?parent=1045"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/categories?post=1045"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/tags?post=1045"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}