Javascript代码优化

来源:互联网 发布:软件系统开发合同 编辑:程序博客网 时间:2024/05/18 14:12

原文 https://developers.google.com/speed/articles/optimizing-javascript

客户端的javascript可以使你的app更加灵活与动态变化,但是浏览器解释代码时,可以引入低效率,而且各个浏览器的区别也很大。如下我们将讨论一些优化javascript代码的方法。

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?';

Working with strings

字符串的连结能够引起IE67垃圾回收的性能问题。尽管在IE8中,这个问题已经被解决了,甚至比其他浏览器更加高效,譬如chrome。但是有很多用户仍然在使用IE6,这个问题应该注意。

取代连结,采用join
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();

同样,通过条件或者循环方式以连结的方式建立string是非常低效的。错误的方式如下

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('');

Buildingstrings with portions coming from helper functions

以传stringbulder方式建立string,注意的是避免临时string的产生。例如,假设buildMenuItemHtml_ 能够把变量转化为string。不好的代码如:

var strBuilder = [];for (var i = 0, length = menuItems.length; i < length; i++) {  strBuilder.push(this.buildMenuItemHtml_(menuItems[i]));}var menuHtml = strBuilder.join();

良好的代码为:

var strBuilder= [];for(var i = 0, length = menuItems.length; i < length; i++) {  this.buildMenuItem_(menuItems[i],strBuilder);}varmenuHtml = strBuilder.join();

Definingclass methods

如下code的效率很低,每当baz.Bar的实例a被构造,foo的函数以及闭包随之产生
baz.Bar = function() {  // constructor body  this.foo = function() {  // method body  };}

更好的方法为:

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

Initializinginstance variables

把变量的声明以及初始化放到实例的prototype里,以此避免当构造函数被调用时,变量每次都被初始化

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

采用如下的code

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

Avoidingpitfalls with closures

闭包的缺点如下:

·        They are the most common source of memory leaks.

·        Creating a closure is significantly slower then creating aninner function without a closure, and much slower than reusing a staticfunction. For example:

function setupAlertTimeout() {  varmsg = 'Message to alert';  window.setTimeout(function(){ alert(msg); }, 100);}

效率低于

function setupAlertTimeout() {  window.setTimeout(function(){    varmsg = 'Message to alert';    alert(msg);  },100);}

效率低于

function alertMsg() {  varmsg = 'Message to alert';  alert(msg);}functionsetupAlertTimeout() {  window.setTimeout(alertMsg,100);}

var a = 'a';functioncreateFunctionWithClosure() {  varb = 'b';  returnfunction () {    varc = 'c';    a;    b;    c;  };}varf = createFunctionWithClosure();f();

f被调用了,ab慢,他们都比c慢。

Avoiding with



原创粉丝点击