0

My aim was to async my external javascript so that the rendering of the website won't be blocked and of course as what async do, load the javascripts afterwards.

But the problem is that it seems like my external javascripts are totally prevented to load.

So here is a sample of my code (Not exact). When the user clicks add the input increments the number on a certain amount. It is from jquery where it gets its clicking and order.js to get the calculation

<!doctype html>
<html lang="en"> 
    <head>
        <script async src="/js/jquery.min.js"></script>
        <script async src="/js/order.min.js"></script>
    </head>
    <body>
        <p>Hello World</p>
        <input type ="text">
        <button id="add">+</button><button id="sub">-</button>
    </body>
</html>

The problem is that the clicking does not work and I don't know what to do.

I want to improve the loading time but async does not work for jquery. Because, without inputting async there should be a default value but when I add async no default value (value from order.js) and button does not work (jquery).

Update: I tried using "defer" but the problem is just the same as async. Buttons does not work for jquery and there is no default value for the input.

Kevz
  • 604
  • 2
  • 8
  • 23
  • 1
    `does not work` Can you explain? See http://idownvotedbecau.se/itsnotworking/ You might want to ensure jQuery loads before running `order` – CertainPerformance Aug 23 '18 at 08:04
  • 1
    Hope your jquery code in encapsulated by this. You can only do jquery stuff after loading jquery and other dependency. $(window).on("load", function(){$.ready.then(function(){ //Your code should be here }}); – amku91 Aug 23 '18 at 08:11
  • @amku91 What advantage should `$(window).on("load", function(){$.ready.then(` have? the `ready` event is fired the `load` event or at the same time. – t.niese Aug 23 '18 at 08:12
  • 2
    Possible duplicate of [Any way to control Javascript Async Load Order?](https://stackoverflow.com/questions/28893519/any-way-to-control-javascript-async-load-order) – t.niese Aug 23 '18 at 08:13
  • 2
    If you have two `async` scripts then those script should not depend on each other, because the execution order is not defined (the file that was loaded and parsed first will be executed first), use `defer` instead. – t.niese Aug 23 '18 at 08:14
  • @Kevz I hope you have attached an event handler for the button to perform click operations? – Sumodh Nair Aug 23 '18 at 08:56

2 Answers2

1

If this fails consistently (almost every time) then the problem is that order.min.js is smaller and is faster to load than jquery.min.js. This means that this:

    <script async src="/js/jquery.min.js"></script>
    <script async src="/js/order.min.js"></script>

ends up being this:

    <script src="/js/order.min.js"></script>
    <script src="/js/jquery.min.js"></script>

So order.min.js will try to use jquery functions before jquery is loaded. Which will obviously fail.

The fix is either make jquery load synchronously:

    <script src="/js/jquery.min.js"></script>
    <script async src="/js/order.min.js"></script>

Or wrap the code in order.min.js in something that will detect jquery:

// Inside order.js:
function wait_for_jquery () {
    if (window.jquery !== undefined) {

        // put the rest of the code for order.js here

    }
    else {
        setTimeout(wait_for_jquery,100); // check 10 times per second
    }
}
wait_for_jquery();

Another common technique is to use a bundler like webpack or browserify to compile both jquery and order.js into a single file

slebetman
  • 109,858
  • 19
  • 140
  • 171
1

Try defer

<script defer src="/js/jquery.min.js"></script>
<script defer src="/js/order.min.js"></script>

This prevents the scripts from blocking the page and load them in order