——第一篇 Javascript加载执行问题探索)
首先大家看看如下的代码1 % Page LanguageC# AutoEventWireuptrue CodeBehindDefault.aspx.cs InheritsJsLoad.Default % 2 3 !DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd 4 html xmlnshttp://www.w3.org/1999/xhtml 5 head idhead 6 title/title 7 link hrefStyles/Site.css relstylesheet typetext/css / 8 script srcjquery/jquery-1.4.1.js typetext/javascript/script 9 script srcjs/hello.js typetext/javascript/script 10 script srcjs/world.js typetext/javascript/script 11 /head 12 body 13 img src1.jpg width200 height300 / 14 /body 15 /html估计90%的程序员都会把js文件放在head中但是大家有没有深究过呢很多浏览器都会使用单一的线程来做“界面UI的更新”和“JS脚本的处理“也就是当执行引擎遇到”script“的时候此时页面的下载和渲染都必须等待script执行完毕。那么对用户而言就悲哀了看着锁住的页面此时用户很可能就会给你关掉。从上面的瀑布图中我们可以看出二点第一三个js文件并行下载但是按我上面的理论中js应该是一个接一个的执行。然而在IE8Firefox3.5和Chrome2都实现了js的并行下载这是相当不错的但是他还是会阻碍一些其他资源的下载比如说图片。第二图片1.jpg的下载是在js执行完成后触发的这也验证了上面所说的情况阻止了image的加载。二第一步优化既然js阻止了UI渲染那么我们可以考虑将js放在/body前这样就可以让script前的html完美的呈现不会让用户看到页面空白等待而苦恼的情况自然就提高了友好性。1 % Page LanguageC# AutoEventWireuptrue CodeBehindDefault.aspx.cs InheritsJsLoad.Default % 2 3 !DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd 4 html xmlnshttp://www.w3.org/1999/xhtml 5 head idhead 6 title/title 7 link hrefStyles/Site.css relstylesheet typetext/css / 8 /head 9 body 10 img src1.jpg width200 height300 / 11 script srcjquery/jquery-1.4.1.js typetext/javascript/script 12 script srcjs/hello.js typetext/javascript/script 13 script srcjs/world.js typetext/javascript/script 14 /body 15 /html下面的图也展示了1.jpg和三个js几乎并行下载和执行。时间由上面的“469ms”缩小到“326ms”。三第二步优化看上面的“瀑布图”估计大家也看出来了三个js文件进行了三次“Get”请求大家都知道Get请求是需要带http头的所以说需要耗费时间那么我们采取的方案自然就是减少Get请求。通常有两种方案。第一合并js文件比如将上面的“hello.js和“world.js“合并掉。第二利用第三方工具比如php中的Minify。关于第二种做法taobao用的还是比较多的看一下其中的一个script应用了三个js文件。由3个Get请求变为了1个。四第三步优化不管是把js文件放在脚尾还是三个合并一个其本质都是”阻塞模式“就是说锁死浏览器当web页面越来越复杂js文件越来越多还是让我们头疼的此时我们就提倡一种“无阻塞模式“加载js脚本也就是页面全部呈现完再追加js也就对应着window.onload事件触发后我们才追加js这就是所谓的“无阻塞“但是其中有一个非常要注意的地方就是我们对js的要求是否有严格的顺序。第一无顺序要求比如我对”hello.js“和”world.js没有顺序要求那么我们完全可以用jquery来动态追加实现。1 % Page LanguageC# AutoEventWireuptrue CodeBehindDefault.aspx.cs InheritsJsLoad.Default % 2 3 !DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd 4 html xmlnshttp://www.w3.org/1999/xhtml 5 head idhead 6 title/title 7 link hrefStyles/Site.css relstylesheet typetext/css / 8 /head 9 body 10 img src1.jpg width200 height300 / 11 script srcjquery/jquery-1.4.1.js typetext/javascript/script 12 script typetext/javascript 13 window.onload function () { 14 $(#head).append(script srcjs/hello.js typetext/javascript\/script) 15 $(#head).append(script srcjs/world.js typetext/javascript\/script); 16 } 17 /script 18 /body 19 /html从图中可以看出hello.js和“world.js出现在蓝色线以后也就说明这两个js是在DomContentLoad结束后再进行触发加载的这样就不会造成页面的锁定等待。第二有顺序要求为什么一定要有顺序要求这个概念呢对于上面的那个动态追加的“两个js”文件在IE系列中你不能保证hello.js一定会在world.js前执行他只会按照服务器端返回的顺序执行代码。1 % Page LanguageC# AutoEventWireuptrue CodeBehindDefault.aspx.cs InheritsJsLoad.Default % 2 3 !DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd 4 html xmlnshttp://www.w3.org/1999/xhtml 5 head idhead 6 title/title 7 link hrefStyles/Site.css relstylesheet typetext/css / 8 /head 9 body 10 img src1.jpg width200 height300 / 11 script typetext/javascript 12 function loadScript(url, callback) { 13 var script document.createElement(script); 14 script.type text/javascript; 15 16 //IE 17 if (script.readyState) { 18 script.onreadystatechange function () { 19 if (script.readyState loaded || script.readyState complete) { 20 script.onreadystatechange null; 21 callback(); 22 } 23 } 24 } else { 25 //非IE 26 script.onload function () { 27 callback(); 28 } 29 } 30 script.src url; 31 document.getElementById(head).appendChild(script); 32 } 33 //第一步加载jquery类库 34 loadScript(jquery/jquery-1.4.1.js, function () { 35 //第二步加载hello.js 36 loadScript(js/hello.js, function () { 37 //第三步加载world.js 38 loadScript(js/world.js, function () { 39 40 }); 41 }); 42 }); 43 /script 44 /body 45 /html