kubetail-org / loadjs

A tiny async loader / dependency manager for modern browsers (961 bytes)
MIT License
2.58k stars 151 forks source link

Support "defer" as well as "async"? #92

Open asos-tomp opened 5 years ago

asos-tomp commented 5 years ago

It might be nice if this could handle defer scripts as well as async, as an option.

e.g. having a consolidated interface to allow notification either type of scripts being parsed. Would allow async scripts to wait on defer ones, etc.

amorey commented 5 years ago

Let me think about this some more... in the mean time you can use the before callback to set the defer attribute:

loadjs(['/path/to/foo.js', '/path/to/bar.js'], {
  success: function() {},
  error: function(pathsNotFound) {},
  before: function(path, scriptEl) {
    scriptEl.setAttribute('defer', 'defer');
  }
});
asos-tomp commented 5 years ago

Yep - I guess this is a similar request to https://github.com/muicss/loadjs/issues/84 - if there's an easy way to set those flags innately in the library, would prevent a lot of extra boilerplate needed in consumers. And should hopefully be a tiny change?

wellington1993 commented 5 years ago

@asos-tomp @amorey

I think something like:

    { success:function(){}, async: true, defer: false, crossorigin: "anonymous",
      importance: "high" }

Adding native way to set defer, async, crossorigin and importance...

My real example:

<script defer importance="low">
  loadjs(
    ["https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css",
     "https://cdn.jsdelivr.net/npm/roboto-fontface-woff@latest/css/roboto/roboto-fontface.min.css"],
    { success:function(){}, async: true, defer: false, crossorigin: "anonymous",
      importance: "high" }
  );
  loadjs(
    ["https://cdn.jsdelivr.net/npm/jquery@latest/dist/jquery.min.js",
     "https://cdn.jsdelivr.net/combine/npm/short-and-sweet@latest/dist/short-and-sweet.min.js,npm/jquery-vjs-rails@latest/src/rails.min.js,npm/bootstrap@latest/dist/js/bootstrap.bundle.min.js,npm/plyr@latest/dist/plyr.min.js,npm/clipboard@latest/dist/clipboard.min.js,npm/jquery-mask-plugin@latest/dist/jquery.mask.min.js",
     "https://cdnjs.cloudflare.com/ajax/libs/vanilla-masker/1.2.0/vanilla-masker.min.js",
     "/javascripts/footer.js"],
    { success:function(){}, async: false, defer: true, crossorigin: "anonymous",
      importance: "low" }
  );
</script>

I have some assets do defer and some to load async.

Thanks!

amorey commented 5 years ago

I did some browser testing and found that when you add a <script> tag dynamically (e.g. document.head.appendChild(scriptEl);) the file gets loaded after the DOMContentLoaded event fires even if async=false. Since this is the method that LoadJS uses, this means that the defer attribute won't have an impact on files loaded with LoadJS.

wellington1993 commented 5 years ago

Thanks!@amorey

How about crossorigin and importance?

amorey commented 5 years ago

Currently, you can add crossOrigin manually using the before() method. I'm not familiar with the importance attribute. Can you refer me to some documentation about it?