我一直在研究一些JavaScript代码,在某些条件下,懒惰加载了几个不同的库(Clicky Web Analytics和Sizzle选择器引擎)。
此脚本每天下载数百万次,因此性能优化是一个主要问题。到目前为止,我已经使用了几个标志,如script_loading
和script_loaded
,以确保我不会多次加载任何一个库(通过“加载”,我的意思是请求后脚本通过在DOM中插入<script>
元素来加载页面。
我的问题是:而不是依赖于这些标志,这些标志在我的代码中有点笨拙且难以理解(想想回调和异步代码的所有缺陷),它是跨浏览器安全的(即返回到IE 6)并且只要在我到达需要其中一个库的代码分支时调用一个简单的函数来插入一个<script>
元素,就不会对性能有害吗?
后者仍然会确保我只在需要时加载任何一个库,并且还会简化并减轻我的代码库的重量,但我需要绝对确定这不会导致额外的,不必要的浏览器请求。
我的预感是多次添加<script>
元素并不会有害,因为我认为浏览器应该识别重复的src
网址并依赖本地缓存副本。但是,你知道当我们假设时会发生什么......
我希望有人熟悉各种现代(而不是那么现代,如IE 6)浏览器的行为,以便能够说明在这种情况下会发生什么。
与此同时,我会写一个测试来试图直接回答这个问题。我的犹豫只是在我的脚本应该支持的每个浏览器中确定地验证这可能是困难和麻烦的。
提前感谢您提供任何帮助和/或输入!
答案 0 :(得分:2)
有另一种解决方案。
在DOM中插入新脚本元素时,您是否可以快速扫描现有脚本元素以查看是否有另一个脚本元素具有相同的src?如果有,不要插入另一个?
同一页面上的Javascript代码无法运行多线程,因此您不会在此或任何内容中获得任何竞争条件。
否则,您只是依赖于当前浏览器(和HTTP代理)的缓存行为。
答案 1 :(得分:1)
该页面作为流处理。如果多次加载相同的脚本,则每次包含该脚本时都会运行该脚本。显然,由于浏览器缓存,它只会从服务器请求一次。
我会远离这种多次为同一个脚本插入脚本标记的方法。
我解决这个问题的方法是为每个脚本设置一个“test”函数,以查看它是否已加载。例如。对于嘶嘶声,这将是“function(){return !! window ['Sizzle'];}”。仅当测试函数返回false时才插入脚本标记。
答案 2 :(得分:0)
每次向页面添加脚本时,即使它具有相同的src,浏览器也可能在本地缓存中找到它,或者询问服务器是否更改了内容。
使用变量检查是否包含脚本是减少加载的好方法,它非常简单: 例如,这可能对你有用:
var LOADED_JS=Object();
function js_isIncluded(name){//returns true if the js is already loaded
return LOADED_JS[name]!==undefined;
}
function include_js(name){
if(!js_isIncluded(name)){
YOUR_LAZY_LOADING_FUNCTION(name);
LOADED_JS[name]=true;
}
}
你也可以获取所有脚本元素并检查src,我的解决方案更好,因为它具有散列数组的速度和简单性,并且脚本src具有绝对路径,即使你使用相对路径设置它也是如此。 /> 您可能还希望在页面init上使用正常加载的脚本(不加延迟加载)来初始化数组,以避免双重请求。