1. 程式人生 > >從virtualDOM說開去

從virtualDOM說開去

我們知道,前端開發的最佳實踐意義包括效能優化,

前端的效能優化就包括儘可能的減少DOM操作

1.效能

    1.1注意作用域

                避免全域性查詢
完全用 let 代替 var (避免變數宣告提升) 

const 代替 不可變變數

避免 with 語句

O(1) 常數  不管有多少值,執行的時間都是恆定的。一般表示簡單值和儲存在變數中的值
O(log n) 對數  總的執行時間和值的數量相關,但是要完成演算法並不一定要獲取每個值。例如:二分查詢
O(n) 線性  總執行時間和值的數量直接相關。例如:遍歷某個陣列中的所有元素

O(n 2 ) 平方  總執行時間和值的數量有關,每個值至少要獲取n次。例如:插入排序

一旦多次用到物件屬性,應該將其儲存在區域性變數中。第一次訪問該值會是 O(n),然而後續的訪問
都會是 O(1),就會節省很多。例如,之前的程式碼可以如下重寫:
var url = window.location.href;

var query = url.substring(url.indexOf("?"));

避免雙重解釋
當 JavaScript 程式碼想解析 JavaScript 的時候就會存在雙重解釋懲罰。當使用 eval() 函式或者是
Function 建構函式以及使用 setTimeout() 傳一個字串引數時都會發生這種情況。下面有一些例子:
//某些程式碼求值——避免!!
eval("alert('Hello world!')");
//建立新函式——避免!!
var sayHi = new Function("alert('Hello world!')");
//設定超時——避免!!
setTimeout("alert('Hello world!')", 500);
在以上這些例子中,都要解析包含了 JavaScript 程式碼的字串。這個操作是不能在初始的解析過程
中完成的,因為程式碼是包含在字串中的,也就是說在 JavaScript 程式碼執行的同時必須新啟動一個解
析器來解析新的程式碼。例項化一個新的解析器有不容忽視的開銷,所以這種程式碼要比直接解析慢得多。
對於這幾個例子都有另外的辦法。只有極少的情況下 eval() 是絕對必須的,所以儘可能避免使用。

在這個例子中,程式碼其實可以直接內嵌在原始碼中

2 最小化現場更新

在這個例子中只有一次現場更新,它發生在所有專案都建立好之後。文件片段用作一個臨時的佔位
符,放置新建立的專案。然後使用 appendChild() 將所有專案新增到列表中。記住,當給 appendChild()
傳入文件片段時,只有片段中的子節點被新增到目標,片段本身不會被新增的。
一旦需要更新 DOM,請考慮使用文件片段來構建 DOM 結構,然後再將其新增到現存的文件中。
2. 使用  innerHTML
var images = document.getElementsByTagName("img"),
image,
i, len;
for (i=0, len=images.length; i < len; i++){
image = images[i];
//處理
}
這段程式碼添加了 image 變數,儲存了當前的影象。這之後,在迴圈內就沒有理由再訪問 images 的
HTMLCollection 了 。
編寫 JavaScript 的時候,一定要知道何時返回 HTMLCollection 物件,這樣你就可以最小化對他們
的訪問。發生以下情況時會返回 HTMLCollection 物件:
  進行了對 getElementsByTagName() 的呼叫;
  獲取了元素的  childNodes 屬性;
  獲取了元素的  attributes 屬性;
  訪問了特殊的集合,如 document.forms 、 document.images 等