0

I have been reading up about using async on script calls in a page header on HTML5 to make script loading not hold up the rest of the page.

So I set out something like

 <script src="/includes/js/modernizr-2.6.2.min.js" async></script> <script src="/includes/js/jquery-1.11.0.min.js" async></script> <script src="/includes/js/tinymce/tinymce.min.js" async></script> <script> $( document ).ready(function() { tinymce.init({ mode : "specific_textareas", editor_selector : "mceEditor", plugins: [ "advlist autolink autosave lists link image" ], toolbar1: "insertfile undo redo", image_advtab: true, paste_as_text: true }); /* <other jQuery page specific scripts here too> */ }); </script> 

But this comes back with various errors:

  • JQuery $ is not recognised for the document call.
  • tinyMCE jquery method tinymce.init is not recognised

So obviously, I remove the async calls from the script links - and this works, but what's the point of the whole async stuff on page loads, when I can not call any JQuery method or function until jquery.js has to be loaded first and then each .js file also has to be loaded non-asynchronously before the relative methods can be run in the page script (or attached scripts) on document load.

I read a lot about how async is good for AJAX but after changing async to defer I find this also does not solve my problem, returning with the same console errors.

Is there something fundamental that I'm not doing? Or is it that asynchronous script loading is simply not to be done on basic non AJAX page loads?

Edit: With the scripts as they are page loading is roughly +4 seconds, mostly due to tinyMCE with all it's plugins, hence I have attempted to try and load the addons etc, with async...

6
  • There are some scripts I async and some I don't. If you have a js file that just holds a bunch of functions, then you can defer. If you need jQuery to load your page, async won't work. However you can just put all your js in the footer and basically it will load last and won't prevent page loading. Commented Aug 28, 2015 at 17:42
  • I think I'm trying to have the $( document ).ready(function() not fire until the scripts are all loaded, which in effect is as you say, non-asychronous and so should be in the footer. :-/ Commented Aug 28, 2015 at 17:49
  • If you aren't bringing in external scripts you could use vanilla JS to do a XHR request to load your js files, and when complete fire a custom event to init all your stuff. Seems a bit overkill. Just throw it all in the footer, don't use async, and load jQuery first. The DOM will load, and scripts will all load just fine. There are plenty of articles and a few tools for loading jquery via async, but seems a bit overkill honestly. Commented Aug 28, 2015 at 17:52
  • The only time async has worked successfully for me is using it before the closing </body> tag. It allowed my script to execute seamlessly with the AJAX calls. Commented Aug 28, 2015 at 17:53
  • cheers for your guidance, I'm putting the scripts at the bottom of the page. I edited my question to show the primary reason for trying to use async being that tinyMCE with all its plugins is quite a slow loader. Commented Aug 28, 2015 at 17:56

2 Answers 2

1

It's not that it jQuery can't be loaded async it's that it's not really conducive to how people generally organize their javascript. There are some articles and tools that can solve the problem (http://www.yterium.net/jQl-an-asynchronous-jQuery-Loader) but it's generally simpler to load your javascript at the bottom of your page as the last thing that loads. This will at the least load your DOM first and not stop any visual loading while the libraries load. As long as you load jQuery before your scripts requiring it, all will go well.

Note, if your scripts affect page layout you will get a flicker/flash/adjustment when those scripts run since most content will be present when the adjustments are made. In your case, tinyMCE will fire after the textarea is visible typically adjusting after the fact.

Sign up to request clarification or add additional context in comments.

Comments

1

I needed to pass Google's pagespeed test. So here is what I did to load jquery async and all the scripts/code that depend on it so loading is not blocking. If jquery is not loaded, it will wait. If jquery is loaded, it will load or execute the code immediately.

<script> var rdy=[],jqloaded=false; function doscript(a){ if(typeof a=="function"){ (a)(); } else { $("head").append('<script src="'+a+'"></script>'); } } function jqrdy(){ if(typeof $=="undefined"){ setTimeout(jqrdy,10); return; } $(document).ready(function(){ jqloaded=true; for (var i=0;i<rdy.length;i++){ doscript(rdy[i]) } }); } jqrdy(); function rdypush(a){ if(!jqloaded){ rdy.push(a); } else { doscript(a); } } </script> <script src="/js/jquery-3.3.1.min.js" async></script> <script> rdypush("/js/jquery-ui.min.js"); rdypush("/js/bootstrap.min.js"); rdypush("/js/tinymce/tinymce.min.js"); rdypush(function(){ console.log("I'm Ready"); }); </script> 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.