How to Defer Inline JavaScript

How to defer inline Javascript?

The scripts with the defer attribute load in the order they are specified, but not before the document itself has been loaded. As defer has no effect on script tags unless they also have the src attribute, the first script that gets executed is your inline script. So at that time jQuery is not loaded yet.

You can solve this in at least two ways:

  • Put your inline script in a .js file and reference it with a src attribute (in addition to the defer attribute which you already had there), or

  • Let your inline script wait for the document and the deferred scripts to be loaded. The DOMContentLoaded event will fire when that has happened:

    <script>
    window.addEventListener('DOMContentLoaded', function() {
    (function($) {
    //do something with b-lazy plugin, lightbox plugin and then with flexslider
    })(jQuery);
    });
    </script>

NB: Notice that in the latter case $(document).ready(function() is not included any more, as that would wait for the same event (DOMContentLoaded). You could still include it like you had in your original code, but then jQuery would just execute the callback immediately, which makes no practical difference.

Can i use defer attribute in inline js?

It's not possible. Per MDN:

defer: This attribute must not be used if the src attribute is absent (i.e. for inline scripts), in this case it would have no effect.

For the functionality you want, you'll have to do one of the following:

  • Put the script into a separate file and set a src
  • Put the inline script at the end of the <body>
  • Wrap the whole code of the script inside a DOMContentLoaded listener

Defer inline javascript execution?

It would be much better if you could place your javascript at the end of the document. Sprinkling your source with small inline javascript snippets is a killer on page performance.

That said, you could create an array and push functions on this array. Then, at the end of your page, right after you load jquery, loop over the array and execute each function.

E.g.:

<html>
...
<script>window.loadEvents = [];</script>
...
<script>loadEvents.push(function() { alert("inline code here"); });</script>
...
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>$.each(loadEvents, function(_,f) { f(); });</script>
</html>

However - as I said - it would be better to just push all the script elements into the bottom of the page, instead of switching back and forth between html and javascript. The rendering performance will be severely degraded, if you do this.

Script defer doesn't seem to work as expected

defer only works on external scripts:

This attribute must not be used if the src attribute is absent (i.e. for inline scripts), in this case it would have no effect.

To achieve a similar effect for dynamically inserted scripts use async=false instead. Scripts with the defer attribute will execute in the order in which they appear in the document.

Also,

Scripts without async or defer attributes, as well as inline scripts, are fetched and executed immediately, before the browser continues to parse the page.

Because local scripts are executed before the page finishes parsing, defer will not apply. defer gets applied after parsing, but before DomContentLoaded.

How to use defer for inline Javascript

One option would be to concatenate all scripts in a single script using Gulp.

That way you wouldn't have this problem and also wouldn't have to open multiple browser connections to download multiple js files.

gulp concat scripts in order?

Also you get the message below when you try to use Jquery but it is not loaded yet:

ReferenceError: $ is not defined


Related Topics



Leave a reply



Submit