JavaScript代码的速度被分成两部分:下载时间和执行速度。

Web浏览器下载的是js源码,因此所有长变量名和注释都回包含在内。这个因素会增加下载时间。1160是一个TCP-IP包中的字节数。最好能将每个javascript文件都保持在1160字节以下以获得最优的下载时间。

由于这个原因,要删除注释、删除制表符和空格、删除所有的换行、将长变量名缩短。 遵循这4条比较困难。因此用外部程序(ECMAScript Cruncher)来帮助我们。

要运行ESC,必使用Windows系统,打开一个控制台窗口,然后使用以下格式的命令:

cscript ESC.wsf -l [0-4] -ow outputfile.js inputfile1.js [inputfile2.js]

第一部分,cscript,是Windows Shell脚本解释程序。文件名ESC.wsf是ESC的程序本身。然后是压缩级别,一个0到4的数值。-ow选项表示下一个参数是优化后输出的文件名。最后,剩下的参数是要进行优化的JavaScript文件,可以有多个文件(多个文件在优化后后会按顺序放到输出文件中)。

0 —— 不改变脚本,要将多个文件拿到单个文件中时用用。

1 —— 删除所有的注释。

2 —— 除等级1外,再删除额外的制表符和空格。

3 —— 除等级2外,再删除换行。

4 —— 除等级3外,再进行变量名替换。

ESC擅长把变量名替换成无意义的名称,它还具有一定的智能,进行私有对象先进性和方法名的替换(由名称前后加上两个下划线表示),所以私有特性和方法依然保持其私有性。

ESC不会更改构造函数名、公用属性和公用方法名,所以无需担心。但要注意的是如果某个JavaScript引用了另一个文件中的构造函数,4级优化会把对构造函数的引用替换成无意义的名称。解决方法是将两个文件合成一个文件,这样就会保持构造函数的名称。

====================================

其他减少字节数的方法还有几个。      1.因为在javascript语言中 true等于1,false等于0。因此,脚本包含的字面变量true都可以用1来替换,而false可以用0来替换。 例如:

var bFound = false; for (var i = 0; i < aTest.length && !bFound; i++) { if (aTest[i] == vTest) {   bFounde = true; } }

var bFound = 0; for (var i = 0; i < aTest.length && !bFound; i++) { if (aTest[i] == vTest) {   bFounde = 1; } }

2.缩短否定检测

if (oTest != undefined) {   //do someting } if (oTest != null) { //do someting } if (oTest != false) {   //do someting }

可以替换成

if (!oTest) { //do something }

3.减少语句数量 var iFive = 5; var sColor = "blue";

可以为

var iFive = 5, sColor = "blue";

var sName = aValues[i]; i++; //可以替换成 var sName = aValues[i++];

◆字符串的使用

在IE6和IE7中因字符串级联导致的主要问题是垃圾回收性能,虽然这些问题在IE8中已经得到解决,但如果你的用户大部分仍然在使用IE或IE7,你就得格外注意这个问题了。看一个例子先:

var veryLongMessage = "This is a long string that due to our strict line length limit of" + maxCharsPerLine + " characters per line must be wrapped. " + percentWhoDislike + "% of engineers dislike this rule. The line length limit is for " + " style purposes, but we don't want it to have a performance impact." + " So the question is how should we do the wrapping?";

可以使用连接代替级联:

var veryLongMessage = ["This is a long string that due to our strict line length limit of", maxCharsPerLine, " characters per line must be wrapped. ", percentWhoDislike, "% of engineers dislike this rule. The line length limit is for ", " style purposes, but we don't want it to have a performance impact.", " So the question is how should we do the wrapping?"].join();

◆与此类似,在条件语句中使用级别也是很低效的,错误的做法:

var fibonacciStr = "First 20 Fibonacci Numbers "; for (var i = 0; i < 20; i++) { fibonacciStr += i + " = " + fibonacci(i) + " "; }

最好的方法是:

var strBuilder = ["First 20 fibonacci numbers:"]; for (var i = 0; i < 20; i++) { strBuilder.push(i, " = ", fibonacci(i)," "); } var fibonacciStr = strBuilder.join("");

◆定义类函数

下面的函数是低效的,因为每次构造baz.Bar的实例时,会创建一个新的函数和闭包:

baz.Bar = function () {

// constructor body this.foo = function () {

// method body }; };

正确的方法是:

baz.Bar = function () {

// constructor body this.foo = function () {

// method body }; }; baz.Bar = function () {

// constructor body }; baz.Bar.prototype.foo = function () {

// method body };

使用这个方法时,无论baz.Bar构造了多少个实例,都只会为foo创建一个函数,而且不会创建闭包。

◆初始化实例变量

使用实例变量值类型初始值初始化实例变量声明,如数值、布尔值、空值、未定义或字符串,这样可以避免每次调用构造器时运行不必要的初始化代码。还是来看一个例子:

foo.Bar = function () { this.prop1_ = 4; this.prop2_ = true; this.prop3_ = []; this.prop4_ = "blah"; };

可以代替为:

foo.Bar = function () { this.prop3_ = []; }; foo.Bar.prototype.prop1_ = 4; foo.Bar.prototype.prop2_ = true; foo.Bar.prototype.prop4_ = "blah";

◆避免使用with

避免在代码中使用with,它会影响到性能,因为它修改了范围链,因此需要花费更多时间到其它范围去查找。

◆尽可能避免使用全局变量和函数. 全局的变量和函数其实等价于 window 对象的属性/方法, 访问速度自然会慢.

var myvar = 0; // 336ms window.myvar = 0; // 2383ms

var myfunc = function(){} // 3515ms window.myfunc = function(){} // 10151ms

◆尽量避免用 new 操作符创建函数. 可能通过 new 创建的函数还需要额外地对函数内容字符串进行解析操作.

function f(){}; // 277ms var f  = function(){} // 3085ms var f = new Function("") // 13275ms

◆尽量避免使用 eval() 执行代码. 原因同 new 创建函数的操作.

var myfunc = function(){} // 3408ms eval("var myfunc = function(){}"); // 9140ms

◆少使用 new 操作符创建数组. 原因同 new 创建函数的操作. 特别在有大量数据时更为明显

a = [1, 2, 3]; // 4360ms a = new Array(1, 2, 3); // 5000ms

◆尽量避免使用 push() 和 pop() 处理数组数据.

a[i] = value; // 1270ms a.push(value); // 3240ms

◆使用对象代替数组存储数据对性能略有影响. 也许是因为 Javascript 的数组是个带有扩展方法和属性的对象, 而不像 VBScript 那样是单纯的数据结构.

a[i] = value; // 1270ms obj[property] = value; // 960ms

◆使用 ++ 代替 x = x+1 和 +=. 事实上 ++ 并不比 + 和 += 快很多, 但是在大量的操作时就会体现出其优势. 而 + 和 += 几乎没有性能差别. 同理对 -- 和 - 以及 -= 适用.

x++; // 378ms x = x+1; // 406ms x += 1; // 406ms

◆使用局部变量缓存对象属性和函数指针 例如在遍历数组时缓存数组长度, 事实上获取 Javascript 的数组长度等于调用一个方法函数(大部分Javascript 引擎是这样实现的). 如果对 HTML DOM 进行操作, 那么优化的效果会非常明显.

for(var i=0;i<arr.length;i++){ ... } // 162ms

var length = arr.length; for(var i=0;i<length;i++){ ... } // 156ms

或者使用局部变量缓存一个外部函数(具体效果视代码复杂度而定). 如果代码块中要多次调用一个外部函数或变量, 那么缓存的效果会非常明显.

function test(){ ... } function run1(){  test(); } function run2(){  var t = test;  t(); }
run1(); // 98ms run2(); // 80ms

转自:http://jiangzhengjun.javaeye.com/

写出高性能的javascript代码相关推荐

  1. code blocks代码性能分析_Julia系列教程13--如果写出高性能的Julia代码

    避免全局变量https://www.zhihu.com/video/1113506985873588224 code generationhttps://www.zhihu.com/video/111 ...

  2. 三周写出高性能的Python代码,这些小技巧你值得一试。

    1一个不上进的 Python 使用者 我是一个有 C 语言背景的开发者.最近转做了 Python,平时用 Python 还算 6,这周在给新员工分享工作之后,有个小孩跑来问我:"哥,你是学 ...

  3. JavaScript进阶:如何写出优雅的JavaScript代码

    目录 一.可维护性代码 二.编码规范-可读性 三.变量和函数命名 四.松散耦合 1.解耦HTML和JavaScript 2.解耦CSS和JavaScript 3.解耦应用程序逻辑和事件处理程序 五.编 ...

  4. 如何写出漂亮的 JavaScript 代码

    原文:https://github.com/ryanmcdermott/clean-code-javascript 说明:本文翻译自 github 上的一个项目,非全文搬运,只取部分精华. 如何提高代 ...

  5. 如何写出高性能代码(四)优化数据访问

      同一份逻辑,不同人的实现的代码性能会出现数量级的差异: 同一份代码,你可能微调几个字符或者某行代码的顺序,就会有数倍的性能提升:同一份代码,也可能在不同处理器上运行也会有几倍的性能差异:十倍程序员 ...

  6. 如何写出高性能代码(二)巧用数据特性

    导语 同一份逻辑,不同人的实现的代码性能会出现数量级的差异: 同一份代码,你可能微调几个字符或者某行代码的顺序,就会有数倍的性能提升:同一份代码,也可能在不同处理器上运行也会有几倍的性能差异:十倍程序 ...

  7. 如何写出高性能代码(一)善用算法和数据结构

    同一份逻辑,不同人的实现的代码性能会出现数量级的差异: 同一份代码,你可能微调几个字符或者某行代码的顺序,就会有数倍的性能提升:同一份代码,也可能在不同处理器上运行也会有几倍的性能差异:十倍程序员不是 ...

  8. 写出更易懂的代码(一)

    今天周日,外面天气不好,舍友出去跟MM约会了,我一个人独自在家,逛逛园子. 发现一篇好文<javascript 杂谈之哪种写法你更喜欢?>,其中有一个代码,是模仿jQuery写法的: 虽然 ...

  9. 如何写出更优雅的代码——编程范式简述

    <如何写出更优雅的代码--编程范式简述>源站链接,阅读体检更佳! 什么是程序? 1976年,瑞士计算机科学家,Algol W,Modula,Oberon 和 Pascal 语言的设计师 N ...

最新文章

  1. 数据库学习之(6)了解数据库触发器
  2. canvas在舞台上点击后图片旋转_View绘制系列(10)Canvas基础变换
  3. boost::signals2模块实现连接类测试
  4. 大学计算机一级计算机应用试题及答案,大学生计算机应用基础试题及答案
  5. 逆水寒服务器维护7.5,逆水寒7.26日维护到什么时候 逆水寒7.26日游戏改动汇总介绍...
  6. android.9背景图变形,Android聊天背景图片变形解决方案
  7. Windows Embedded CE 6.0开发初体验(三)设置Boot-loader
  8. thread local性能 c++_MySQL 5.7 amp; MySQL 8.0 性能对比
  9. w7 mysql不启动_Win7安装mysql5.7服务无法启动没有任何报错信息处理:
  10. 从Slice_Header学习H.264--相关细节之 POC的计算
  11. 【李宏毅2020 ML/DL】P76 Generative Adversarial Network | Unsupervised Conditional Generation
  12. 史上最全python常用英语单词,建议收藏
  13. 揭秘空手套白狼的灰色产业,人性背后的暴利
  14. Dubbo 常见的负载均衡(Load Balance)算法,一起学习一下吧~
  15. 第41课:Checkpoint彻底解密:Checkpoint的运行原理和源码实现彻底详解
  16. JSP实用教程-JSP语法
  17. Visual Stdio 中的error C2001: 常量中有换行符
  18. T3902(TDK)
  19. idea project structure下modules的Language Level总是自动变到5
  20. vb.net 简单的方法模拟三体(有行星)

热门文章

  1. linux制作归档文件目录,在 Linux 中如何归档文件和目录
  2. docxtpl - 页眉页脚-替换图片-预留图片位置
  3. vue.js 依赖收集
  4. How to Do Everything with YouTube
  5. 电话销售找客户难在哪?销售找客户方法
  6. 远心镜头的特点及应用知识
  7. qt 单例模式实际应用 单例模式自定义对话框类
  8. eMule Server发公告对中国人改造客户端,疯狂扫描服务器不满
  9. 二代身份证号码验证器[超简单]
  10. 全球及中国钴行业发展调研及投资前景分析报告2022-2028年