Search code examples
javascripthtmlcore-web-vitals

Is there any advantage to add 'defer' to a new script tag after $(document).ready()?


I have some javascript that is not required for my initial page load. I need to load it based on some condition that will be evaluated client-side.

$(document).ready(function() {
  let someCondition = true; // someCondition is dynamic
  if (someCondition) {
    var element = document.createElement('script');
    element.src = 'https://raw.githubusercontent.com/Useless-Garbage-Institute/useless-garbage/master/index.js';
    element.defer = true; // does this make a difference?
    element.onload = function() {
      // do some library dependent stuff here
      document.getElementById("loading").textContent = "Loaded";
    };
    document.body.appendChild(element);
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1 id="loading">Loading...</h1>

Does it make a difference (in terms of how browser will treat the script tag), if a new tag created using javascript, after document is ready, has 'defer' attribute or not? I think there is no difference, but how can I say for sure?

I believe I understand how deferred scripts behave when script tag is part of the initial html (as described here). Also, this question is not about whether element.defer=true can be used or not (subject of this question).


Solution

  • No that doesn't make any difference, the defer attribute is ignored in case of "non-parser-inserted" scripts:

    <script defer src="data:text/javascript,console.log('inline defer')"></script>
    <script>
      const script = document.createElement("script");
      script.src = "data:text/javascript,console.log('dynamic defer')";
      script.defer = true;
      document.body.append(script);
    </script>
    <!-- force delaying of parsing -->
    <script src="https://deelay.me/5000/https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

    Look at your browser's console or pay attention to the logs timestamps to see that the dynamically inserted script actually did execute while we were waiting for the delayed script to be fetched.