假设我有一个相当庞大的JavaScript文件,打包到大约100kb左右.通过文件我的意思是它是一个外部文件,将在via中链接<script src="...">,而不是粘贴到HTML本身.
哪个是放在HTML中的最佳位置?
<html>
<head>
<!-- here? -->
<link rel="stylesheet" href="stylez.css" type="text/css" />
<!-- here? -->
</head>
<body>
<!-- here? -->
<p>All the page content ...</p>
<!-- or here? -->
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
每个选项之间是否存在功能差异?
我有以下HTML代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/blazy/1.8.2/blazy.min.js" defer></script>
<script src="https://code.jquery.com/jquery-2.1.4.min.js" integrity="sha256-8WqyJLuWKRBVhxXIL1jBDD7SDxU936oZkCnxQbWwJVw=" crossorigin="anonymous" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.9.0/js/lightbox.min.js" defer></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous" defer></script>
<!-- 26 dec flexslider js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/flexslider/2.6.3/jquery.flexslider.min.js" defer></script>
<script defer>
(function($) {
$(document).ready(function() {
//do something with b-lazy plugin, lightbox plugin and then with flexslider
});
})(jQuery);
</script>
</head>
<body>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
我收到一个错误,说没有定义jQuery.现在,即使我从我的内联JS代码中删除defer,它也说jQuery是未定义的.出于某种原因,我必须将jQuery插件保留在头部并保持我的JS代码内联.我的问题是:
为什么内联Javascript代码在defer属性存在时不会延迟?
有没有办法模仿我的内联Javascript代码的延迟行为?如果需要,我可以将它放在body标签的末尾.
Chrome for me一直是Web标准的参考,遗憾的是不支持defer,IE从5.5版开始就支持它.为什么?
js.js
document.getElementById ("hi").innerHTML = "Hi :)";
Run Code Online (Sandbox Code Playgroud)
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset = "utf-8">
<script defer="defer" src="js.js"></script>
<title>Hi</title>
</head>
<body>
<div id="hi"></div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud) 我想使用javascript/jquery在页面加载完成时触发一个事件.
页面加载完全完成后,有没有办法触发事件或调用简单函数.
如果你有任何参考,请建议大家.
我一直在为我的一个项目的HEAD部分中使用的外部脚本添加defer属性.我查询了多个延迟脚本标签的执行顺序.
以下是我的观察,这将有助于我们更好地理解我的查询:
根据http://www.w3.org/TR/html5/scripting-1.html
如果存在defer属性,则在页面完成解析时执行脚本
defer属性确实有效.但是,我怀疑执行顺序.在FF和Chrome上看起来有所不同.
根据我的项目:
<script defer="defer" src="{SERVER_PATH}/deps.js?1441452359"></script>
<script defer="defer" src="{SERVER_PATH}/script1.js?1440067073"></script>
<script defer="defer" src="{SERVER_PATH}/script2.js?1441451916"></script>
Run Code Online (Sandbox Code Playgroud)
在这里,deps.js是大约120kb(gzip)的大文件,而script1-3的常规大小是20-50kb(gzip).
在Firefox上,延迟脚本的执行确实按照出现的顺序开始,但是没有以相同的顺序完成.除非前一个脚本完成执行,否则在chrome上,下一个脚本的执行不会启动.Chrome看起来很有意义.
为了测试执行顺序,我在每个脚本的第一行和最后一行插入了console.log,例如在deps.js中
console.log("Execution Start: deps");
// minified deps script content.
console.log("Execution End: deps");
Run Code Online (Sandbox Code Playgroud)
在Firefox上的控制台输出下方:
Execution Start: deps
Execution Start: script1
Execution Start: script2
// Script Error as script1 needs deps to render completely.
// Script Error as script2 needs deps to render completely.
Execution End: deps
Run Code Online (Sandbox Code Playgroud)
在Chrome上的控制台输出下方:
Execution Start: deps
Execution End: deps
Execution Start: script1
Execution End: script1
Execution Start: script2
Execution …Run Code Online (Sandbox Code Playgroud) 每次我将js文件放在页面底部时,这个问题一直困扰着我.如果我把所有js文件放在结束body标记之前的底部,那么我认为浏览器将首先下载所有的html和样式表,然后它将解析html和css,最后它将发送js文件的请求.所以,
defer已经在底部的js文件会有什么不同吗? 我的另一个问题是,如果我将所有js文件放在头部并使用defer它们.这相当于将所有js文件放在底部吗?在head浏览器中看到js与延迟会向服务器发出请求,然后继续下载其余的html文件,还是只在下载所有html和css之后才向服务器发出请求?
据我所知async,相当于defer和唯一的区别是js将在不考虑文件顺序的情况下下载时执行.所以,
async已经在底部的js文件除了执行它们的顺序之外会有什么不同吗?我有一个打字稿应用程序,动态添加指向JS文件的脚本标记.由于一些限制,我不能在html文件中静态定义这些脚本标记,所以我通过typescript动态添加它们,如下所示:
for (let src of jsFiles) {
let sTag = document.createElement('script');
sTag.type = 'text/javascript';
sTag.src = src;
sTag.defer = true;
document.body.appendChild(script);
}
Run Code Online (Sandbox Code Playgroud)
现在,我注意到,当我动态添加脚本标签时,它们似乎不是按照加载顺序的保证.不幸的是,该jsFiles阵列具有相互依赖的脚本.因此,数组中的第二个脚本只能在第一个完全加载后加载.第二个脚本引用第一个脚本中定义的函数.有没有一种方法可以指定脚本在动态添加脚本时的顺序和执行顺序(类似于在html文件中静态定义脚本标记时的排序方式)?
PS我想避免使用onload回调来解决这个问题,因为我注意到我的应用程序性能下降.我的第二个脚本文件非常大,我假设这导致了降级.
我在Sentry中遇到很多错误,说"ReferenceError:jQuery未定义",但与页面加载总数相比,它仍然很少发生.
<script src="/js/compiled/jquery.min-2fe08f7.js" defer></script>
<script src="/js/my-script-e6f35a4.js" defer></script>
Run Code Online (Sandbox Code Playgroud)
my-script.js的位置如下:
(function($) {
$('h1').text('Hello world');
})(jQuery);
Run Code Online (Sandbox Code Playgroud)
但是我从Sentry报告中找不到为什么没有加载jQuery的线索.
Sentry面包屑中给出的唯一线索是无用的:
12:15:25 sentry ReferenceError: jQuery is not defined
12:15:25 sentry ReferenceError: jQuery is not defined
12:15:26 exception ReferenceError: jQuery is not defined
Run Code Online (Sandbox Code Playgroud)
延迟脚本应按它们在文档中的顺序加载,因此我不认为问题出在异步加载中.
也许jQuery文件在一些慢速设备上加载超时?或者某个时刻服务器上的文件不可用?
这种情况发生在各种JS文件中,也有各种依赖项,而不仅仅是jQuery.任何人都可以告诉我如何正确解决这样的问题,或者至少获得完整的控制台输出到Sentry,包括失败的HTTP子请求到资源,如JS文件,找出实际原因是什么?
提前致谢.
我正在合并使用YouTube iFrame API和通过defer设置了标志的脚本标记加载的jQuery .必须设置延迟标记,因为客户端具有完美的Google页面洞察分数,并希望保持该分数.
YouTube API在完全加载并可以使用后,immediatley调用我定义的功能onYouTubeIframeAPIReady.然后它会调用onPlayerReady播放器完全加载和渲染.
我希望在这个函数中使用jQuery,但只是在onPlayerReady函数中使用jQuery将创建一个竞争条件(希望jQuery库在onPlayerReady被调用时已完成加载).
它发生在我身上一个可行的解决方案是使用onPlayerReady函数在调用一个测试播放器和jQuery的函数之前设置一个变量.另一个函数在jQuery准备就绪时设置一个变量,并调用相同的测试函数.
我有一些代码可以工作,但检查jQuery的部分对我来说似乎很乱,并且还引入了少量额外的不必要的延迟.我想知道是否有人知道更好的方式来运行即时jQuery变得可用的东西.基本上,jQuery的回调是否可以内置到库中?
我目前的代码如下:
var ready = {
'jquery': false,
'youtube' false
},
testJQueryLoaded;
testJQueryLoaded = function() {
if(typeof jQuery == 'undefined') {
window.setTimeout(function() {
testJQueryLoaded();
}, 25);
return;
}
ready.jquery = true;
postLibraryLoad();
};
testJQueryLoaded();
function onYouTubeIframeAPIReady() {
// Stuff
};
function onPlayerReady() {
ready.youtube = true;
postLibraryLoad();
};
function postLibraryLoad() {
if(!ready.jquery || !ready.youtube) {
return;
}
// More stuff
};
Run Code Online (Sandbox Code Playgroud) 拥有以下代码:
<html>
<head>
<script>
function elem_onload() {
console.log("elem_onload");
};
</script>
</head>
<body onload="elem_onload()">
<script type="text/javascript" src="script.js" defer></script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
的script.js:
console.log("external script");
Run Code Online (Sandbox Code Playgroud)
defer属性似乎不起作用.输出是:
external script
elem_onload
Run Code Online (Sandbox Code Playgroud)
是否有延迟属性.不是的
elem_onload
external script
Run Code Online (Sandbox Code Playgroud)
推迟定义?
我想说明我的答案不是重复的
<script defer ="defer">究竟是如何工作的?
引用的推荐答案是内联脚本,浏览器行为对我来说很明显 - 它只是忽略defer.我的问题是关于外部脚本,在这种情况下,浏览器应该执行外部延迟脚本
解析文档后
因为文件在onload事件之后就这样说了
所以我在等待一个合适的答案......
具有以下代码:
<html>
<head>
<script>
function elem_onload() {
console.log("elem_onload");
};
</script>
</head>
<body onload="elem_onload()">
<script type="text/javascript" src="script.js" defer></script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
script.js:
console.log("external script");
Run Code Online (Sandbox Code Playgroud)
defer属性似乎不起作用。输出为:
external script
elem_onload
Run Code Online (Sandbox Code Playgroud)
是否具有defer属性。不应该
elem_onload
external script
Run Code Online (Sandbox Code Playgroud)
与延期定义?
我想说我的答案不是重复的
<script defer =“ defer”>是如何工作的?
推荐的参考答案是关于内联脚本的,在该脚本中浏览器的行为对我来说很清楚-它只是忽略defer。我的问题是关于外部脚本,在这种情况下,浏览器应执行外部延迟脚本
文件解析后
作为文档说明onload事件发生后。
所以我正在等待一个适当的答案...
javascript ×11
html ×6
jquery ×4
html5 ×2
attributes ×1
deferred ×1
http ×1
load-order ×1
optimization ×1
raven ×1
sentry ×1
typescript ×1