Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use jQuery to handle dynamically added script tags in parallel

Here is my situation: I dynamically added 2 scripts through

$('body').append('<script src="http://localhost:8080/script_1.js"></script>');
$('body').append('<script src="http://localhost:8080/script_2.js"></script>');

Then I found they would be loaded in sequence instead of parallel from chrome console.

However, they could be loaded in parallel if I use either native js

document.body.appendChild(script);

or jQuery function: getScript

$.getScript('http://localhost:8080/script_1.js');

I searched a lot and found that jQuery actually will remove the script tag, parse the source, and use its ajax function $.ajax() to load script instead of letting browser to handle. But $.getScript() function also uses $.ajax() and have no blocking. Obviously, it's not the fault of $.ajax().

Here is a test case: Go to http://jquery.com and paste following script in the console which will add a js file twice through jQuery

$('body').append('<script src="/jquery-wp-content/themes/jquery/js/plugins.js"></script>');
$('body').append('<script src="/jquery-wp-content/themes/jquery/js/plugins.js"></script>');

Check the timeline, you'll find they are loaded in sequence. Of course, I can use native js or $.getScript() above to save my time.

However, I want to know why? Why are these jQuery ajax call from adding script tag not in parallel?

Update

More interesting, seems the sequence only apply to the script from the same origin. I tried to load some js files form google hosted libraries and they are in parallel. Tried following also in http://jquery.com

$('body').append('<script src="https://ajax.googleapis.com/ajax/libs/ext-core/3.1.0/ext-core.js"></script>');
$('body').append('<script src="https://ajax.googleapis.com/ajax/libs/ext-core/3.1.0/ext-core.js"></script>');
like image 647
Aobo Yang Avatar asked Jan 22 '15 08:01

Aobo Yang


Video Answer


1 Answers

When appending scripts to the DOM, depending on the cross-domain test, different ajaxTransport functions are used.

A cross-domain request happens when we have a protocol:host:port mismatch

In the first case same-origin:

JQuery uses the XMLHttpRequest open function with async=false forcing a synchrounous request (see source).

xhr.open(
        options.type,
        options.url,
        options.async,
        options.username,
        options.password
    );

Hence the warning on the console (at least on Canary anyway).

Synchronous XMLHttpRequest on the main thread is deprecated

In the second case cross-origin:

JQuery uses ajax as follows(see source)

script = jQuery("<script>").prop({
                    async: true,
                    charset: s.scriptCharset,
                    src: s.url
                }).....
document.head.appendChild(script[0]);

which will load in parallel as you have stated.

like image 76
gotomanners Avatar answered Nov 14 '22 23:11

gotomanners