Javascript代码具有阻塞特性:当页面在加载或者执行Javascript代码的时候(遇到<script>标签,不管是内嵌还是外链),页面其他部分的加载、渲染和用户交互都会停止。因为Javascript代码执行过程中有可能会改变页面的内容(比如document.write),而浏览器只有一个进程用来同时处理用户界面(UI)更新和Javascript的执行,所以浏览器会先等Javascript执行完成之后,再继续解析和渲染页面的其他部分。因此,加载和执行的优化,主要是如何解决页面阻塞问题:
将所有的<script>标签放到页面的底部,靠近</body>标签,这能确保在脚本执行前页面已经完成了渲染;尽量不把脚本放在<head>标签中,避免内容没有加载之前,页面被脚本阻塞,导致页面在某个时间段内一篇空白。
合并文件,减少面中的<script>标签,下载一个100k的脚本文件,比下载4个25k的脚本文件更快,而且能够减少页面被阻塞的次数。
使用<script>标签的defer属性(适用于外链脚本文件,仅适用于IE、Firefox 3.5以上、chrome最新版本)。
<script type="text/javascript" src="a.js" defer="defer"></script> https://developer.mozilla.org/En/HTML/Element/Script
这样添加的脚本会在加载玩之后立即自动执行,可以添加回调函数,在需要的时候执行脚本,需要注意的是ie的回调中readyState的判断和处理。
function loadScript(url, callback){ var script = document.createElement("script") script.type = "text/javascript"; if (script.readyState){ //IE script.onreadystatechange = function(){ //ie下readyState的状态的值loaded和complete可能只会出现一个 if (script.readyState == "loaded" || script.readyState == "complete"){ //避免loaded和complete重复处理 script.onreadystatechange = null; callback(); } }; } else { //Others script.onload = function(){ callback(); }; } script.src = url; document.getElementsByTagName("head")[0].appendChild(script); }
下载之后不会立即自动执行,但是不能跨域。
动态创建<script>标签的方法loadScript。
通过use来动态加载各种已经定义好的文件
YUI().use('animation', function(Y) { // Y.Anim is available });
可以同时加载多个,并按照顺序执行:
LazyLoad.js(['foo.js', 'bar.js', 'baz.js'], function () { alert('all files have been loaded'); });
LazyLoad.css('foo.css', function (arg) { alert(arg); }, 'foo.css has been loaded');
支持链式操作,wait处理依赖或执行先后关系。
<script> $LAB .script("framework.js").wait() .script("plugin.framework.js") .script("myplugin.framework.js").wait() .script("init.js").wait(); </script>