登录
文章RSS 评论RSS
您还浏览过:
    • 前端技术
      • Div+Css
      • JavaScript
      • jQuery
      • AngularJs
    • 后端程序
      • node.js
      • PHP
    • 网站管理系统
      • 织梦
      • wordpress
    • 操作系统
      • Windows
      • Linux
    • 随 笔
    当前位置: Home » JavaScript » 正文

    JavaScript代码优化

    javascript, jQuery, 效率, 代码优化 2 条评论 围观360次

    优化什么,何时优化?

    与技术同等重要的是:能适时的进行代码的优化。过早的代码优化,可能会引起晦涩的代码和一些程序的bug,而且优化很少执行的代码块也是没有多大必要的。以帕莱托法则(80 - 20法则)来看,20%的代码将占80%的CPU周期。程序员应该集中于优化这20%、10%或5%,而忽略其它部分。这样的话,bug更少,并且大部分代码都具有可读性,也为后期开发减小难度。

    关于Js代码的执行性能,你可以用Firebug等性能测试工具,来了解哪些函数执行花去了绝大部分时间,然后检查这些函数并决定要优化的代码段。

    下图所示的是用Firebug性能测试的界面。在“控制台”菜单下,选择“概况”来开始性能测试,然后再选择“概况”来停止测试。然后Firebug就会显示所有在开始和结束点之间被调用的JavaScript函数分析。所显示的信息如下所示:

    Firebug测试页面性能

    自定义代码性能测试

    浏览器并不是运行准确代码性能测试的完美环境。短时间的定时器不够准确、事件的要求、零散的垃圾回收和系统上运行的其它进程都会导致结果偏差。一般可以这样来测试JavaScript代码的性能。

    var startTime = new Date().getTime();
    //Run some test code here
    var timeElapsed = new Date().getTime()-startTime;

    这种方法理论上可行,但在现实中它并不能给出准确的结果。尤其是当被测试代码只有几毫秒执行时间的情况下。

    更好的方法是让被测试代码先运行较长时间(如1秒),然后再用那段时间完成的循环次数来评价性能。如果你要计算均值(mean)和中值(median)等统计信息,可以重复测试几次。

    为了保证测试运行时间,可以使用如下代码:

    //Credit: based on code by John Resig.
    var startTime = new Date().getTime();
    for(var iters = 0; timeElapsed < 1000; iters++){
    	//Run some test code here.
    	timeElapsed = new Date().getTime() - startTime;
    }
    //iters = number of iterations achieved in 1000 milliseconds.

    优化JavaScript

    查找表

    高开销的计算可以预先进行,并将值存在一个查找表(lookup table)中,使用时给出简单的整形下标(index)就可以取出表中的值。那么,只要查找表访问的代价比从头计算的代价低,你的应用程序就能因此获得更好的性能。比如说,JavaScript的三角函数就可以得用查找表加速。

    位操作、整数和二进制数

    在JavaScript中,所有数都以浮点数形式表示。和C++,Java等语言不同,JavaScript语言中无法显示声明int和float类型。虽然JavaScript中单个数值类型帮助程序员避免了许多数值类型错误,但毕竟整数更快,CPU更容易处理。

    仔细阅读ECMAScript标准会发现JavaScript有几个内部操作可以处理整数:

    ToInteger:转为整数

    ToInt32:转为有符号32位整数

    ToUint32:转为无符号32位整数

    ToUint16:转为号16位整数

    这些操作是不能直接使用,而是在执行位操作时自动被调用,使得数字被预先转为合适的整形。虽然这些操作看起来和Web编程不相关,但实际上它们可以用于优化。

    循环展开:麻烦的真相

    任何编程语言中的循环都会增加额外的开销。循环通常要维护一个计数器和/或检查结束条件,这两者都要花费时间。

    移除循环开销将提供一些性能提升。一个典型的JavaScript循环如下:

    for(var i = 0; i < 8; i++){
    	/*** do something here ***/
    }

    如果替换成下面代码,你可以完全除去循环开销:

    /*** do something here ***/
    /*** do something here ***/
    /*** do something here ***/
    /*** do something here ***/
    /*** do something here ***/
    /*** do something here ***/
    /*** do something here ***/
    /*** do something here ***/

    不过,对于8次的迭代的循环,性能的提升不大。假设循环体是一个简单语句(如X++),循环展开可能会快300%,但只是在毫秒级的;3毫秒比1毫秒不会有很大的差别。如果循环体花费时间较长,那可能是0.100 003秒和0.100 001秒的差别,也不太值得优化。

    有两个因素决定了循环展开是否会带来可以观的好处:

    • 循环迭代的次数。事实上,需要许多(比如上千)个迭代才能带明显的区别。
    • 循环体开销和循环开销的比例。如果前都比后者的比例越大,性能提升越少。

    要完全展开成千上百的迭代并不现实。现实的解决方案是使用达夫设备经典算法的变种,部分展开循环。如比,1 000次迭代的循环可以分成125个展开8次迭代。

    //Credit: from Jeff Greenberg's site via an anonymous donor.
    var testVal = 0;
    var n = literations % 8;
    while (n--){
    	testVal++;
    }
    
    n = parseInt(iteratins / 8);
    while (n--){
    	testVal++;
    	testVal++;
    	testVal++;
    	testVal++;
    	testVal++;
    	testVal++;
    	testVal++;
    	testVal++;
    }

    第一个while循环处理了不能被8整除的部分迭代。比如1 004迭代需要1个4次(1 004%8)普通迭代的循环,然后跟着125个(parseInt(1 004/8))展开的8次迭代。下面是一个稍稍改进的版本:

    var testVal = 0;
    var n = iterations >> 3;//Same as:parseInt(iterations /8).
    while(n--){
    	testVal++;
    	testVal++;
    	testVal++;
    	testVal++;
    	testVal++;
    	testVal++;
    	testVal++;
    	testVal++;
    }
    n = iterations - testVal;//testVal has kept a tally, so do the remainder here.
    while(n--){
    	testVal++;
    }

    对于一个循环体很少的10 000次循环的迭代,这会得到很大的性能提升。

    jQuery优化篇

    jQuery和DOM交互

    jQuery是一个被广泛使用的JavaScript库,它能用简洁方便灵活的方式来访问和操作DOM元素,还可以减轻跨浏览器问题,使得你可以集中于核心应用开发而不是浏览器兼容问题。便如,下面的代码返回一个jQuery对象(一种数组)包含所有具有”big” CSS类的图像元素:

    var $images = jQuery('img.big');

    有一点要注意的是:一个看似简单无害的jQuery语句会在幕后做很多工作。如果只偶尔访问少量元素,还没有太大关系。不过,如果要连续访问许多元素,就会严重地影响性能。

    优化CSS格式变化

    用DHTML创建JavaScript图形的一个基本操作就是快速操作DOM元素的CSS样式属性。在jQuery中,你可以这么来做:

    $('#element1').css('color','#ccc');

    这条语句分开做了这么些事:

    • 调用jQuery并让它在DOM中搜索一个id为element1的元素。除了搜索本身之外,还涉及进行正则表达式测试来决定需要搜索的类型。
    • 返回找到的元素列表,一个特殊的jQuery数组对象
    • 再用jQuery的css()函数。这会进行不同的检测,如决定是读或写,是否传入一个字符串参数、对象或者更多,最后更新数组元素样式本身。

    连续进行此类工作会很慢的,不管jQuery有多么的高效:

    $('#element1').css('color','red');
    $('#element1').css('color','blue');
    $('#element1').css('color','pink');
    $('#element1').css('color','black');

    因为这里每行进行一次id为element1元素的搜索,这样很没有效率。一个更快的方法是指定jQuery应该搜索的范围。jQuery默认是从document根或DOM层次的最上层开始搜索。而在许多情况下,是没有必要的。如果指定一个范围,会减少jQuery的搜索工作是,更快的返回结果。别一方面,一旦元素被找到,你不应该再重新搜索它们。我们可以将搜索结果存起来:

    var $elem = $('#element1');    //Cache the serach results
    $elem.css('color','red');
    $elem.css('color','blue');
    $elem.css('color','pink');
    $elem.css('left','100px');

    不过上面的jQuery的css()函数还是做了额外的工作,我们可以直接引用到DOM元素的实际样式对象中:

    //Get the first element ([0]) from the jQuery search results and store
    //a reference to the style object of the element in elemStyle.
    
    var elemStyle = $('#element1')[0].style;
    
    //It is now quicker to manipulate the css styles of the element.
    //jQuery is not being used at all here:
    
    elemStyle.color = 'red';
    elemStyle.color = 'blue';
    elemStyle.color = 'pink';
    elemStyle.left = '100px';

    在页面更复杂、CSS选择器更慢的情况,这种情况的效率会高出很多。

    直接操作无素的属性本身比使用jQuery更快。比如,jQuery.html()方法要比直接使用一个元素的innerHtml对象要慢许多。

    那么这些意味着我们就不用jQuery吗?No,jQuery是不容错过的。在某些环境下慢些是可以理解和接受的。但在速度很关键的代码区内应注意jQuery的使用方式。

    优化DOM插入

    如果你的应用需要加入大量的元素到DOM中,可能会影响性能。DOM是一个复杂的数据结构,应尽量少去修改。但是不修改,是不太可能的。因此我们需要一个高效的方式来插入。

    你可以通过jQuery来插入一个元素到DOM中:

    $("#element1").append('element to insert');

    这对几个元素来说足够了,但当要插入成百上千个元素时,单个插入这些元素会太慢。

    更好的方式是将所有要插入的元素构建为一个大的字符串,然后一次插入。对于每个元素,这防止了jQuery调用和进行各种内部测试的开销。

    var elements = '';
    //First build up a string containing all the elements.
    for(var i = 0; i&lt; 1000; i++){
    	elements += '<p>This is element '+ i + '</p>';
     }
     //They can now be inserted all at once.
     $('#element1').append(elements);

    原创文章,转载请注明出处: 小天地,大世界[ https://www.lyblog.net/]
    文章地址: https://www.lyblog.net/detail/209.html

    上一篇: JS版俄罗斯方块代码详细解说
    下一篇: 织梦网站搬家及常见问题解决汇总

    取消回复

    添加新评论

    电子邮件地址不会被公开。 必填项已用*标注

    已有 2 条评论

    1. 像框墙 像框墙

      呵呵 不错哇,博主换友情连接吗?期待回复

      1. 刘洋 刘洋

        en,可以啊!这个是我的邮箱LiuYang@lyblog.net,请用邮箱联系。

    ABOUT ME

    浏览最多 随机文章 热评文章
    • 通过sharp获取图片文件的原始数据
    • NestJs中表单提交时,验证字段唯一,数据是否已存在的实现方案
    • 文学大赛一等奖:卖米!
    • JavaScript多种文件类型格式互转
    • ThinkPHP 5 中AJAX跨域请求头设置方法
    • ubuntu中创建和设置交换分区
    • Ubuntu 开启mysql远程连接
    • JavaScript中解析URL
    • JavaScript中matches(matchesSelector)的兼容写法
    • Nginx中 Rewrite学习笔记

    分类目录

      • 前端技术
        • Div+Css
        • JavaScript
        • jQuery
        • AngularJs
      • 后端程序
        • node.js
        • PHP
      • 网站管理系统
        • 织梦
        • wordpress
      • 操作系统
        • Windows
        • Linux
      • 随 笔

    最新回复

    相关文章

    代做工资流水公司大连制作车贷流水天津开房贷银行流水开封签证流水样本邯郸办理工资流水账单保定代开车贷流水九江薪资流水单样本岳阳薪资银行流水模板东莞代办背调流水烟台代做工资银行流水菏泽代办薪资银行流水厦门工资流水账单报价黄冈对公银行流水样本三亚代办贷款银行流水成都企业对私流水查询许昌车贷流水代开蚌埠代做车贷工资流水深圳打公司流水信阳工资代付流水办理绵阳工资证明代做厦门办工资代付流水宁德薪资流水单费用宜昌企业贷流水模板沧州工资流水账单费用石家庄自存银行流水样本郑州工作收入证明多少钱西安工资证明公司天津办房贷流水沈阳流水费用南通转账银行流水代做湘潭离职证明办理香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声卫健委通报少年有偿捐血浆16次猝死汪小菲曝离婚始末何赛飞追着代拍打雅江山火三名扑火人员牺牲系谣言男子被猫抓伤后确诊“猫抓病”周杰伦一审败诉网易中国拥有亿元资产的家庭达13.3万户315晚会后胖东来又人满为患了高校汽车撞人致3死16伤 司机系学生张家界的山上“长”满了韩国人?张立群任西安交通大学校长手机成瘾是影响睡眠质量重要因素网友洛杉矶偶遇贾玲“重生之我在北大当嫡校长”单亲妈妈陷入热恋 14岁儿子报警倪萍分享减重40斤方法杨倩无缘巴黎奥运考生莫言也上北大硕士复试名单了许家印被限制高消费奥巴马现身唐宁街 黑色着装引猜测专访95后高颜值猪保姆男孩8年未见母亲被告知被遗忘七年后宇文玥被薅头发捞上岸郑州一火锅店爆改成麻辣烫店西双版纳热带植物园回应蜉蝣大爆发沉迷短剧的人就像掉进了杀猪盘当地回应沈阳致3死车祸车主疑毒驾开除党籍5年后 原水城县长再被查凯特王妃现身!外出购物视频曝光初中生遭15人围殴自卫刺伤3人判无罪事业单位女子向同事水杯投不明物质男子被流浪猫绊倒 投喂者赔24万外国人感慨凌晨的中国很安全路边卖淀粉肠阿姨主动出示声明书胖东来员工每周单休无小长假王树国卸任西安交大校长 师生送别小米汽车超级工厂正式揭幕黑马情侣提车了妈妈回应孩子在校撞护栏坠楼校方回应护栏损坏小学生课间坠楼房客欠租失踪 房东直发愁专家建议不必谈骨泥色变老人退休金被冒领16年 金额超20万西藏招商引资投资者子女可当地高考特朗普无法缴纳4.54亿美元罚金浙江一高校内汽车冲撞行人 多人受伤

    代做工资流水公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化