前端脚本代码之效率优化
作者:秋了秋 发表时间:2015年05月04日
代码在浏览器中执行是要时间的,只不过很多时候,这个时间非常短,短到让我们感觉不到,这不等同于网页内容的下载,比起代码执行时间,网页加载是个可以明确感知到速度的东西,比如我们打开一个网页,加载进度条一直在那转转转,其实就是在下载网页所需的文件。而这里说的代码执行不等同于这个。
代码执行需要时间,都是瞬间的事,我们感知不到,但是如果代码写得不好的话,这个时间就会延长的,尤其是js的执行,同一种方法,用js可以有很多种写法。但是各自的执行时间是不一样的,用一个糟糕的写法将会严重降低代码执行效率,慢到可以让你感觉到它的存在~
自己就犯过这样的错误,比如:
for(i=0,i<$("#obj").height(),i++){
//这里放循环的内容
}
这样就导致了每执行一次循环内容都要去document.getelementById("obj"),众所周知document.getelementById方法是去整个网页文档代码中寻找匹配的元素。这个效率是很低的,况且它每执行一次就要运行一下这个方法,如果i的值非常大的话,而你又在网页中多处用了这种for循环,如果循环内容是个实时动画的话,将会明显感知到动画的迟缓性。良好的写法是将$("#obj").height()存入缓存:
var abc=$("#obj");
for(i=0,$abb=$abc.height(),i<abb,i++){
//这里放循环的内容
}
除了js脚本有效率之称外,css同样有效率高低之分,css是给浏览器渲染页面的基石。基石打得不好,将给浏览器造成麻烦。
最近又遇到一个奇葩的问题,众所周知,同一个元素同一属性被定义了两次,浏览器只认最后一个属性,即前面的被后面的覆盖,虽然出来的效果是我们想要的后面的那个效果。但是浏览器对这个页面的这个元素渲染了两次,这是要花时间成本的,虽然时间短得让我们感觉不到。可是我碰到的问题是时间长得无法让我想象:
<div id="fff"><p>秋叶网络博客</p><p class="uur">netblog.cn</p></div>
#fff P{-webkit-transform: scale(0.8);-moz-transform: scale(0.8);-ms-transform:scale(0.8);transform:scale(0.8);} #fff .uur{-webkit-transform: scale(0.8);-moz-transform: scale(0.8);-ms-transform:scale(0.8);transform:scale(0.8);}
就像这样,在一个页面中重复把.uur同一属性transform写了两次,结果页面直接打不开~~,但是单独运行这段代码又可行在页面中有众多css3渲染的情况下是不行的,js冲突导致页面打不开这很好理解,css冲突这就是稀奇了。
现在给大家整理一些网页性能小tips给大家参考,养成良好的代码书写习惯: 1、jQuery类型的变量最好加个$前缀;时常将jQuery选择器返回的内容存进变量以便重用,避免重复遍历文档。
var $products = $("div.ehyduct");
2、id选择器比类选择器快
var $products = $(".pro"); // 慢 var $products = $("#pro"); // 快
3、多级查找中,右边尽量指定得详细点而左边则尽量简单点
$("p.at .ez");//优化前 $(".at td.ez");// 优化后
4、指定查找范围
$('.class');//原始代码 $('.class', '#class-container');//在#class-container容器范围内进行查找
5、不要使用通配符万能选择器
$('div.container > *'); // 差 $('div.container').children(); // 棒
6、ID已经是唯一了,不需要具体
$('.outer-container #inner'); // 差 $('#inner');//干净利落,好!
7、不要处理不存在的元素
$("#nosuchthing").slideUp();// 丧尽天良的做法:jQuery后台要执行三遍查询后才会知道这个元素其实根本不存在从而放弃 // 应该这样 var $mySelection = $("#nosuchthing"); if ($mySelection.length) {$mySelection.slideUp();}
8、尽量不要把js写在内联html上
<a id="myLink" href="#">my link</a> <!--内联绑定 不好 -->
$("#myLink").on("click", myEventHandler);//js中绑定,好!
9、表在链接里面嵌参数,请使用专门的参数设置来传递
// 不易阅读的代码... $.ajax({ url: "something.php?param1=test1¶m2=test2", .... });// 更易阅读... $.ajax({ url: "something.php", data: { param1: test1, param2: test2 } });
提供标准的ajax模版一份参考:
var jqxhr = $.ajax({ url: url, type: "GET", // 默认为GET,你可以根据需要更改 cache: true, // 默认为true,但对于script,jsonp类型为false,可以自行设置 data: {}, // 将请求参数放这里. dataType: "json", // 指定想要的数据类型 jsonp: "callback", // 指定回调处理JSONP类型的请求 statusCode: { // 如果你想处理各状态的错误的话 404: handler404, 500: handler500 } }); jqxhr.done(successHandler); jqxhr.fail(failureHandler);
10、用链式保存变量
$("#myDiv").addClass("error").show();
11、巧用数组形式传递多个属性
$myLink.attr("href", "//netblog.cn").attr("title", "my link").attr("rel", "external"); // 糟糕:调用了三次attr // 不错,只调用了一次attr $myLink.attr({ href: "//netblog.cn", title: "my link", rel: "external" });
12、尽量不要用js操作css
$("#mydiv").css({'color':red, 'font-weight':'bold'}); // 不好 //nice! css:.error {color: red;font-weight: bold;} js:$("#mydiv").addClass("error");
13、能用js尽量少用jq,浏览器要先把jq转变成原生js。。。
$("#myId"); // 多少还是会逊色于...
document.getElementById("myId");