Google Pagespeed说我应该异步加载我的JS文件,但这给我的许多页面带来了使用库和插件的代码的问题。
例如,我在一个页面上有以下代码:
$(document).ready(function () {
var hound = new Bloodhound({ .......
});
因此,当页面加载时,我正在创建一个Twitter Bloodhound(与Typeahead一起使用)对象。问题是,如果异步加载Bloodhound和Typeahead,则会抛出错误:
Uncaught ReferenceError: Bloodhound is not defined
这是因为尚未加载这些脚本。
我提出了这个解决方案:
$(document).ready(function () {
createBloodhound();
});
function createBloodhound() {
if (typeof Bloodhound != "undefined") { // if bloodhound JS has loaded
var hound = new Bloodhound({ .......
}
else {
setTimeout(function(){
createBloodhound();
}, 10);
}
}
这是一个好习惯,还是有更好的方法?
注意:我意识到有一些像RequireJS这样的库来处理加载文件时的依赖关系,但我不认为这种解决方案在我的情况下不起作用,因为我在包装文件中异步加载库(因为它们“每页都需要”。此处的示例代码不会出现在每个页面上,而只会出现在我网站上的特定页面上。
答案 0 :(得分:1)
最好的方法是使用回调机制,您可以对此做出反应,而不是使用轮询机制。我使用了script.js,它简单但功能强大,并提供了回调机制。
没有它,你可以自己实现一些东西。但是在性能方面,使用回调更好。
答案 1 :(得分:1)
根据网站的复杂程度,不同的选项可能是最佳选择。如果...
...然后将它们组合成一个文件,而不是所有单独的服务器。然后你根本不必担心依赖。将脚本文件包含在body标签的底部(不需要异步或延迟属性,但如果需要,可以使用它们。)
如果您的某些javascript是必要的,以使您的首要内容看起来正确,做同样的事情,除了将您的JS分成两个文件。一个文件仅包含使上面的内容看起来正确所需的内容,另一个文件包含其他所有内容。在头标记中包含第一个(可能内联),并在body标记的底部包含第二个。如果第二个标记依赖于第一个标记,请不要使用async属性,因为它可能首先执行。
如果您有一些仅在某些页面上使用的大型JS文件,并且这些文件依赖于其他JS文件,请将脚本粘贴在body标签的底部并使用defer属性。
如果你的HTML混入了你的HTML,你可以使用回调机制(比如script.js),或者你可以建立像Google Analytics这样的执行队列,外部脚本知道它在什么时候寻找首先加载。