作家
登录

编写高性能的JavaScript 脚本的加载与执行

作者: 来源:www.28hudong.com 2013-03-30 01:40:08 阅读 我要评论

脚本可以放在html页面的head里面,也可以放在body里面。 把脚本放在body中,当浏览器遇见<script>标签时, 浏览器不知道脚本会插入文本还是html标签,因此浏览器会停止分析html页面而去执行脚本。当使用src的方式添加脚本时,浏览器也会做同样的动作。在脚本处理的时候,页面呈现和用户交互将被完全阻止。脚本下载和执行阻塞了其他资源的下载,比如呈现页面使用的图片。(虽然很多浏览器实现了脚本并行下载的技术,但是这个问题依然没有解决) 脚本的位置 鉴于上面的理由,脚本应该始终放在页面的底部,即</body>前面。 一个简单的示例: 复制代码 代码如下: <html> <head> <title>Script Example</title> <link rel="stylesheet" type="text/css" href="styles.css"> </head> <body> <p>Hello world!</p> <script type="text/javascript" src="file1.js"></script> <script type="text/javascript" src="file2.js"></script> <script type="text/javascript" src="file3.js"></script> </body> </html> 合并脚本 因为脚本下载阻塞了页面呈现,因而应该减少页面<script>标签的使用,不管脚本是内联的还是外部的。在处理外部脚本的时候情况比较特殊,浏览器下载一个100kb的脚本的时间将远远小于4个25kb的脚本,因为建立一个请求要消耗大量的时间。所以页面应该尽量的减少外部脚本的引用。 非阻塞的脚本 秘诀在于当页面loading完成之后再来加载脚本,也就是在window对象的onload事件触发之前 。下面是实现的几种方式: 1.使用defer 复制代码 代码如下: <html> <head> <title>Script Defer Example</title> </head> <body> <script defer> alert("defer"); </script> <script> alert("script"); </script> <script> window.onload = function(){ alert("load"); }; </script> </body> </html> 页面弹出框出现的顺序: script/defer/load,这个技术的缺点是IE4+和FF3.5+才支持。 非阻塞的脚本(续) 2. 动态脚本元素 要知道<script>和普通的html标签并没有本质的区别,所以可以利用标准的DOM方法动态的添加脚本文件引用。方法如下: 复制代码 代码如下: var script = document.createElement("script"); script.type = "text/javascript"; script.src = "file1.js"; document.getElementsByTagName("head")[0].appendChild(script); 当这个标签一旦加入到html中,脚本文件就开始下载。这种方法的一个特点就是,文件下载和执行并不阻塞html页面其它部分的处理。通常将这样的脚本放在<head>中较之<body>更加安全,尤其是文件包含的代码需要在页面的load事件中执行。如果body的内容还没有被完全的加载,IE还会弹出“禁止操作”的错误。 当脚本文件下载完成之后,脚本立即执行(FF、Opera会等待前一个以同样方式添加的脚本执行)。当脚本自执行时,这没什么问题。但是如果脚本包含页面中其它脚本使用的interfaces,你需要确认脚本已经加载完成并且可用。幸好,当获得script标签的src的值之后,Firefox, Opera, Chrome, and Safari 3+ 会触发一个load事件。 复制代码 代码如下: var script = document.createElement("script") script.type = "text/javascript"; //Firefox, Opera, Chrome, Safari 3+ script.onload = function(){ alert("Script loaded!"); }; script.src = "file1.js"; document.getElementsByTagName("head")[0].appendChild(script); IE则提供了另外一种解决方案--readystatechange事件。根据下载 脚本文件所处的状态,readyState 的值有以下几种: "uninitialized" 默认状态 "loading" 开始下载 "loaded" 下载完成 "interactive" 下载完成,但是并非全部可用 "complete" 所有数据可用 IE的实现方式: 复制代码 代码如下: var script = document.createElement("script") script.type = "text/javascript"; script.onreadystatechange = function(){ if (script.readyState == "loaded" || script.readyState == "complete"){ script.onreadystatechange = null; alert("Script loaded."); } }; script.src = "file1.js"; document.getElementsByTagName("head")[0].appendChild(script); 下面是综合以后的通用方法: 复制代码 代码如下: function loadScript(url, callback){ var script = document.createElement("script") script.type = "text/javascript"; if (script.readyState){ //IE script.onreadystatechange = function(){ if (script.readyState == "loaded" || script.readyState == "complete"){ script.onreadystatechange = null; callback(); } }; } else { //Others script.onload = function(){ callback(); }; } script.src = url; document.getElementsByTagName("head")[0].appendChild(script); } The loadScript() function is used as follows: loadScript("file1.js", function(){ alert("File is loaded!"); }); 现在你可以按这种动态方式加载脚本了,但是你仍然需要考虑这些文件的下载顺序。主流浏览器中只有FF和Opera保证脚本的执行顺序和你指定的下载顺序一致,其他浏览器将按照脚本文件从服务器返回的顺序来执行。虽然如此,我们仍然有替代的解决方案: 复制代码 代码如下: loadScript("file1.js", function(){ loadScript("file2.js", function(){ loadScript("file3.js", function(){ alert("All files are loaded!"); }); }); }); 这样我们就能保证脚本文件的下载顺序严格的按照file1-file2-file3的方式进行。 注明:以上内容来自:<High Performance JavaScript>by Nicholas C. Zakas

  推荐阅读

  网站导致浏览器崩溃的原因总结(多款浏览器) 推荐

面试某公司的时候,面试官问到,导致浏览器崩溃的原因有哪些?愚辈不才,仅回答出了内存泄漏。其实在网页在装载的过程中,常常由于种种原因使浏览器的反映变的很慢,或造成浏览器失去响应,甚至会导致机器无法进行>>>详细阅读


本文标题:编写高性能的JavaScript 脚本的加载与执行

地址:http://www.17bianji.com/kaifa2/JS/26588.html

关键词: 探索发现

乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

网友点评
自媒体专栏

评论

热度

精彩导读
栏目ID=71的表不存在(操作类型=0)