2011-10-29 23 views
6

Benchmark so sánh QSA & .forEach vs một NodeIteratorKhi sử dụng NodeIterator

toArray(document.querySelectorAll("div > a.klass")).forEach(function (node) { 
    // do something with node 
}); 

var filter = { 
    acceptNode: function (node) { 
     var condition = node.parentNode.tagName === "DIV" && 
      node.classList.contains("klass") && 
      node.tagName === "A"; 

     return condition ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT 
    } 
} 
// FIREFOX Y U SUCK 
var iter = document.createNodeIterator(document, NodeFilter.SHOW_ELEMENT, filter, false); 
var node; 
while (node = iter.nextNode()) { 
    // do thing with node  
} 

Bây giờ hoặc NodeIterator 's mút hoặc tôi đang làm sai.

Câu hỏi: Khi nào tôi nên sử dụng NodeIterator?

Trong trường hợp bạn không biết, DOM4 chỉ định những gì NodeIterator là.

Trả lời

9

Rất chậm vì nhiều lý do. Rõ ràng nhất là một thực tế là không ai sử dụng nó như vậy khá đơn giản chỉ cần ít thời gian hơn đã được chi tiêu tối ưu hóa nó. Một vấn đề khác là nó được tái tham gia ồ ạt, mỗi nút phải gọi JS và chạy chức năng lọc.

Nếu bạn nhìn vào revision three of the benchmark, bạn sẽ thấy tôi đã thêm lại việc thực hiện những gì mà trình lặp đang thực hiện bằng cách sử dụng getElementsByTagName("*") và sau đó chạy một bộ lọc giống nhau trên đó. Như kết quả cho thấy, nó ồ ạt nhanh hơn. Đi JS -> C++ -> JS chậm.

Lọc toàn bộ các nút trong JS (trường hợp getElementsByTagName) hoặc C++ (trường hợp querySelectorAll) nhanh hơn nhiều so với thực hiện nó bằng cách lặp đi lặp lại vượt qua ranh giới. Ghi chú cũng phù hợp với thông minh: nó phù hợp từ phải sang trái và dựa trên bộ nhớ cache được tính trước (hầu hết các trình duyệt sẽ lặp qua danh sách được lưu trong bộ nhớ cache của tất cả các phần tử với lớp "" klass ", kiểm tra xem đó là một phần tử a và sau đó kiểm tra xem phụ huynh có phải là div) và do đó họ thậm chí sẽ không bận tâm với việc lặp lại toàn bộ tài liệu.

Cho rằng, khi nào sử dụng NodeIterator? Về cơ bản không bao giờ trong JavaScript, ít nhất. Trong các ngôn ngữ như Java (chắc chắn là lý do chính tại sao có một giao diện được gọi là NodeIterator), nó có thể sẽ nhanh như bất kỳ thứ gì khác, khi đó bộ lọc của bạn sẽ có cùng ngôn ngữ với bộ lọc. Ngoài ra, chỉ có một lần khác nó có ý nghĩa là trong các ngôn ngữ mà việc sử dụng bộ nhớ của việc tạo ra một đối tượng Node là lớn hơn nhiều so với các đại diện nội bộ của nút.

Các vấn đề liên quan