How to load multiple files from CDNs asynchronously (but execute them synchronously)?

user1111929

When downloading multiple commonly used javascript/css files (e.g. boostrap and jquery), many topics like this one recommend the use of a CDN, with one of the main arguments that it can then be used to load them asynchronously.

How does that work? To the best of my knowledge, <script> tags in the header are read synchronously, so it won't actually look at the second CDN file until the first one is finished.

  <script src="//ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
  <script src="//maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>

How can I make the page download the scripts asynchronously, but execute them synchronously? Or is that actually happening by default somehow? And what about CSS files, will my

  <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">

behave any different in that sense? I would like to understand the loading process properly before adding my own failovers to local code (for if the CDN is down), as to prevent getting stuck with synchronous downloading.

(Note that, despite the near-identical title, this is not a duplicate of this question, which is about loading scripts dynamically.)

Also note that I can't use defer (at least in the vanilla way that I know) as that would prevent me from adding said failover when the CDN is down, e.g.

<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/js/bootstrap.min.js"></script>
<script>    $.fn.modal || document.write('<script src="Script/bootstrap.min.js">\x3C/script>')</script>

would be broken by simply adding defer.

T.J. Crowder

It's more about parallelism than asynchronousness. (They're certainly related, but the CDN argument related to limits on multiple downloads from the same origin is about parallelism.)

How can I make the page download the scripts asynchronously, but execute them synchronously?

Any decent browser, when given the three script tags you've shown, will download them in parallel (up to its parallel-from-the-same-site limit) and then execute them in order. You don't have to do anything to make that happen. Browsers read ahead in the HTML to find resources to fetch.

Adding fallback scripts with document.write might complicate the browser's ability to do that, or even prevent it, but you can ensure it declaratively using <link rel="preload" as="script" href="..."> (more on MDN). Combining that with fallback scripts for failed CDN resources, it might look something like this:

<head>
<!-- ... -->
<link rel="preload" as="script" href="//ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js">
<link rel="preload" as="script" href="//cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js">
<link rel="preload" as="script" href="//maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js">
</head>
<body>
<!-- ... -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>if (!/*loaded condition*/) document.write(/*fallback*/);</script>
<script src="//cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script>if (!/*loaded condition*/) document.write(/*fallback*/);</script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script>if (!/*loaded condition*/) document.write(/*fallback*/);</script>
</body>
</html>

Note that that doesn't preload the fallbacks. You could, but then you'd be loading them even when the CDN was working, which wastes the end user's bandwidth. The fallbacks would be for the presumably-temporary degraded situation where the CDN was unavailable, where a degraded user experience is probably okay. (You could even show the user an indicator of a problem when scheduling the fallback, like Gmail's "something is taking longer than usual" indicator.)


If you're bothered by repeating the URLs and you're okay with document.write in small doses (as you seem to be), you can avoid duplicating the URLs by doing something along these lines:

<head>
<!-- ... -->
<script>
var scripts = [
    {
        url: "//ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js",
        okay: function() { return /*check it loaded*/; }
    },
    {
        url: "//cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js",
        okay: function() { return /*check it loaded*/; }
    },
    {
        url: "//maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js",
        okay: function() { return /*check it loaded*/; }
    },
];
scripts.forEach(function(script) {
    document.write('<link rel="preload" as="script" href="' + script.url + '">');
});
</script>
</head>
<body>
<!-- ... -->
<script>
scripts.forEach(function(script, index) {
    var fallback = script.url.substring(script.url.lastIndexOf('/') + 1);
    document.write('<script src="' + script.url + '"><\/script>');
    document.write('<script>if (!scripts[' + index + '].okay()) document.write(\'<script src="' + fallback + '"><\\/script>\');<\/script>');
});
</script>
</body>
</html>

(Since that's all inline script you're unlikely to transpile, I've kept the syntax to ES5 level in case you have to support obsolete environments.)

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

How to load a shader file synchronously in dart

분류에서Dev

How to select multiple files and copy them in Far Manager

분류에서Dev

Load multiple files with Modernizr

분류에서Dev

Capture output from multiple processes asynchronously

분류에서Dev

Reading text from multiple text files at the same time and splitting them into array of words

분류에서Dev

Apache doesn't execute PHP files, but makes me download them

분류에서Dev

Open multiple terminal tabs, execute commands and continue working on them

분류에서Dev

How to load xls data from multiple xls file into hive?

분류에서Dev

How to automatically execute a javascript function from an external js file on page load with a specific condition

분류에서Dev

Conditionally asynchronously execute mocha test

분류에서Dev

Retrieving multiple data from db and grouping them

분류에서Dev

How to create multiple folders and name them by reading lines from text file?

분류에서Dev

How to create a generator of lines from multiple files in Python

분류에서Dev

Jsoup : How to parse multiple HTML files from local drive?

분류에서Dev

How to copy multiple files from GitHub in a single request

분류에서Dev

How to refer to multiple files from a directory to one command

분류에서Dev

How to run multiple JAR files at differnt locations from a command prompt

분류에서Dev

How to find files with regex and list them?

분류에서Dev

Uploading multiple files with iOS SDK and deleting them locally when done

분류에서Dev

Does RHEL/CentOS execute all cronjob files under /etc/cron.d/*, or just some of them?

분류에서Dev

Listing folders and files within them from particular folder in Google drive

분류에서Dev

How to load multiple configuration file from classpath using @ImportResource annotation in Spring

분류에서Dev

php load first image from multiple sources

분류에서Dev

How to run hxnormalize on multiple files?

분류에서Dev

Do some files downloaded from the internet have execute permission by default?

분류에서Dev

How can I find files and then use xargs to move them?

분류에서Dev

".c" files called by fiona. How to import them?

분류에서Dev

How can I work on files on my server and keep them in sync?

분류에서Dev

how to change the value of system files without opening them?

Related 관련 기사

  1. 1

    How to load a shader file synchronously in dart

  2. 2

    How to select multiple files and copy them in Far Manager

  3. 3

    Load multiple files with Modernizr

  4. 4

    Capture output from multiple processes asynchronously

  5. 5

    Reading text from multiple text files at the same time and splitting them into array of words

  6. 6

    Apache doesn't execute PHP files, but makes me download them

  7. 7

    Open multiple terminal tabs, execute commands and continue working on them

  8. 8

    How to load xls data from multiple xls file into hive?

  9. 9

    How to automatically execute a javascript function from an external js file on page load with a specific condition

  10. 10

    Conditionally asynchronously execute mocha test

  11. 11

    Retrieving multiple data from db and grouping them

  12. 12

    How to create multiple folders and name them by reading lines from text file?

  13. 13

    How to create a generator of lines from multiple files in Python

  14. 14

    Jsoup : How to parse multiple HTML files from local drive?

  15. 15

    How to copy multiple files from GitHub in a single request

  16. 16

    How to refer to multiple files from a directory to one command

  17. 17

    How to run multiple JAR files at differnt locations from a command prompt

  18. 18

    How to find files with regex and list them?

  19. 19

    Uploading multiple files with iOS SDK and deleting them locally when done

  20. 20

    Does RHEL/CentOS execute all cronjob files under /etc/cron.d/*, or just some of them?

  21. 21

    Listing folders and files within them from particular folder in Google drive

  22. 22

    How to load multiple configuration file from classpath using @ImportResource annotation in Spring

  23. 23

    php load first image from multiple sources

  24. 24

    How to run hxnormalize on multiple files?

  25. 25

    Do some files downloaded from the internet have execute permission by default?

  26. 26

    How can I find files and then use xargs to move them?

  27. 27

    ".c" files called by fiona. How to import them?

  28. 28

    How can I work on files on my server and keep them in sync?

  29. 29

    how to change the value of system files without opening them?

뜨겁다태그

보관