如何异步加载库时如何处理依赖项?

时间:2014-07-18 20:10:20

标签: javascript jquery asynchronous

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这样的库来处理加载文件时的依赖关系,但我不认为这种解决方案在我的情况下不起作用,因为我在包装文件中异步加载库(因为它们“每页都需要”。此处的示例代码不会出现在每个页面上,而只会出现在我网站上的特定页面上。

2 个答案:

答案 0 :(得分:1)

最好的方法是使用回调机制,您可以对此做出反应,而不是使用轮询机制。我使用了script.js,它简单但功能强大,并提供了回调机制。

没有它,你可以自己实现一些东西。但是在性能方面,使用回调更好。

答案 1 :(得分:1)

根据网站的复杂程度,不同的选项可能是最佳选择。如果...

  1. 您的所有javascript都在JS文件中
  2. 在加载JS之前和之后,您的首要内容看起来相同(或者足够接近,以便在您加载JS时不会分散用户的注意事项)
  3. 总文件大小很小(或者每次访问您网站时每个人都会访问的页面上需要大部分JS)
  4. ...然后将它们组合成一个文件,而不是所有单独的服务器。然后你根本不必担心依赖。将脚本文件包含在body标签的底部(不需要异步或延迟属性,但如果需要,可以使用它们。)

    如果您的某些javascript是必要的,以使您的首要内容看起来正确,做同样的事情,除了将您的JS分成两个文件。一个文件仅包含使上面的内容看起来正确所需的内容,另一个文件包含其他所有内容。在头标记中包含第一个(可能内联),并在body标记的底部包含第二个。如果第二个标记依赖于第一个标记,请不要使用async属性,因为它可能首先执行。

    如果您有一些仅在某些页面上使用的大型JS文件,并且这些文件依赖于其他JS文件,请将脚本粘贴在body标签的底部并使用defer属性。

    如果你的HTML混入了你的HTML,你可以使用回调机制(比如script.js),或者你可以建立像Google Analytics这样的执行队列,外部脚本知道它在什么时候寻找首先加载。