懒加载 JavaScript

7
这三种方式中,惰性加载js或按需加载的基本区别是什么?

如果您编写了这些函数,希望您意识到 readyState == 'loaded' 发生在脚本执行之前,而 'complete' 发生在之后。 - zzzzBov
是的,真的... 即使我打算仅解析脚本而不是执行,因为执行需要比解析更多的时间 - paul
4个回答

7
  1. 使用ajax加载脚本,更具体地说,它使用XHR加载一些js并使其在浏览器中可用。不会阻塞任何操作。但它仍然强制实施相同的源策略。
  2. 通过创建<script/>元素修改标头以注入新的.js文件。这也不会在页面加载时阻塞浏览器。
  3. 与#2执行相同的操作,但似乎支持一系列脚本。它还将异步设置为true,这不会造成阻塞。for循环只是更混乱,因为它创建了更多的匿名方法。

当我们在不使用Ajax的情况下注入脚本时,缓存是否存在问题?函数1由于它是XHR,我们可以指定cache:cache。 - paul
我认为所有这些都可能存在这个问题。浏览器甚至可以缓存xhr请求。您可以使用随机查询来打破缓存。如果您控制服务器,则可以选择不进行缓存。 - Amir Raminfar
此外,如果我发送正确的带过期日期的标头,则不应该出现任何问题... - paul
使用XHR,您可能能够控制它。我不确定您是否可以使用<script/>标签来控制它? - Amir Raminfar

2
  1. 似乎使用XmlHttpRequest检索脚本,然后通过eval()执行它。如果脚本未托管在同一协议/域名/端口上,则此方法无效。

  2. 而且3.似乎都是做同样的事情:它们创建一个<script src="the script url"></script>元素,在其上绑定onload事件,并将其插入到页面中。当浏览器加载脚本时,它将被执行,并触发onload事件。


你对缓存有什么看法?因为在第一个函数中,我可以传递一个属性cache:cache,而对于其他两种情况,会有问题吗? - paul
两种方法都是缓存友好的,只要服务器发送正确的头部信息。 - Arnaud Le Blanc

2
  1. 通过ajax获取脚本,然后使用eval()执行其内容
  2. 将一个script元素插入到head元素中,并在加载完成后报告回来
  3. 与(2)相同,但接受脚本url的数组,且写法更为复杂

(2)和(3)都使用了onreadystatechange钩子,可能不兼容旧浏览器(例如Firefox 3.x及以下版本不支持)。

(1)可能是最健壮的,兼容性方面,因为它只需要XHR。但如果您以这种方式加载的代码出现错误,则浏览器的控制台可能不太有用,因为错误仅发生在“eval'd code”中,而不是在特定的文件/行中。话虽如此,懒加载通常是一种优化方法,因此您可以在调试时正常地或使用其他2种方法加载脚本。


1

你应该尝试一下这个叫做head.js的新库。

他们有一些有趣的想法和 API,希望能对你有所帮助。

或者你可以使用普通的 XHR 请求来获取你的脚本文件名,并使用类似于这样的方法插入到 DOM 中。我还添加了 removeScript 部分。

addScript = function(file)
{
    var headID = document.getElementsByTagName("head")[0];         
    var newScript = document.createElement('script');
    newScript.type = 'text/javascript';
    newScript.src = file;
    headID.appendChild(newScript);
};
removeScript = function(file)
{
    var headID = document.getElementsByTagName("head")[0].children;
    for(var i in headID)
        if(headID[i].tagName == "SCRIPT")
            if(headID[i].getAttribute('src') == file)
                headID[i].parentNode.removeChild(headID[i]);
}

如果您正在使用像jQuery这样的库,您不需要担心任何事情,您可以从服务器获取HTML或脚本标记,并使用.html() API将其插入到DOM中。

这应该是一条注释,因为它实际上并没有回答任何问题。 - Amir Raminfar
@zzzz 是的,我浏览了head.js、labjs和controljs,但是我正在尝试想出自己的解决方案,而不是使用另一个库。 - paul
你觉得 addScript 方法怎么样? - Baz1nga
这与我正在做的类似...只是你有一个removeScript函数...但是为什么需要这个函数呢?因为一旦加载脚本,它将在浏览器缓存中,并在重新访问时提高性能。 - paul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接