前端优化过程中常提到js的加载方式,下面说下几种常用的加载方式:
1:head标签内插入<script>标签
<script type="text/javaScript" src="test.js"></script>
这是最常见的方法,但是这个方法有个最大的问题,就是当浏览器解析到<script>标签时,浏览器会停止解析其后的内容,而优先下载脚本文件,并执行其中的代码,是个阻塞的过程,这意味着,其后的test.css样式文件和<body>标签都无法被加载,由于<body>标签和样式等资源无法被加载,那么页面自然就无法渲染了,因此常常页面打开会出现页面内容空白或者样式丢失问题,这都是在头部引入了过多的js文件阻塞加载造成的,虽然高版本的浏览器已经可以对脚本并行加载,可是还有些浏览器脚本依旧是一个接一个加载的,因此优化的话可以把js放在body标签最底部,这样页面可以先快速显示出来,提高了体验友好度。
2:创建动态脚本
var script=document.createElement(‘script‘); script.type=‘text/javaScript‘; script.src=‘test.js‘; document.getElementsByTagName(‘head‘)[0].appendChild(script);
上述代码动态创建了一个<script>标签,并添加在<head>标签内,无论在何时启动下载,文件的下载和执行过程不会阻塞页面其他内容的加载执行。此方法比较常见,我们常用的一些第三方库中,很多都采用这种方式。然而这种方式有个最大的问题就是无法保证多个脚本之间的加载顺序,比如我写了一个代码,这个代码要依赖于jQuery,但是如果我这个文件优先于jQuery脚本先下载完并立即执行,这时浏览器会报错——‘jQuery未定义’之类的,因为此时jQuery库还未下载完成。
3:LABjs
可以帮我们完成脚本的并行加载和按顺序执行,这也是我们公司目前用的主要方式,想要看详细的用法去官网看看。
常见用法:
1,
$LAB.script("script1.js") .script("script2.js") .script("script3.js") .wait(function(){// 等待所有script加载完再执行这个代码块 script1Func(); script2Func(); script3Func(); });
2,
$LAB.script("script1.js") .wait() // 空的wait()只是确保script1在其他代码之前被执行 .script("script2.js") // script2 和 script3 依赖于 script1 .script("script3.js") .wait() // 但是script2 和 script3 并不互相依赖,可以并行下载 .script("script4.js") //script4 依赖于 script1, script2 及 script3 .wait(function(){script4Func();});
3,
$LAB.script("script1.js") // script1, script2, and script3 之间没有依赖关系, .script("script2.js") // 所以可以任意顺序执行 .script("script3.js") .wait(function(){ // 如果需要,这里当然可以执行javascript函数 alert("Scripts 1-3 are loaded!"); }) .script("script4.js") // 依赖于 script1, script2 及 script3 .wait(function(){script4Func();});
上面实例中,前面三个脚本并行加载,任意顺序执行,如果有依赖并且脚本很多的话,没一个script函数后面接个wait就闲的代码很臃肿麻烦,所以labjs库提供了个参数可以确保下载完后顺序执行
$LAB.setOptions({AlwaysPreserveOrder:true})// 设置每个脚本之间等待 .script("script1.js")// script1, script2, script3, script4 互相依赖 .script("script2.js")// 并且并行下载后循序执行 .script("script3.js") .script("script4.js") .wait(function(){ script4Func(); });
这样写代码精炼了很多,推荐
4,
$LAB.script(function(){ // `_is_IE`的值ie为true ,非ie为false if(_is_IE){ return"ie.js"; // 如果是ie则这个js会被加载 }else{ return null; //如果不是ie这个代码就会被略过 } }) .script("script1.js") .wait();