Delay the execution of a simple inline script or lazy load – Defer.js

Super tiny script to efficiently load JavaScript. as per Google’s PageSpeed Insights, loading your deferred JavaScript also means no blocking, your browsing experience needn’t wait for code you may not need yet.

You need to load this library only once on a page, ideally right after the opening <head> tag:

<!DOCTYPE html>
<html>
<head>
    <title>My awesome page</title>
    <script type="text/javascript" src="//raw.githubusercontent.com/shinsenter/defer.js/master/defer.min.js"></script>
</head>
<body>
 
</body>
</html>

Because the minified version is super tiny (less than 500 bytes), you can inline its content directly into the HTML document and avoid the network request.

Defer a inline script block

Delay the execution of a simple inline script (and also complex inline scipt) for 2 seconds.

defer(function() {
    alert("This message is shown after 2 seconds since 'onload' event.");
}, 2000);


Real life example: lazy-load your images without using jQuery

// here is a simple inline code block
var lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));
 
if ("IntersectionObserver" in window) {
    var lazyImageObserver = new IntersectionObserver(function(entries, observer) {
        entries.forEach(function(entry) {
            if (entry.isIntersecting) {
                var lazyImage = entry.target;
                lazyImage.src = lazyImage.dataset.src;
                lazyImage.srcset = lazyImage.dataset.srcset;
                lazyImage.classList.remove("lazy");
                lazyImageObserver.unobserve(lazyImage);
            }
        });
    });
    lazyImages.forEach(function(lazyImage) {
        lazyImageObserver.observe(lazyImage);
    });
}
 
// You can try wrap your code in a function, then pass it to defer() like this
 
function lazyLoadImages() {
    var lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));
    if ("IntersectionObserver" in window) {
        var lazyImageObserver = new IntersectionObserver(function(entries, observer) {
            entries.forEach(function(entry) {
                if (entry.isIntersecting) {
                    var lazyImage = entry.target;
                    lazyImage.src = lazyImage.dataset.src;
                    lazyImage.srcset = lazyImage.dataset.srcset;
                    lazyImage.classList.remove("lazy");
                    lazyImageObserver.unobserve(lazyImage);
                }
            });
        });
        lazyImages.forEach(function(lazyImage) {
            lazyImageObserver.observe(lazyImage);
        });
    }
}
 
defer(lazyLoadImages);
 
// ... or put them together like this
 
defer(function() {
    var lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));
    if ("IntersectionObserver" in window) {
        var lazyImageObserver = new IntersectionObserver(function(entries, observer) {
            entries.forEach(function(entry) {
                if (entry.isIntersecting) {
                    var lazyImage = entry.target;
                    lazyImage.src = lazyImage.dataset.src;
                    lazyImage.srcset = lazyImage.dataset.srcset;
                    lazyImage.classList.remove("lazy");
                    lazyImageObserver.unobserve(lazyImage);
                }
            });
        });
        lazyImages.forEach(function(lazyImage) {
            lazyImageObserver.observe(lazyImage);
        });
    }
});

Delay loading Google Publisher Tag script for 1 second (to prevent advertisement iframes that may block rendering).

deferscript('//www.googletagservices.com/tag/js/gpt.js', 'gpt-js', 1000);

That is simple, isn’t it?

Delay loading Facebook, Twitter scripts for 2 second (social widgets usually are expensive resources).

deferscript('//connect.facebook.net/ja_JP/sdk.js#xfbml=1&version=v2.5', 'facebook-jssdk', 2000);
deferscript('//platform.twitter.com/widgets.js', 'twitter-wjs', 2000);

It saves huge amount of HTTP requests. Don’t worry, all of your loved social widgets work well 2 seconds later.

We also lazy-load 3rd-party library’s JavaScript and CSS. Thanks to highlightjs for a lightweight, extensible syntax highlighter.

<script type="text/javascript">
deferstyle('https://highlightjs.org/static/demo/styles/tomorrow.css', 'highlightjs-css', 1000);
deferscript('https://highlightjs.org/static/highlight.site.pack.js', 'highlightjs-api', 1000, function() {
    document.querySelectorAll('pre code').forEach(function(block) {
        hljs.highlightBlock(block);
    });
});
</script>


Example: Lazy-load iframes (Youtube videos) with CSS effect.

<style type="text/css">
.fade {
    transition: opacity 500ms ease;
    opacity: 0;
}
 
.fade.show {
    opacity: 1;
}
</style>
 
<iframe class="video fade"
    data-src="https://www.youtube.com/embed/Uz970DggW7E"
    frameborder="0" width="560" height="315" allowfullscreen
    allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"></iframe>
 
<script type="text/javascript">
deferiframe('video', 100, 'loaded', function(frame) {
    frame.onload = function() {
        frame.classList.add('show');
    }
});
</script>

See live demo and download source code.

This awesome plugin is developed by shinsenter. Visit their official github repository for more information and follow for future updates.