当前位置: 首页 > news >正文

优化javaScript代码,提高执行效率

今天看完书,总结了一下可以如何优化 JavaScript 。

 

1.合并js文件

为优化性能,可以把多个js文件(css文件也可以)合并成极少数大文件。跟十个5k的js文件相比,合并成一个50k的文件更好。虽然代码总字节数没变,却避免了多个HTTP请求造成的开销。每个请求都会在客户端和服务器两边有个建立和消除的过程,导致请求和响应header带来开销,还有服务器端更多的进程和线程资源消耗(可能还有为压缩内容耗费的cpu时间)。除了HTTP请求,并发问题也很重要。默认情况下,在使用持久连接(persistent connections)时,ie和firefox在同一域名内只会同时下载两个资源。这就意味着,在我们等待下载2个js文件的同时,将无法下载图片资源。也就是说,这段时间内用户在页面上看不到图片。

(这个方法有缺点:把所有资源一起打包,将强制用户一次下载完所有资源,造成某些用户不必要的开销)

 

2、减缓代码下载时间:

        Web浏览器下载的是javaScript的源码、其中包含的长变量名、注释、空格和换行等多余字符大大减缓了代码下载的时间。这些字符对于团队编写时十分有效、但在最后工程完成上传到服务器时、应当将它们全部删除。例如:

  1. function showMeTheMoney(){  
  2.         if(!money){  
  3.                 return false;  
  4.         }else{  
  5.                 ...  
  6.         }  
  7. }  
Javascript代码  可优化成:
  1. function showMeTheMoney(){if(!money){return false;}else{...}}  

        这样、优化后就节约了25个字节、倘若是一个大的javaScript工程、将节省出非常大的空间、不但提高了用户的下载速度、也减轻了服务器的压力。相信这样的代码大家见过不少、很多优秀的js插件源码都这么干!

        另外、对于布尔型的值true和false、true都可以用1来代替,而false可以用0来代替。对于true节省了3个字节、而false则节省了4个字节、例如

  1. var bSearch = false;  
  2.         for(var i=0;i<aChoices.length&&!bSearch;i++){  
  3.             if(aChoices[i] == vValue)  
  4.                 bSearch = true ;  
  5.         }  

替换成:

  1. var bSearch = 0;  
  2.         for(var i=0;i<aChoices.length&&!bSearch;i++){  
  3.             if(aChoices[i] == vValue)  
  4.                 bSearch = 1 ;  
  5.         }  

替换了布尔值之后、代码的执行效率、结果都相同、但节省了7个字节。

代码中常常会出现检测某个值是否为有效值的语句、而很多条件非的判断就判断某个变量是否为"undefined"、"null"、或者"false"、例如:

  1. if(myValue != undefined){  
  2.             //...   
  3.         }  
  4.           
  5.         if(myValue !=null){  
  6.             //...   
  7.         }  
  8.           
  9.         if(myValue != false){  
  10.             //...   
  11.         }  

这些虽然都正确、但采用逻辑非操作符"!"也可以有同样的效果、代码如下:

  1. if(!myValue){  
  2.             //...   
  3.         }  

这样的替换也可以节省一部分字节、而且不太影响代码的可读性。类型的代码优化还有将数组定义时的 new Array()直接用"[]"代替、对象定义时的 new Object()用"{}"代替等、例如:

  1. var myArray = new Array();  
  2.         var myArray = [];  
  3.         var myObject = new Object();  
  4.         var myObject = {};  

显然、第二行和第四行的代码较为精简、而且也很容易理解。

另外、在编写代码时往往为了提高可读性、函数名称、变量名称使用了很长的英文单词、同时也大大增加了代码的长度、例如:

  1. function AddThreeVarsTogether(firstVar,secondVar,thirdVar){  
  2.             return (firstVar+secondVar+thirdVar);  
  3.         }  

可优化成:

  1. function A(a,b,c){return (a+b+c);}  

注意:在进行变量名称替换时、必须十分小心、尤其不推荐使用文本编辑器的"查找"、"替换"功能、因为编辑器不能很好地区分变量名称或者其他代码。例如、希望将变量"tion"全部替换成"io"、很可能导致关键字"function"也被破坏。

对于上面说的这些减少代码体积的方法、有一些很实用的小工具可以自动完成类似的工作、例如ECMAScript Cruncher、JSMin、Online JavaScript Compressor等。

 

3、合理声明变量

        减少代码的体积仅仅只能使得用户下载的速度变快、但执行程序的速度并没有改变。要提高代码执行的效果、还得在各方面做调整。

        在浏览器中、JavaScript默认的变量范围是window对象、也就是全局变量。全局变量只有在浏览器关闭才释放。而JavaScript也有局部变量、通常在function中执行完毕就会立即被释放。因此在函数体中要尽可能使用var关键字来声明变量:

  1. function First(){  
  2.             a = "" ;   //直接使用变量   
  3.         }  
  4.         function Second(){  
  5.             alert(a);  
  6.         }  
  7.         First();  
  8.         Second();  
 

        这样、变量"a"就成为了全局变量、直到页面关闭时才会被销毁、浪费了不必要的资源、如果在"a"的前面加上"var"、这样"a"就成为了当前function的局部变量。在执行完First()便立即被销毁。因此、在函数体中、如果不是特别需要的全局变量、都应当使用"var"进行声明、从而节省系统资源。

 

4、使用内置函数缩短编译时间

        只要可能、应当尽量使用JavaScript的内置函数。因为这些内置的属性、方法都是用类似C、C++之类的言语编译过的、运行起来比实时编译的JavaScript快很多。例如计算指数函数、可以自己编写:

  1. <html>  
  2.   <head>  
  3.     <base href="<%=basePath%>">  
  4.     <title>内置函数</title>  
  5.     <meta http-equiv="pragma" content="no-cache">  
  6.     <meta http-equiv="cache-control" content="no-cache">  
  7.     <meta http-equiv="expires" content="0">      
  8.     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  9.     <meta http-equiv="description" content="This is my page">  
  10.     <script type="text/javascript">  
  11.         function myPower(iNum,n){  
  12.             var iResult = iNum ;  
  13.             for(var i=0;i<n;i++)  
  14.                 iResult *= iNum ;  
  15.             return iResult;  
  16.         }  
  17.         var myDate1 = new Date();  
  18.         for(var i=0;i<150000;i++){  
  19.             myPower(7,8);  //自定义方法  
  20.         }  
  21.         var myDate2 = new Date();  
  22.         document.write(myDate2 - myDate1);  
  23.         document.write("<br/>");  
  24.         myDate1 = new Date();  
  25.         for(var i=0;i<150000;i++){  
  26.             Math.pow(7,8);  //采用系统内置方法  
  27.         }  
  28.         myDate2 = new Date();  
  29.         document.write(myDate2 - myDate1);  
  30.     </script>  
  31.   </head>  
  32.   <body>  
  33.   </body>  
  34. </html>  

运行的结果:在IE上使用定义的方法耗时2156ms,使用内置方法为750ms;  在firefox浏览器上,使用定义的方法耗时3625ms,使用内置方法为766ms;

 

5、合理书写if语句

if语句恐怕是所有代码中使用最频繁的、然而很可惜的是它的执行效率并不是很高。在用if语句和多个else语句时、一定要把最有可能的情况放在第一个、然后是可能性第二的、依此类推。例如预计某个数值在0~100之间出现的概率最大、则可以这样安排代码:

  1. if(iNum>0&&iNum <100){  
  2.             alert("在0和100之间");  
  3.         }else if(iNum>99&&iNum<200){  
  4.             alert("在100和200之间");  
  5.         }else if(iNum>199&&iNum<300){  
  6.             alert("在200和300之间");  
  7.         }else{  
  8.             alert("小于等于0或者大于等于300");  
  9.         }  

总是将出现概率最多的情况放在前面、这样就减少了进行多次测试后才能遇到正确条件的情况。当然也要尽可能减少使用else if 语句、例如上面的代码还可以进一步优化成如下代码:

  1. if(iNum>0){  
  2.             if(iNum<100){  
  3.                 alert("在0和100之间");  
  4.             }else{  
  5.                 if(iNum<200){  
  6.                     alert("在100和200之间");  
  7.                 }else{  
  8.                     if(iNum<300){  
  9.                         alert("在200和300之间");  
  10.                     }else{  
  11.                         alert("大于等于300");  
  12.                     }  
  13.                 }  
  14.             }  
  15.         }else{  
  16.             alert("小于等于0");  
  17.         }  

上面的代码看起来比较复杂、但因为考虑了很多代码潜在的判断问题、执行问题、因此执行速度要较前面的代码快。另外、通常当超过两种情况时、最好能够使用switch语句。经常用switch语句代替if语句、可令执行速度快甚至10倍。另外、由于case语句可以使用任何类型、也大大方便switch语句的编写。

 

6、最小化语句数量

脚本找哦个的语句越少执行的时间就越短、而且代码的体积也会相应减少。例如使用var定义变量时可以一次定义多个、代码如下

  1. var iNum = 365;  
  2.         var sColor = "yellow";  
  3.         var aMyNum = [8,7,12,3] ;  
  4.         var oMyDate = new Date();  

上面的多个定义可以用var关键字一次性定义、代码如下:

  1. var iNum = 365, sColor = "yellow" , aMyNum = [8,7,12,3],oMyDate = new Date() ;  

同样在很多迭代运算的时候、也应该尽可能减少代码量、如下两行代码:

  1. var sCar = aCars[i];  
  2.         i++;  

 可优化成:

  1. var sCar = aCars[i++];  
 

7、节约使用DOM

JavaScript对DOM的处理可能是最耗费时间的操作之一。每次JavaScript对DOM的操作都会改变页面的表现、并重新渲染整个页面、从而有明显的时间消耗。比较快捷的方法就是尽可能不在页面进行DOM操作、如下例中为ul添加了10个条目

  1. var oUl = document.getElementById("ulItem");  
  2.         for(var i=0;i<10;i++){  
  3.             var oLi = document.createElement("li");  
  4.             oUl.appendChild(oLi);  
  5.             oLi.appendChild(document.createTextNode("Item "+i));  
  6.         }  

以上代码在循环中调用oUl.appendChild(oLi)、每次执行这条语句后、浏览器就会重新渲染页面、其次给列表添加文本节点oLi.appendChild(document.createTextNode("Item "+i))、这也会造成页面被重新渲染。因此每次运行都会造成两次重新渲染页面、共20次。

通常应当尽可能减少DOM的操作、将列表项目在添加文本节点之后在添加、并合理地使用createDocumentFragment()、代码如下:

  1. var oUl = document.getElementById("ulItem");  
  2.         var oTemp = document.createDocumentFragment();  
  3.         for(var i=0;i<10;i++){  
  4.             var oLi = document.createElement("li");  
  5.             oLi.appendChild(document.createTextNode("Item "+i));  
  6.             oTemp.appendChild(oLi);  
  7.         }  
  8.         oUl.appendChild(oTemp);  


本文转自ChokCoco博客园博客,原文链接: http://www.cnblogs.com/coco1s/p/3581222.html

相关文章:

  • 小型企业Exchange server 2010高可用性方案要注意咯!
  • CentOS6.8 搭建SVN并用钩子自动实现同步到web目录
  • python3 文本变图片
  • SCCM2007操作系统部署出现0xC0000005错误的解决!
  • 接口类 和 抽象类
  • .NET命名规范和开发约定
  • Nginx安装、默认虚拟主机、Nginx用户认证、Nginx域名重定向
  • Mysql性能
  • 【转】self.myOutlet=nil、viewDidUnload、dealloc的本质剖析
  • Find Blank Cell in Excel
  • 浮动元素引起的问题和解决办法?
  • 使用 pod install 还是 pod update ?
  • SylixOS中APIC HPET定时器字符驱动实现
  • 如何在windows上调试安卓机谷歌浏览器上的页面
  • django-权限管理
  • JavaScript-如何实现克隆(clone)函数
  • 《微软的软件测试之道》成书始末、出版宣告、补充致谢名单及相关信息
  • 「前端」从UglifyJSPlugin强制开启css压缩探究webpack插件运行机制
  • Facebook AccountKit 接入的坑点
  • java 多线程基础, 我觉得还是有必要看看的
  • python 学习笔记 - Queue Pipes,进程间通讯
  • Vue2.0 实现互斥
  • vue和cordova项目整合打包,并实现vue调用android的相机的demo
  • 大快搜索数据爬虫技术实例安装教学篇
  • 好的网址,关于.net 4.0 ,vs 2010
  • 驱动程序原理
  • 数据可视化之 Sankey 桑基图的实现
  • 它承受着该等级不该有的简单, leetcode 564 寻找最近的回文数
  • 仓管云——企业云erp功能有哪些?
  • 国内开源镜像站点
  • 如何用纯 CSS 创作一个货车 loader
  • #我与Java虚拟机的故事#连载04:一本让自己没面子的书
  • (10)STL算法之搜索(二) 二分查找
  • (TipsTricks)用客户端模板精简JavaScript代码
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (附源码)ssm教师工作量核算统计系统 毕业设计 162307
  • (附源码)基于SpringBoot和Vue的厨到家服务平台的设计与实现 毕业设计 063133
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (一)SpringBoot3---尚硅谷总结
  • ****** 二十三 ******、软设笔记【数据库】-数据操作-常用关系操作、关系运算
  • .bashrc在哪里,alias妙用
  • .NET delegate 委托 、 Event 事件
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
  • .NET 设计模式—适配器模式(Adapter Pattern)
  • .NET 使用 ILMerge 合并多个程序集,避免引入额外的依赖
  • .NET版Word处理控件Aspose.words功能演示:在ASP.NET MVC中创建MS Word编辑器
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境
  • .NET学习教程二——.net基础定义+VS常用设置
  • /etc/fstab和/etc/mtab的区别
  • ??在JSP中,java和JavaScript如何交互?
  • @html.ActionLink的几种参数格式
  • @NestedConfigurationProperty 注解用法
  • [ C++ ] STL---仿函数与priority_queue
  • []sim300 GPRS数据收发程序
  • [1181]linux两台服务器之间传输文件和文件夹