javascript性能

来源:互联网 发布:csol优化参数 编辑:程序博客网 时间:2024/05/20 05:11

1、浏览器在遇到<body>标签之前,不会渲染页面的任何部分。

如果将<script>标签放在<body>,这种方法把脚本放在页面的顶端,将导致一个可以察觉的延迟,通常表现为:页面打开时,首先显示为一幅空白的页面,而此时用户即不能阅读,也不能与页面进行交互操作。

推荐:将所有的<script>标签放在尽可能接近<body>标签底部的位置

 

2、由于每个<script>标签下载时阻塞页面解析过程,所以限制页面的<script>总数也可以改善性能。

 

非阻塞脚本:

等页面加载完成后,再加载Javascript源码,意思是:在window.onload事件发生后才开始下载源码。

方法1:延期脚本

<script type="text/javascript" src="fileUpload.js"defer></script>

但是只在IE 4+ 和 FF 3.5+才支持。

方法2:动态脚本元素

文档对象模型(DOM)允许使用javascript动态创建HTML的几乎全部文档内容。因为<script>元素与页面中的其它元素没有什么不同。

所以一个<script>可以很容易通过标准DOM创建:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312" /><title>动态脚本元素</title><style type="text/css">*{margin:0;padding:0;font-family:微软雅黑}span{position:absolute;left:0;top:0}</style></head><body><span>测试</span></body><script type="text/javascript">window.onload = function() {var jQueryScript = document.createElement("script");jQueryScript.type = "text/javascript";jQueryScript.src = "jquery-1.9.1.min.js";document.getElementsByTagName("head")[0].appendChild(jQueryScript);//不能随即调用jQuery中的方法,我们不知道什么时候能加载完成/**IE中可以调用onreadystatechange *<script>有个readyState属性,它随着外部文件的加载过程而改变 *1、"uninitialized" :默认状态 *2、"loading" :下载开始 *3、"loaded" :下载完 *4、"interactive" :下载完但是不可用 *5、"complete" :所有数据已经准备好 *由于<script>加载的过程中,这些状态不一定会都出现,我们只需关系loaded和complete两种状态 *考虑到可能不会同时出现,用||即可,为了不让事件重复绑定,当出现其中一种状态时清空readystatechange事件*************************************/ jQueryScript.onreadystatechange = function(){if(jQueryScript.readyState == "loaded" || jQueryScript.readyState == "complete") {jQueryScript.onreadystatechange = null;callback();}}//非IEjQueryScript.onload = function(){callback();}}; //当加载完成后就可以调用jQuery中的方法了 function callback() {jQuery(document).ready(function(){$("span").animate({"left":"300px","top":"500px"},5000);});}</script></html>

考虑通用性,可以稍作整理:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/  xhtml1/DTD/xhtml1-transitional.dtd">  <html xmlns="http://www.w3.org/1999/xhtml">  <head>  <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />  <title>动态脚本元素</title>  <style type="text/css">  *{margin:0;padding:0;font-family:微软雅黑}  span{position:absolute;left:0;top:0}  </style>  </head>    <body>  <span>测试</span>  </body>    <script type="text/javascript">  LoadScript = (function(doc){var position = doc.getElementsByTagName("body")[0],script = doc.createElement("script"),script.type = "text/javascript";//加载jsfunction load(url,callback) {if(typeof url != "string" || url == null || url == '') {alert("加载失败...");return ;}if(script.readyState) {  script.onreadystatechange = function(){  if(script.readyState == "loaded" || script.readyState == "complete") {  script.onreadystatechange = null;  callback();  }  };  } else  {  script.onload = function(){  callback();  };  }script.src  = url;position.appendChild(script);}return {js:function(url,callback){load(url,callback);}};})(this.document);LoadScript.js("jquery-1.9.1.min.js",function(){$("span").animate({"left":"300px","top":"500px"},5000);  });  </script>  </html>  

完整写法:参考loadScript.js

调用如:

<script type="text/javascript">Require.js(['js/jquery.anchor-1.0.0.js'],function(){jQuery.anchor({layer:$(".yitian-layer")});});Require.js(['js/yitian.footer-1.0.0.js'],function(){Yitian.footer.loader({start:2012});});</script>
可以传入多个参数:

/** * javascript 样式,js文件导入 * @author:xuzengqiang * @since :2015-3-12 21:36:08 * 调用方式: * Require.css('index.css',function(){ *  //加载完成后的回调函数 * }); * Require.js(['js/jquery.anchor-1.0.0.js','js/common.js'],function(){});**/var Require = (function(window){var document = window.document,agent = window.navigator.userAgent.toLowerCase(),queue = { //任务队列css : [],js  : []},head = document.head || document.getElementsByTagName("head")[0],//目前正在进行的请求request = {},//轮询总数pollCount = 0;//全局变量window.DOMUtils = {//描述:创建一个元素,name:元素名称,attrs:属性集合{id:'content',class:'content'};createElement:function(name,attrs){var element = document.createElement(name);for(var attr in attrs) {element.setAttribute(attr,attrs[attr]);}return element;}};//浏览器信息window.Browser = {agent: agent,isIE : /mise|trident/.test(agent),//Gecko内核isGecko : agent.indexOf("gecko") > 0 && agent.indexOf("like gecko") < 0,//webkit内核isWebkit : agent.indexOf("webkit") > 0 };var Load = {run : function(type,urls,callback) {var isCSS = (type === "css"), //加载类型,只考虑js和cssnode,current; //节点 if(urls) {//concat()用于连接数组,但是不会改变现有数组,只是返回被连接数组的一个副本urls = typeof urls === 'string' ? [urls] : urls.concat();//除了Firefox和Opera浏览器能够保证并行加载且能保留顺序执行,所以统一按顺序将任务加入到任务队列中for(var i=0,maxLen = urls.length;i<maxLen;i++) {queue[type].push({url : urls[i],callback : (i === maxLen-1)? callback : null //当有多个等所有资源加载完成后才调用callback});}}//如果资源加载完成if (request.type || !(current = request.type = queue[type].shift())) {return false;}if(isCSS) {//火狐下不支持link标签的onload事件.所以创建style标签,通过@import引入样式node = Browser.isGecko?DOMUtils.createElement("style"):DOMUtils.createElement("link",{type:'text/css',rel:'stylesheet',href:current.url});} else {node = DOMUtils.createElement("script",{type:'text/javascript',src:current.url});//同步加载,防止顺序错乱node.async = false;}node.className="require";node.setAttribute("charset","utf-8");//IE浏览器且不是CSS文件if(Browser.isIE && !isCSS && node.onreadystatechange) {    node.onreadystatechange = function(){    if(/loaded|complete/.test(node.readyState)) {    node.onreadystatechange = null;    Load.complete(type);}    }; //webkit内核和gecko内核不支持link节点的onload方法,document.getElementsByTagName("link")[0].onload} else if(isCSS && (Browser.isWebkit || Browser.isGecko)) { if (Browser.isWebkit) {  //current.url = node.href; // 解决相对url(或轮询不会工作)  Load.pollWebkit(type); } else {  node.innerHTML = '@import "' + current.url + '";';  Load.pollGecko(node); }} else  {    node.onload = node.onerror = function(){Load.complete(type);};  }  head.appendChild(node);},complete:function(type){var req = request.type,callback;//如果有请求if(req) {callback = req.callback;pollCount = 0;// 如果为最后一个待加载的URL 执行回调并且开始下一个队列中的请求(如果有)  if (req.url !== null) {if(typeof callback !== 'undefined' && callback !== null) {callback();}request.type = null;queue[type].length && Load.run(type);// 队列中如还有当前类型的资源 加载该类型资源  }}},//轮询判断样式是否已经加载完成,样式加载完成后或10s后停止轮询pollWebkit:function(type){var css = request.type, len, styleSheets = document.styleSheets; if (css !== null) {      len = styleSheets.length; //遍历styleSheets判断是否加载完毕      while (--len >= 0) {        if (styleSheets[len].href === css.url) {          Load.complete('css');          break;        }      }pollCount += 1; if (css !== null) {        if (pollCount < 200) {          setTimeout(function(){Load.pollWebkit(type);}, 50);        } else {          Load.complete('css');        }      }    }},//内核为Gecko的浏览器轮询pollGecko:function(node){var hasRules; //是否已经加载完成 try {     hasRules = !!node.sheet.cssRules;} catch (ex) {// 样式表仍然是在加载...那么轮询10秒,超过10s,退出pollCount += 1; if (pollCount < 200) {setTimeout(function () { Load.pollGecko(node); }, 50);} else {hasRules && Load.complete('css');} return false;}Load.complete('css');}};return {css:function(urls,callback) {return Load.run("css",urls,callback);},js:function(urls,callback) {return Load.run("js",urls,callback);}}})(window);





0 0
原创粉丝点击