JavaScript性能優化小知識總結

  一直在學習javascript,也有看過《犀利開發Jquery內核詳解與實踐》,對這本書的評價只有兩個字犀利,多是對javascript理解的還不夠透徹異或是本身太笨,更多的是本身不擅於思考懶得思考以致於裏面說的一些精髓都沒有太深刻的理解。javascript

  鑑於想讓本身有一個提高,進不了一個更加廣闊的天地,總得找一個屬於本身的居所好好生存,因此平時會有意無心的去積累一些使用jQuerry的經常使用知識,特別是對於性能要求這一塊,老是會想是否是有更好的方式來實現。html

  下面是我總結的一些小技巧,僅供參考。(我先會說一個總標題,而後用一小段話來講明這個意思 再最後用一個demo來簡單言明)java

  避免全局查找node

  在一個函數中會用到全局對象存儲爲局部變量來減小全局查找,由於訪問局部變量的速度要比訪問全局變量的速度更快些數組

  function search() {緩存

  //當我要使用當前頁面地址和主機域名app

  alert(window.location.href + window.location.host);dom

  }函數

  //最好的方式是以下這樣  先用一個簡單變量保存起來工具

  function search() {

  var location = window.location;

  alert(location.href + location.host);

  }

  定時器

  若是針對的是不斷運行的代碼,不該該使用setTimeout,而應該是用setInterval,由於setTimeout每一次都會初始化一個定時器,而setInterval只會在開始的時候初始化一個定時器

  var timeoutTimes = 0;

  function timeout() {

  timeoutTimes++;

  if (timeoutTimes < 10) {

  setTimeout(timeout, 10);

  }

  }

  timeout();

  //能夠替換爲:

  var intervalTimes = 0;

  function interval() {

  intervalTimes++;

  if (intervalTimes >= 10) {

  clearInterval(interv);

  }

  }

  var interv = setInterval(interval, 10);

  字符串鏈接

  若是要鏈接多個字符串,應該少使用+=,如

  s+=a;

  s+=b;

  s+=c;

  應該寫成s+=a + b + c;

  而若是是收集字符串,好比屢次對同一個字符串進行+=操做的話,最好使用一個緩存,使用JavaScript數組來收集,最後使用join方法鏈接起來

  var buf = [];

  for (var i = 0; i < 100; i++) {

  buf.push(i.toString());

  }

  var all = buf.join("");

  避免with語句

  和函數相似 ,with語句會建立本身的做用域,所以會增長其中執行的代碼的做用域鏈的長度,因爲額外的做用域鏈的查找,在with語句中執行的代碼確定會比外面執行的代碼要慢,在能不使用with語句的時候儘可能不要使用with語句。

  with (a.b.c.d) {

  property1 = 1;

  property2 = 2;

  }

  //能夠替換爲:

  var obj = a.b.c.d;

  obj.property1 = 1;

  obj.property2 = 2;

  數字轉換成字符串

  般最好用」" + 1來將數字轉換成字符串,雖然看起來比較醜一點,但事實上這個效率是最高的,性能上來講:

  (「」 +) > String() > .toString() > new String()

  浮點數轉換成整型

  不少人喜歡使用parseInt(),其實parseInt()是用於將字符串轉換成數字,而不是浮點數和整型之間的轉換,咱們應該使用Math.floor()或者Math.round()

  各類類型轉換

  var myVar = "3.14159",

  str = "" + myVar, //  to string

  i_int = ~ ~myVar,  //  to integer

  f_float = 1 * myVar,  //  to float

  b_bool = !!myVar,  /*  to boolean - any string with length

  and any number except 0 are true */

  array = [myVar];  //  to array

  若是定義了toString()方法來進行類型轉換的話,推薦顯式調用toString(),由於內部的操做在嘗試全部可能性以後,會嘗試對象的toString()方法嘗試可否轉化爲String,因此直接調用這個方法效率會更高

  多個類型聲明

  在JavaScript中全部變量均可以使用單個var語句來聲明,這樣就是組合在一塊兒的語句,以減小整個腳本的執行時間,就如上面代碼同樣,上面代碼格式也挺規範,讓人一看就明瞭。

  插入迭代器

  如var name=values[i]; i++;前面兩條語句能夠寫成var name=values[i++]

  使用直接量

  var aTest = new Array(); //替換爲

  var aTest = [];

  var aTest = new Object; //替換爲

  var aTest = {};

  var reg = new RegExp(); //替換爲

  var reg = //;

  //若是要建立具備一些特性的通常對象,也可使用字面量,以下:

  var oFruit = new O;

  oFruit.color = "red";

  oFruit.name = "apple";

  //前面的代碼可用對象字面量來改寫成這樣:

  var oFruit = { color: "red", name: "apple" };

  使用DocumentFragment優化屢次append

  一旦須要更新DOM,請考慮使用文檔碎片來構建DOM結構,而後再將其添加到現存的文檔中。

  for (var i = 0; i < 1000; i++) {

  var el = document.createElement('p');

  el.innerHTML = i;

  document.body.appendChild(el);

  }

  //能夠替換爲:

  var frag = document.createDocumentFragment();

  for (var i = 0; i < 1000; i++) {

  var el = document.createElement('p');

  el.innerHTML = i;

  frag.appendChild(el);

  }

  document.body.appendChild(frag);

  使用一次innerHTML賦值代替構建dom元素

  對於大的DOM更改,使用innerHTML要比使用標準的DOM方法建立一樣的DOM結構快得多。

  var frag = document.createDocumentFragment();

  for (var i = 0; i < 1000; i++) {

  var el = document.createElement('p');

  el.innerHTML = i;

  frag.appendChild(el);

  }

  document.body.appendChild(frag);

  //能夠替換爲:

  var html = [];

  for (var i = 0; i < 1000; i++) {

  html.push('<p>' + i + '</p>');

  }

  document.body.innerHTML = html.join('');

  經過模板元素clone,替代createElement

  不少人喜歡在JavaScript中使用document.write來給頁面生成內容。事實上這樣的效率較低,若是須要直接插入HTML,能夠找一個容器元素,好比指定一個div或者span,並設置他們的innerHTML來將本身的HTML代碼插入到頁面中。一般咱們可能會使用字符串直接寫HTML來建立節點,其實這樣作,1沒法保證代碼的有效性2字符串操做效率低,因此應該是用document.createElement()方法,而若是文檔中存在現成的樣板節點,應該是用cloneNode()方法,由於使用createElement()方法以後,你須要設置屢次元素的屬性,使用cloneNode()則能夠減小屬性的設置次數——一樣若是須要建立不少元素,應該先準備一個樣板節點

  var frag = document.createDocumentFragment();

  for (var i = 0; i < 1000; i++) {

  var el = document.createElement('p');

  el.innerHTML = i;

  frag.appendChild(el);

  }

  document.body.appendChild(frag);

  //替換爲:

  var frag = document.createDocumentFragment();

  var pEl = document.getElementsByTagName('p')[0];

  for (var i = 0; i < 1000; i++) {

  var el = pEl.cloneNode(false);

  el.innerHTML = i;

  frag.appendChild(el);

  }

  document.body.appendChild(frag);

  使用firstChild和nextSibling代替childNodes遍歷dom元素

  \

  var nodes = element.childNodes;

  for (var i = 0, l = nodes.length; i < l; i++) {

  var node = nodes[i];

  //……

  }

  //能夠替換爲:

  var node = element.firstChild;

  while (node) {

  //……

  node = node.nextSibling;

  刪除DOM節點

  刪除dom節點以前,必定要刪除註冊在該節點上的事件,不論是用observe方式仍是用attachEvent方式註冊的事件,不然將會產生沒法回收的內存。另外,在removeChild和innerHTML=’’兩者之間,儘可能選擇後者。 由於在sIEve(內存泄露監測工具)中監測的結果是用removeChild沒法有效地釋放dom節點

  使用事件代理

  任何能夠冒泡的事件都不只僅能夠在事件目標上進行處理,目標的任何祖先節點上也能處理,使用這個知識就能夠將事件處理程序附加到更高的地方負責多個目標的事件處理,一樣,對於內容動態增長而且子節點都須要相同的事件處理函數的狀況,能夠把事件註冊提到父節點上,這樣就不須要爲每一個子節點註冊事件監聽了。另外,現有的js庫都採用observe方式來建立事件監聽,其實現上隔離了dom對象和事件處理函數之間的循環引用,因此應該儘可能採用這種方式來建立事件監聽

  重複使用的調用結果,事先保存到局部變量

  //避免屢次取值的調用開銷

  var h1 = element1.clientHeight + num1;

  var h2 = element1.clientHeight + num2;

  //能夠替換爲:

  var eleHeight = element1.clientHeight;

  var h1 = eleHeight + num1;

  var h2 = eleHeight + num2;

  注意NodeList

  最小化訪問NodeList的次數能夠極大的改進腳本的性能

  var images = document.getElementsByTagName('img');

  for (var i = 0, len = images.length; i < len; i++) {

  }

  編寫JavaScript的時候必定要知道什麼時候返回NodeList對象,這樣能夠最小化對它們的訪問

  進行了對getElementsByTagName()的調用武漢精神分裂醫院哪一個好

  獲取了元素的childNodes屬性

  獲取了元素的attributes屬性

  訪問了特殊的集合,如document.forms、document.images等等

  要了解了當使用NodeList對象時,合理使用會極大的提高代碼執行速度

  優化循環http://net.3688.tv/whrjyy164571/detail/75270.htm

相關文章
相關標籤/搜索