編寫高性能的JavaScript

隨着計算機硬件的不斷升級,開發者愈加以爲Javascript性能優化的好很差對網頁的執行效率影響不明顯,因此一些性能方面的知識被不少開發者忽視。但在某些狀況下,不優化的Javascript代碼必然會影響用戶的體驗。所以,即便在當前硬件性能已經大大提高的時代,在編寫Javascript代碼時,若能遵循Javascript規範和注意一些性能方面的知識,對於提高代碼的可維護性和優化性能將大有好處。那麼,接下來咱們討論幾種可以提升JavaScript性能的方法。javascript

一、js文件加載和執行

(1)將 <script>標籤放到 <body>標籤的底部
(2)能夠合併多個 js文件,減小頁面中 <script>標籤改善性能
(3)使用 defer 屬性,加載後續文檔元素的過程將和 script.js 的加載並行進行,可是 script.js 的執行要在全部元素解析完成以後, DOMContentLoaded 事件觸發以前完成。
(4)使用 async 屬性,加載和渲染後續文檔元素的過程將和 script.js 的加載與執行並行進行
(5)動態加載腳本元素,不管在什麼時候啓動瞎子,文件的下載和執行過程都不會阻塞頁面其它進程

var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'file.js';
document.getElementsByTagName('head')[0].appendChild(script);複製代碼

二、標識符所在的做用域鏈的位置越深

標識符所在的做用域鏈的位置越深,那麼它的標識符解析的性能就越慢。因此一個好的性能提高的經驗法則是:若是某個跨做用域的值在函數中被引用一次以上,那麼就把它存儲到局部變量裏。css

function fun1() {  
// 將全局變量的引用先存儲在一個局部變量中,而後使用這個局部變量代替全局變量,從而提升         
// 性能;否則每次(3次)都要遍歷整個做用域鏈找到
document  var doc = document;   
 var bd = doc.body;  
 var links = doc.getElementsByTagName('a');  
 doc.getElementById('btn').onclick = function(){   
 console.log('btn');  
 }
}複製代碼

三、避免過長原型鏈繼承

方法或屬性在原型鏈中存在的位置越深,搜索它的性能也就越慢,因此要避免N多層原型鏈的寫法。java

四、對象成員嵌套過深

對象的嵌套成員,對象成員嵌套越深,讀取速度也就越慢。因此好的經驗法則是:若是在函數中須要屢次讀取一個對象屬性,最佳作法是將該屬性值保存在局部變量中,避免屢次查找帶來的性能開銷。編程

function f() { 
 // 由於在如下函數中須要3次用到DOM對象屬性,因此先將它存儲在一個局部變量        
 // 中,而後使用這個局部變量代替它進行後續操做,從而提升性能  
var dom = YaHOO.util.Dom;  
if(Dom.hasClass(element,'selected')){   
  Dom.removeClass(elemet,'selected');  
}else{   
  Dom.addClass(elemet,'selected');  
 }
}複製代碼

五、DOM操做

js訪問和操做DOM都會帶來性能損失,可經過如下幾點來減小性能損失:數組

(1)儘量減小 DOM訪問次數;
(2)若是須要屢次訪問某個 DOM節點,請使用局部變量存儲它的引用;
(3)當心處理 HTML集合,由於它實時連繫着底層文檔;咱們能夠把集合的長度緩存到一個變量中,並在迭代中使用它;
(4)下述狀況會發生重排:
  • 添加或刪除可見的DOM元素;
  • 元素位置改變;
  • 元素尺寸改變(包括:外邊距、內邊距、邊框厚度、寬度、高度等屬性);
  • 內容改變(例如:文本改變或圖片被另外一個不一樣尺寸的圖片改變);
  • 頁面渲染器初始化;
  • 瀏覽器窗口尺寸改變
可經過如下方式減小重排:
  • 留意上面會致使重排的操做,儘可能避免;
  • 獲取佈局信息的操做會致使強制渲染隊列重排,應該儘可能避免使用如下獲取佈局信息的操做方法或屬性或者緩存佈局信息,例如:offsetTop,offsetLeft,offsetWidthoffsetHeight,scrollTop,scrollLeft,scrollWidth,scrollHeight,clientTop,clientLeft,clientWidth,clientHeight,getComputedStyle()等;
  • 批量修改樣式,例如使用:

function f() {  
  // 推薦使用如下操做  
  var el1 = document.getElementById('mydiv');  
  el1.style.cssText = 'border:1px;padding:2px;margin:3px';  
  // 不推薦使用如下操做  
  var el2 = document.getElementById('mydiv');  
  el2.style.border = '1px';  
  el2.style.padding = '2px';  
  el2.style.margin = '3px';
}複製代碼
  • 當須要批量修改DOM時,能夠經過如下步驟減小重繪和重排的次數:
    • 使元素脫離文檔流(隱藏元素、拷貝元素)
    • 對其應用多重改變;
    • 把元素帶回文檔中
  • 使用事件委託(事件逐層冒泡並能被父級元素捕獲,使用事件代理,只需給外層元素綁定一個處理器,就能夠處理其子元素上觸發的所用事件),由於給DOM元素綁定事件以及瀏覽器須要跟蹤每一個事件處理器都須要消耗性能。

六、字符串鏈接

str += 'one'+'two';
str= str+'one'+'two';複製代碼
後者方式會比前者少在內存中建立一個臨時字符串,因此性能有相應的提高,因此,因此推薦後者的寫法。

七、直接使用字面量

建立對象和數組推薦使用字面量,由於這不只是性能最優也有助於節省代碼量。瀏覽器

var obj = {   
 name:'tom',    
 age:15,    
 sex:'男'
}複製代碼

八、數組長度緩存

若是須要遍歷數組,應該先緩存數組長度,將數組長度放入局部變量中,避免屢次查詢數組長度。緩存

九、循環比較

JS提供了三種循環:for(;;)、while()、for(in)。在這三種循環中 for(in)的效率最差,由於它須要查詢Hash鍵,所以應儘可能少用for(in)循環,for(;;)、while()循環的性能基本持平。性能優化

十、少用eval

儘可能少使用eval,每次使用eval須要消耗大量時間,這時候使用JS所支持的閉包能夠實現函數模板。bash

十一、字符串轉換

當須要將數字轉換成字符時,採用以下方式:"" + 1。從性能上來看,將數字轉換成字符時,有以下公式:("" +) > String() > .toString() > new String()String()屬於內部函數,因此速度很快。而.toString()要查詢原型中的函數,因此速度遜色一些,new String()須要從新建立一個字符串對象,速度最慢。閉包

十二、浮點數轉換整形

當須要將浮點數轉換成整型時,應該使用Math.floor()或者Math.round()。而不是使用parseInt(),該方法用於將字符串轉換成數字。並且Math是內部對象,因此Math.floor()其實並無多少查詢方法和調用時間,速度是最快的。

以上就是總結的12條 JavaScript高性能編程的一些建議,但願對你有借鑑之處,若是對你有啓發,請點贊鼓勵,若是有疑問或建議,歡迎留言討論。

相關文章
相關標籤/搜索