Contenu connexe Similaire à 让我们的页面跑得更快 (20) 让我们的页面跑得更快2. 慢 500ms = 20% 将放弃访问 (Google) 慢 400ms = 5-9% 将放弃访问 (Yahoo!) 慢 100ms = 1% 将放弃交易 (Amazon) we 2.97 s they 1.67 s (2010.2.1--2010.3.1 ) 慢 1300 ms = ??% 将放弃访问 http://www.slideshare.net/stubbornella/after-yslow-a 我们? 3. 20/80 法则 0.16 s 后端 20% ( jsp 、 Apache 、 hibernate 、 Nginx....... ) 4. 20/80 法则 ∞ s 前端 80% ( js 、 css 、 images 、 <script></script> 、 jQuery.... ) 13. 首屏阻塞元素 首屏时间 总下载时间 下载速度 基础页下载字节数 DOM 元素个数 首屏对象数 页面的原代码的体积 Pconline 375.6k/63.3k Pcauto 273.4k/49.6k Zol 349.8k/85.7k Autohome 320.0k/50.3k xxx 10.5k/4.4k 14. 首屏阻塞元素 首屏时间 总下载时间 下载速度 基础页下载字节数 DOM 元素个数 首屏对象数 document.getElementsByTagName("*").length Pconline 7951 Pcauto 4975 Pclady 3474 Zol 2867 Autohome 4649 瑞丽 2860 VS 内容为王 ? 页面复杂程度 Reflow 30. 渲染 3 4 5 6 7 计算的样式 <style> body{...} .wrap{...} .xx{...} .header{...} .content{...} </style> 渲染块 渲染块 渲染块 <div class=“xx”></div> <style> .xx{......;background:url( logo.jpg )} </style> <style> .... </style> <html> <div class=“xx”></div> <script></script> .... .... <style> content{...} </style> <ul></ul> </html> 1 2 8 32. A. 样式精简合并 新页面—— CSS 模块化:后期维护成本 操作习惯的改变 经验的总结归纳 旧页面—— CSS 提取: Dust-Me DOM 操作、动态页使得提取存在风险 ? 更好的工具 :更加细心 36. defineJS () : 同步: XMLhttprequest 不能跨域 默认 UTF-8 ,如 js 含有中文需改为 UTF-8 格式 异步: getElementsByTagName("head")[0].appendChild(js); 可以跨域 异步对页面不会阻塞 如果有用到监听函数的返回值,则需要改为同步方式 eg : jQuery defineJS(“ !$,!jQuery,!$.getScript = /www1/js/pc.jquery1.4.js ”);// 同步 defineJS(“ featuredcontentslider.init =1000: http://www1.pconline.com.cn/global/2008/js/contentslider.js ”); // 异步 39. $.lazy() : jQuery 插件的 defineJS var p='http://www1.pconline.com.cn/js/'; $. lazy ( { name:‘cluetip’, //jQuery 插件名 cache:true, // 是否缓存 src:p+‘jquery.cluetip.js’,// 插件地址 dependencies:// 插件依赖的资源 { js:[p+'jquery.hoverIntent.js'], css:[p+'jquery.cluetip.css'] } }); $. lazy ({name:'bt', cache:true, src:p+'jquery.bt.js'}); http://www.pconline.com.cn/www1/js/pc.jquery1.4.js 40. 接口后出: var old_node=document.getElementById("old_node"); var s=document.getElementById("new_node").getElementsByTagName("script"); for(var i=0;i<s.length;i++){ s[0].parentNode.removeChild(s[0]);// 防止接口重复请求 } old_node .parentNode.replaceChild(document.getElementById(" new_node "), old_node ); <div id=" new_node "><script class=" defer" src="http://game.pcgames.com.cn/jsp/interface/item_piece_js.jsp?id="></script></div> <div id="topTxt"></div> <div id="topTxt"></div> <div id=" old_node "></div> 41. setTimeout : <div id="topTxt"></div> <div id="topTxt"></div> if(window.ajaxLogon0906) ajaxLogon0906(); else setTimeout (function(){ var js=document.createElement("script"); js.src="http://www1.pconline.com.cn/global/2009/js/chalogon09.js"; document.getElementsByTagName("head")[0].appendChild(js); },1000) // 登陆 js 后出 对于网速较慢的用户后出效果并不理想 比如汽车网首页品牌下拉框,当鼠标移上去时才初始化。一些不是一开始就需要的效果,可在 body.onload 里加载,为避免代码冲突,可以用下面的代码: if(window.attachEvent) document.body.attachEvent("onload",fn); else document.body.addEventListener("load",fn); 42. 普通调用事件化: <div id="topTxt"></div> <div id="topTxt"></div> if(window.attachEvent) document.body. attachEvent ("onload",fn); else document.body. addEventListener ("load",fn); 比如汽车网首页品牌下拉框,当鼠标移上去时才初始化。一些不是一开始就需要的效果,可在 body.onload 里加载,为避免代码冲突,可以用下面的代码: 比如汽车网首页品牌下拉框,当鼠标移上去时才初始化。一些不是一开始就需要的效果,可在 body.onload 里加载,为避免代码冲突,可以用下面的代码: if(window.attachEvent) document.body.attachEvent("onload",fn); else document.body.addEventListener("load",fn); 57. 字符串合并 var reselt=“aaa”+”bbb”; 下面的代码效率更高,但不易维护,如果字符串相加操作量不大可不用以下方式 var buf=new Array(); buf.push(“aaa”); buf.push(“bbb”); var result=buf.join(“”); a += 'x' + 'y'; 后者比前者快 20% ,而且消耗更少的内存: a += 'x'; a += 'y'; 58. var min = Math.min(a,b); A.push(v); 下面代码实现相同功能,但效率更高: var min = a < b ? a : b; A[A.length] = v; 还有 ... 基本运算符比函数调用更快 59. var original = document.getElementById('container'); var cloned = original. cloneNode (true); // 克隆节点,处理完后再替换原节点 cloned.setAttribute('width','50%'); var elem, contents; for( var i = 0; i < textlist.length; i++ ) { elem = document.createElement('p'); contents = document.createTextNode(textlist[i]); elem.appendChild(contents); cloned.appendChild(elem); } original.parentNode. replaceChild (cloned,original); DOM 元素处理尽量脱离 DOM 树 if(window.ajaxLogon0906) ajaxLogon0906(); else setTimeout(function(){ var js=document.createElement("script"); js.src=“http://www1.pconline.com.cn/global/2009/js/chalogon09.js”;// 先设置 src ,再插入 document.getElementsByTagName("head")[0].appendChild(js); },1000) 60. var toChange = document.getElementById('mainelement'); toChange.style.background = '#333'; toChange.style.color = '#fff'; toChange.style.border = '1px solid #00f'; 通过修改元素 class 名使用新样式,效率更高, reflow 更少: div { background: #ddd; color: #000; border: 1px solid #000; } div.highlight { background: #333; color: #fff; border: 1px solid #00f; } ... document.getElementById('mainelement').className = 'highlight'; 修改元素 class 名 61. document.getElementById('test').property1 = 'value1'; document.getElementById('test').property2 = 'value2'; document.getElementById('test').property3 = 'value3'; document.getElementById('test').property4 = 'value4'; 下面的代码比上面的代码要快 5-10 倍: var sample = document.getElementById('test'); sample .property1 = 'value1'; sample .property2 = 'value2'; sample .property3 = 'value3'; sample .property4 = 'value4'; 用变量保存 DOM 值 62. jQuery 选择符本质: $(“#id”) : document.getElementById(“id”); // 快 $(“div”) : document.getElementsByTagName(“div”); // 较慢 $(“.class”) : ????? // 很慢很慢 var all=document.getElementsByTagName(“ * ”); for(var i=0;i<all.length;i++){ if(all[i].className=“class”){ return all[i]; } } $(“.class”,$(“#id”)) // 好一些 jQuery 不要直接使用 class 作为选择符 http://blog.dynatrace.com/2009/11/09/101-on-jquery-selector-performance/ $(“#id”).addClass(“yyy”); $(“#id ul”).show(); $(“#id ul li”).addClass(“xxx”); // 慢 var div=$(“#id”); div.addClass(“yyy”); $(“ul”,div).show(); $(“li”,div).addClass(“xxx”); 63. $(‘#traffic_light input.on).bind(’click‘, function(){…}); $(’#traffic_light input.on).css(‘border’, ‘3px dashed yellow’); $(‘#traffic_light input.on).css(’background-color‘, ‘orange‘); $(’#traffic_light input.on).fadeIn(’slow’); 将 jquery 对象缓存起来 http://blog.dynatrace.com/2009/11/09/101-on-jquery-selector-performance/ var $active_light = $(‘#traffic_light input.on’); $active_light.bind(‘click’, function(){…}); $active_light.css(‘border’, ‘3px dashed yellow’); $active_light.css(‘background-color’, ‘orange’); $active_light.fadeIn(’slow’); OR $(‘#traffic_light input.on’).bind(‘click’, function(){…}).css(‘border’, ‘3px dashed yellow’).css(‘background-color’, ‘orange’).fadeIn(’slow’); 64. $(document).rady 在 DOM 载入时执行,有可能会延迟不够,影响到页面的渲染 $(window).load http://blog.dynatrace.com/2009/11/09/101-on-jquery-selector-performance/ $(window).load 在所有内容加载后触发,包括窗口,框架,对象和图像 71. CSS 选择符对页面的影响 1. 页面元素越多,渲染时间对页面速度的影响越明显。 2. 选择符从右至左匹配,最右边的选择符匹配效率最为关键。 http://stevesouders.com/efws/css-selectors/csscreate.php 76. 并发 ie 中,同一个 script 中用 document.write 可以并发 // 并发 js 和 css <script> document.write(“a.css”); document.write(“b.js”); </script> // 并发 js 和 js <script> document.write(“a.js”); document.write(“b.js”); </script> 为保证模板在 DW 中的效果,样式表在 <head> 中写成 <c:set var="CSS"> <link href="...." rel="..."/> </c:set> 然后在 body 中 ivy.js 的地方,写成 <script> document.write('${CSS}'); if(!window.addIvyID)document..... //ivy.js document.write("<script src= 头部 js></script>"); </script> 78. IE6 下背景图加载顺序测试 <div style="background:url(bg.png)"></div><img src="img1.jpg"/> 很多图 <div style="background:url(bg.png)"><img src="img1.jpg"/><img src="img2.jpg"/></div> <div style="background:url(bg.png)"></div><img src="img1.jpg"/><script></script><img src="img2.jpg"/> 加载顺序 : img1.jpg > 很多图 > bg.png 加载顺序 : img1.jpg > bg.png > img2.jpg 加载顺序 : img1.jpg > bg.png > img2.jpg 初探 IE6 的内部机制