javaScript 在浏览器中的运行性能,在web2.0时代显得尤为重要,成千上万行javaScript代码无疑会成为性能杀手,
在较低版本的浏览器执行JavaScript代码的时候,由于浏览器只使用单一进程来处理ui界面刷新和JavaScript脚本执行,
这意味着在加载javascript文件的时候不能同时做任何其他的事情。 在加载的同时造成了用户交互阻塞;
理论上来说,把样式与行为有关的脚本放在一起率先加载,这样有利于确保正确的用户体验,例如下面的代码:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>javascript</title> <script src="file.js" type="text/javascript" charset="utf-8"></script> <script src="file1.js" type="text/javascript" charset="utf-8"></script> <link rel="stylesheet" type="text/css" href="file.css"/> <link rel="stylesheet" type="text/css" href="file1.css"/> <link rel="stylesheet" type="text/css" href="file2.css"/> </head> <body> </body> </html>
这种看似合理的代码其实有着很严重的性能问题:在javascript文件加载并执行完成之前会阻止页面进行渲染,我们的web页面会出现一片空白
无法与之正常交互,这称之为脚本阻塞
由于脚本会阻塞页面其他资源的加载 我们可以把所有的script标签放在</body>之前 在页面加载的最后来加载javascript文件
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>javascript</title> <link rel="stylesheet" type="text/css" href="file.css"/> <link rel="stylesheet" type="text/css" href="file1.css"/> <link rel="stylesheet" type="text/css" href="file2.css"/> </head> <body> <!--推荐所有的js文件位置--> <script src="file.js" type="text/javascript" charset="utf-8"></script> <script src="file1.js" type="text/javascript" charset="utf-8"></script> </body> </html>
-----------优化javascript的首要任务,将js文件放置在页面底部;
那如何创建一个无阻塞的脚本呢?
无阻塞脚本的秘诀在于,在页面加载完成之后才开始加载javascript代码。 我们要在window对象的load时间触发后再下载并执行脚本,
已知有很多种方式可以实现这一效果,这里简单例举一二:
1.HTML5新特性
html5为script标签提供了两个新的属性 一个是defer 另一个是async 它们采用的都是并行下载的方式; 在下载过程中并不会造成页面阻塞
它们的区别在于 defer表示等待页面加载完成才会执行,async则是它本身加载完成后就自动执行;
defer目前已被各大主流浏览器所兼容;
2.创建动态脚本元素;这很容易使页面渲染完成之后再进行脚本加载;
例如:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>javascript</title> </head> <body> <script type="text/javascript"> var script = document.createElement("script"); script.src = "ztf.js"; document.getElementsByTagName("head")[0].appendChild(script); </script> </body> </html>
我们使用标准的dom方法document.createElement来动态的创建一个script元素并指定它的src;这行成了一个动态的脚本模式;在任意时刻插入任意的javascript代码都会被浏览器执行;(创建的script最好不要插入到body里面;这样可能会引起ie抛出一个‘操作已终止’的错误信息;)
ff,opera,chrome和safari3以上版本的script标签会在加载完成触发onload事件。
而在老版本ie下(ie6-10) 它会触发一个readystatechange事件。<script>元素会提供一个readyState属性,它的值在scr加载不同过程产生不同的变化;我们通常会使用到 "loaded" 和 "complete"。
通过“客户端能力检测” (http://www.jxbh.cn/newshow.asp?id=1434&tag=2) 我们可以创建一个通用的动态加载javascript的函数:
function loadScript(url,callback){ var script = document.createElement("script"); script.type="text/javascript"; if(script.readyState){ //客户端能力检测 如果支持readyState则返回的是字符串 反之返回undefined script.onreadystatechange = function(){ //onreadystatechange事件 if(script.readyState=="loaden"||script.readyState=="complete"){ script.onreadystatechange=null; callback(); } } }else{ script.onload = function(){ callback(); } } script.src = url; document.getElementsByTagName("head")[0].appendChild(script); }
这个函数接受两个参数;javascript文件的url和完成加载后的回调函数。loadScript()函数的用法如下
loadScript("ztf.js",function(){ alert("loadend") });
如果需要的话,你可以尽可能多的加载javascript文件到页面上,但一定要考虑清楚文件的加载顺序,可以不断的使用callback回调函数加载多个javascript脚本;
另外还有一种,ajax动态请求加载脚本 在这里笔者就不一 一说明 ,大家查阅有关文档;
部分内容摘自《高性能javascript》