书写高效的jquery代码

一、浏览器渲染原理
  1. 用户输入网址(假设是个html页面,并且是第一次访问),浏览器向服务器发出请求,服务器返回html文件;
  2. 浏览器开始载入html代码,发现<head>标签内有一个<link>标签引用外部CSS文件;
  3. 浏览器又发出CSS文件的请求,服务器返回这个CSS文件;
  4. 浏览器继续载入html中<body>部分的代码,并且CSS文件已经拿到手了,可以开始渲染页面了;
  5. 浏览器在代码中发现一个<img>标签引用了一张图片,向服务器发出请求。此时浏览器不会等到图片下载完,而是继续渲染后面的代码;
  6. 服务器返回图片文件,由于图片占用了一定面积,影响了后面段落的排布,因此浏览器需要回过头来重新渲染这部分代码;
  7. 浏览器发现了一个包含一行Javascript代码的<script>标签,赶快运行它;
  8. Javascript脚本执行了这条语句,它命令浏览器隐藏掉代码中的某个<div> (style.display=”none”)。杯具啊,突然就少了这么一个元素,浏览器不得不重新渲染这部分代码;
  9. 终于等到了</html>的到来,浏览器泪流满面……
  10. 等等,还没完,用户点了一下界面中的“换肤”按钮,Javascript让浏览器换了一下<link>标签的CSS路径;
  11. 浏览器召集了在座的各位<div><span><ul><li>们,“大伙儿收拾收拾行李,咱得重新来过……”,浏览器向服务器请求了新的CSS文件,重新渲染页面。
二、Reflow and Repaint
  1. 当浏览器需要更新它的呈现模型时(即将DOM与组成页面样式组件的css规则合并在一起)就会发生重布局(reflow)和重绘(repaint),只要加载页面,至少会发生一次重布局和重绘,但是在动态页面的应用程序中,会发生多次reflow和repaint。
  2. Reflow 与Repaint 相关但是有区别
  3. 当改变样式,不改变页面的几何布局时,将发生重绘。隐藏一个元素,或者改变一个元素的背景色时,都将导致一次重绘。
  4. 当 页面的结构进行更新时,将导致重布局。从文档中添加、移除元素,改变元素的大小或改变元素,会reflow。Reflow的代价大于repaint,因为它涉及使用当前DOM/CSS的定义,重新计算页面的几何结构。
三、jsjQuerymin dom update
1当要进行DOM插入时,完全在JavaScript中创建或操纵Dom,仅一次性地将其更新到DOM中。
Eg:不推荐:
For( var i=0;I < 10000;i++){
  $(“#main  table”).append(“<tr><td>My job is to log table rows,this is row #” + I “</td></tr>”)}
推荐:
Var tableRows = “”;
For (var i=0;I < 10000;i++){
tableRows +=“(“<tr><td>My job is to log table rows,this is row #” + I “</td></tr>”}
$(“#main table”).append(tableRows);

四、更高效的循环

  1. 在绝大多数情况下,在集合中使用jquery便利的$.each()方法便利数组的成员,这是一个可接受的的、理想的解决方案。
  2. 对于巨大的几何,此方法不可接受,速度会成为问题,此时应使用原生js控制结构。
  3. 遍历的方法主要有1、$.each() < 2、Array.forEach()或者[ ].forEach()  <  3、for(){}。2可用时jquery应回退到es5的此方法。
五、高效的使用选择器
  1. 解析引擎自右向左计算每一条规则,从关键(key)选择器开始,自右向左计算每一个选择器,直到发现一个匹配的选择器, 无匹配(regexp)则放弃
  2. 具体话的选择器id>tag>class
  3. 包括sizzle引擎和内建的document.querySelectorAll,它们都是用了相同的技术。
  4. jQuery核心之jQuery([selector,[context]])
  5. 默认情况下,当把一个选择器传递给jQuery时,它将遍历整个DOM。利用jquery核心函数,匹配选择器给他附加一个上下文可以提高遍历的速度和效率。如果传入的上下文本身需要经过较慢的搜索才能达到,那么它对提升jquery选择器的速度没有多少帮助。
  6. $(“.className”);将遍历整个DOM
  7. $(“.className”,”#id”)仅搜索#id元素 此方法推荐不需要遍历但重复使用class节点时使用,谨记$(“#id”)的遍历速度是最快的
  8. 父子选择器推荐$parent.find('.child')
六、缓存

 

选中某一个网页元素,是开销很大的步骤。所以,使用选择器的次数应该越少越好,并且尽可能缓存选中的结果,便于以后反复使用。
不推荐:
jQuery('#top').find('p.classA'); jQuery('#top').find('p.classB'); 
推荐:
var cached = jQuery('#top'); cached.find('p.classA'); cached.find('p.classB'); 
当然每当你使用一次选择器(比如$('#id')),就会生成一个jQuery对象。jQuery对象是一个很庞大的对象,带有很多属性和方法,会占用不少资源。所以,尽量少生成jQuery对象。
不推荐
var $text = $("#text"); var $ts = $text.text(); 
推荐
var $text = $("#text"); var $ts = $.text($text); 
七、使用直接函数,而不要使用与与之等同的函数
 
为了获得更好的性能,你应该使用直接函数如$.ajax(),而不要使用$.get(),$.getJSON(),$.post(),因为后面的几个将会调用$.ajax()。
八、跳过jquery
 
对于网站或者应用程序而言,性能是首要考虑因素。那么请记住在哪些完全可以跳过jquery方法的地方,回归原生js。一个常见的例子就是attr方法的href属性,然后在使用attr()方法将其应用于另外一个元素
不推荐:
$(“#abc”).attr(“href”,$(this).attr(“href”));
推荐:
document.getElementById(“abc”).href = this.href;
九、DRY(Don’t repeat yourselef)
  1. 对于性能和维护而言,这是一个重要的原则。
  2. Jquery中唯一鼓励重复性的地方就是使用匿名函数,将一个匿名函数传递给一个时间处理程序如此地常见。
    $(“#foo”).click(
        $(this).addClass(“active”);
        $.get(“/my/app/service/”,function(data){
            $(#dialog).text(data.status).dialog(“open”);
        })
    );
    $(“#abc”).click(
        $(this).addClass(“active”);
        $.get(“/my/app/service/”,function(data){
            $(#dialog).text(data.status).dialog(“open”);
        })
    );
    $(“#baz”).click(
        $(this).addClass(“active”);
        $.get(“/my/app/service/”,function(data){
            $(#dialog).text(data.status).dialog(“open”);
        })
    );
    可以将多个选择器几何为一个选择器的列表,简化代码

 

$(“# foo ,#abc,  #baz”).click(
    $(this).addClass(“active”);
    $.get(“/my/app/service/”,function(data){
        $(#dialog).text(data.status).dialog(“open”);
    })
);    
十、以匿名函数调用
 
Function outHandler(){
    $(this).click(
    $(this).addClass(“active”);
    $.get(“/my/app/service/”,function(data){
        $(#dialog).text(data.status).dialog(“open”);
    })
    );
}
$(“#baz”). on(“click”,ourHandler);
    
十一、使用一个单例创建一个应用程序的名称空间
 
var Home = {
    options: {
        code: ""
    }
};
Home.init = function() {
Home.autoLogin();
};
Home.autoLogin = function() {
    var a = getCookie("autoLogin");
    if (a !== null && !Home.sessionFail) {
        location.href = "default.aspx"
    } else {
        Home.returnLogin()
    }
};
$(function() {
    Home.init()
});
posted @ 2015-06-01 16:59  徐学进  阅读(228)  评论(0)    收藏  举报