2012-05-07 7 views
6

Tôi đã tạo một plugin jQuery để sửa đổi điều hướng của mình. Rất tiếc, tôi phải truy cập và sửa đổi hầu như tất cả các phần tử con như <ul>, <li>, <a> v.v. Những yếu tố này sau đó cần thiết giữa một và bốn lần.Không lưu trữ các yếu tố được chọn/tìm thấy trong hiệu suất tăng biến?

Tôi có nên lưu trữ tất cả trong các biến hay tôi nên truy cập chúng như $('.my-nav').find('li') hoặc $('.my-nav').find('li') khi cần thiết?

Nó có vẻ như lãng phí bộ nhớ có 5 biến cho 25 dòng mã. Nhưng tôi không biết liệu đây có phải là sự cân bằng chấp nhận được cho hiệu suất cao hơn hay không.

Tôi tạo ra một Fiddle để minh họa cho những gì là có nghĩa là: http://jsfiddle.net/Yj35Q/2/

+0

Cảm ơn, tôi đã sửa Fiddle. –

Trả lời

8

thực hành Luôn luôn tốt để cache các nút của bạn. Bạn cũng có thể chuẩn bị cho mình bằng cách sử dụng http://jsperf.com/

Bạn không thực sự cần phải lo lắng về việc cần bao nhiêu không gian lưu trữ trừ khi bạn đang lưu trữ một cây DOM lớn hoặc thứ gì đó. Phần lớn công việc của JS phải làm để xác định vị trí các nút.

EDIT
hoặc thậm chí tốt hơn, bạn có thể tìm thấy một trường hợp thử nghiệm hiện có ai đó đã tạo ra
http://jsperf.com/ns-jq-cached/4

+0

Cảm ơn, nó cho thấy rõ sự khác biệt. –

2

Trong chức năng tương tự, tôi sẽ cache kết quả tìm kiếm DOM trong một biến địa phương vì vậy tôi không bao giờ phải thực hiện tìm kiếm DOM giống nhau nhiều lần trong cùng một chức năng. Đối với hầu hết các chức năng này sẽ không cần thiết, nhưng thật dễ dàng và an toàn để đưa kết quả vào một biến cục bộ chỉ trong khoảng thời gian của hàm vì vậy tôi nghĩ đó là một thói quen tốt. Tôi thường sẽ KHÔNG lưu các nút DOM vào các biến toàn cục đơn giản chỉ vì tôi cố gắng tránh các biến toàn cầu và hiếm khi là một vấn đề hiệu năng để truy xuất nút DOM khi cần cho một hàm cụ thể. Một lý do khác để tránh việc có tham chiếu DOM trong biến toàn cầu là nếu một nút DOM cụ thể bị xóa khỏi DOM và bạn dự định sẽ thu thập rác, nếu có tham chiếu đến biến đó trong biến toàn cầu, nút DOM sẽ không được rác thu thập và có thể dẫn đến rò rỉ bộ nhớ.

Có một số trường hợp tôi liên tục tìm kiếm cùng một nút DOM (như trên bộ hẹn giờ), nơi tôi sẽ lưu nút DOM vào một biến không toàn cầu trong một đóng chức năng và sau đó sử dụng biến đó cục bộ. Nhưng, tôi thấy những trường hợp cần phải hiếm hoi.

+0

+1. Và cho tôi biết bạn nghĩ gì về bộ chọn jQuery tải chậm của tôi. –

+0

Cảm ơn rất nhiều vì câu trả lời của bạn. Như thường lệ, nhiều câu trả lời tôi muốn chấp nhận nhưng tiếc là chỉ có một câu trả lời. fritzfromlondon nhanh hơn một chút. –

+0

@JohnB. - Câu trả lời của fritzfromlondon và câu trả lời của tôi là những câu trả lời khác nhau với các khuyến nghị khác nhau. Tôi nghĩ bạn sẽ bầu cho một người có ý nghĩa hơn với bạn hoặc có vẻ hoàn thiện hơn là cái nào đến trước một phút trước. Tôi không phản đối việc bạn chọn một câu trả lời khác với câu trả lời của tôi, chỉ là tiêu chí của bạn không nên đến trước khi câu trả lời khác. – jfriend00

3

Đó là chắc chắn khôn ngoan để bộ nhớ cache các yếu tố DOM của bạn khi thích hợp, cho dù bạn đang sử dụng jQuery hay không.

Nhưng câu hỏi này khiến tôi nghĩ rằng có lẽ chúng ta nên có một plugin để trợ giúp điều này. Tôi tìm kiếm xung quanh và không thể tìm thấy.

Vì vậy, tôi đã viết rất nhanh. Đó là một lazy loading jQuery selector ...

(function($){ 
    var cachedObjects = new Array(); 

    $.lazy = function(selector) { 
     if (typeof selector != "string" || arguments.length > 1) 
      return $.apply(this, arguments); 

     var o = cachedObjects[selector]; 
     if (o == undefined) 
     { 
      o = $(selector); 
      cachedObjects[selector] = o; 
     } 

     return o; 
    }; 
})(jQuery); 

Bạn muốn sử dụng nó như thế này ...

$.lazy('.my-nav').show(); 

Hãy cho tôi biết nếu tôi đã bỏ qua bất cứ điều gì. Nhưng tôi tin rằng điều này sẽ là tốt để sử dụng bất cứ khi nào các yếu tố bạn chọn là tĩnh và không bao giờ được thêm hoặc xóa tự động.

CẬP NHẬT

Tôi đã thay đổi mã để làm điều này hiệu quả hơn. Và tôi đã thêm một dòng vào return $(selector) khi bộ chọn không phải là một chuỗi. Vì vậy, bộ nhớ đệm sẽ chỉ hoạt động khi bộ chọn là một chuỗi.

CẬP NHẬT # 2

Bây giờ nó sẽ return $.apply(this, arguments) khi bạn không chỉ đơn giản là đi qua một chuỗi, mỗi gợi ý jfriend00 của.

+0

Một ý nghĩ thú vị. Vì vậy, thay vì '$ (selector) .fadeOut()', một cái sử dụng '$ .lazy (selector) .fadeOut()'. Tôi đề nghị bạn chắc chắn rằng selector là một chuỗi và nó có thể hiệu quả hơn khi nó chưa được lưu trữ bởi không phải tìm lại nó trong 'cachedObjects' sau khi bạn đặt nó vào đó. – jfriend00

+0

@ jfriend00 - Ý nghĩ hay. Tôi sẽ thực hiện những thay đổi này tối nay. –

+0

Tôi đề nghị bạn thay đổi 'if (typeof selector! =" String ") trả về $ (selector);' to: 'if (typeof selector! =" String "|| arguments.length> 1) return $ .apply (này, đối số); vì vậy nó hoạt động cho tất cả các đối số jQuery có thể chấp nhận được. – jfriend00