如何使用jQuery并行处理动态添加的脚本标签
How to use jQuery to handle dynamically added script tags in parallel
这是我的情况:我通过
动态添加了2个脚本
$('body').append('<script src="http://localhost:8080/script_1.js"></script>');
$('body').append('<script src="http://localhost:8080/script_2.js"></script>');
然后我发现它们会按顺序加载,而不是从 chrome 控制台并行加载。
但是,如果我使用原生 js,它们可以并行加载
document.body.appendChild(script);
或jQuery函数:getScript
$.getScript('http://localhost:8080/script_1.js');
查了很多,发现jQuery居然会去掉脚本标签,解析源码,用它的ajax函数$.ajax()代替加载脚本让浏览器来处理。但是 $.getScript() 函数也使用 $.ajax() 并且没有阻塞。显然,这不是 $.ajax().
的错
这是一个测试用例:
转到 http://jquery.com 并在控制台中粘贴以下脚本,这将通过 jQuery
添加一个 js 文件两次
$('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>');
查看时间轴,您会发现它们是按顺序加载的。
当然我可以使用原生js或者上面的$.getScript()来节省我的时间
但是,我想知道为什么?为什么这些 jQuery ajax 添加脚本标签的调用不是并行的?
更新
更有趣的是,似乎该序列仅适用于来自同源的脚本。
我尝试从 google 托管库加载一些 js 文件,它们是并行的。也在 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>');
将脚本附加到 DOM 时,根据跨域测试,使用不同的 ajax 传输函数。
A cross-domain request happens when we have a protocol:host:port
mismatch
第一种情况同源:
JQuery 使用 XMLHttpRequest open function with async=false
forcing a synchrounous request (see source).
xhr.open(
options.type,
options.url,
options.async,
options.username,
options.password
);
因此在控制台上出现警告(无论如何至少在 Canary 上)。
Synchronous XMLHttpRequest on the main thread is deprecated
第二种情况cross-origin:
JQuery 使用 ajax 如下(see source)
script = jQuery("<script>").prop({
async: true,
charset: s.scriptCharset,
src: s.url
}).....
document.head.appendChild(script[0]);
这将如您所述并行加载。
这是我的情况:我通过
动态添加了2个脚本$('body').append('<script src="http://localhost:8080/script_1.js"></script>');
$('body').append('<script src="http://localhost:8080/script_2.js"></script>');
然后我发现它们会按顺序加载,而不是从 chrome 控制台并行加载。
但是,如果我使用原生 js,它们可以并行加载
document.body.appendChild(script);
或jQuery函数:getScript
$.getScript('http://localhost:8080/script_1.js');
查了很多,发现jQuery居然会去掉脚本标签,解析源码,用它的ajax函数$.ajax()代替加载脚本让浏览器来处理。但是 $.getScript() 函数也使用 $.ajax() 并且没有阻塞。显然,这不是 $.ajax().
的错这是一个测试用例: 转到 http://jquery.com 并在控制台中粘贴以下脚本,这将通过 jQuery
添加一个 js 文件两次$('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>');
查看时间轴,您会发现它们是按顺序加载的。 当然我可以使用原生js或者上面的$.getScript()来节省我的时间
但是,我想知道为什么?为什么这些 jQuery ajax 添加脚本标签的调用不是并行的?
更新
更有趣的是,似乎该序列仅适用于来自同源的脚本。 我尝试从 google 托管库加载一些 js 文件,它们是并行的。也在 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>');
将脚本附加到 DOM 时,根据跨域测试,使用不同的 ajax 传输函数。
A cross-domain request happens when we have a protocol:host:port mismatch
第一种情况同源:
JQuery 使用 XMLHttpRequest open function with async=false
forcing a synchrounous request (see source).
xhr.open(
options.type,
options.url,
options.async,
options.username,
options.password
);
因此在控制台上出现警告(无论如何至少在 Canary 上)。
Synchronous XMLHttpRequest on the main thread is deprecated
第二种情况cross-origin:
JQuery 使用 ajax 如下(see source)
script = jQuery("<script>").prop({
async: true,
charset: s.scriptCharset,
src: s.url
}).....
document.head.appendChild(script[0]);
这将如您所述并行加载。