2013-02-19 24 views
5

Có một số câu hỏi hỏi về các đối tượng jQuery trong bộ nhớ đệm nhưng tôi không thể tìm thấy một đối tượng nào hỏi chính xác đối tượng jQuery có thể ở đâu và nên được lưu trong bộ nhớ cache. Tôi có một trang web có một tệp JavaScript duy nhất với một loạt các chức năng như được hiển thị bên dưới.Tôi nên lưu các kết quả bộ nhớ cache của các truy vấn jQuery DOM ở mức nào?

$(document).ready(function() { 

    // do some setup 
}); 

/* function queries the DOM with the same selector multiple times without caching */ 
function myFunctionOne() { 

    $('#name_input').css("border","1px solid #ccc"); 
    $('#name_input').val(someValue);   
} 

/* function uses cached object from a single query */ 
function myFunctionTwo() { 

    var nameInput = $('#name_input') 
    nameInput.css("border","1px solid #ccc"); 
    nameInput.val(someValue); 
    // do some other stuff with cached selector   
} 

Trong myFunctionOne Tôi không hiệu quả truy vấn DOM hai lần trong khi ở myFunctionTwo tôi truy vấn DOM một lần, bộ nhớ cache kết quả trong một biến địa phương, sau đó làm việc với biến đó. Tôi hiểu rằng cách tiếp cận trong myFunctionTwo hiệu quả hơn nhưng tôi không chắc chắn về nơi tôi thực sự nên lưu vào bộ nhớ cache các đối tượng đó. Tại thời điểm tôi đang lưu bộ nhớ đệm đối tượng ở cấp phương thức nhưng tôi tự hỏi liệu tôi có thể thực sự lưu nó ở mức cao hơn và sau đó sử dụng nó trên nhiều hàm. Bằng cách này tôi sẽ chỉ truy vấn DOM một lần và sau đó sử dụng lại kết quả trong tất cả các hàm trong tệp này. Một ví dụ về những gì tôi đang đề xuất được hiển thị dưới đây.

$(document).ready(function() { 

    // do some setup 
    var nameInput = $('#name_input') 
}); 

/* function uses cached query result from .ready function above */ 
function myFunctionOne() { 

    nameInput .css("border","1px solid #ccc"); 
    nameInput .val(someValue);   
} 

/* function uses cached query result from .ready function above */ 
function myFunctionTwo() { 

    nameInput.val(someValue); 
    // do some other stuff with cached selector   
} 

Cách tiếp cận này có hợp lý hoặc có cách nào tốt hơn để thực hiện? Có lẽ bằng cách sử dụng chức năng .ready là một nơi tồi tệ để làm điều này loại thiết lập vì nó sẽ làm chậm tải trang? Có cách nào khác để cache các đối tượng jQuery ở mức đối tượng hay chúng chỉ được lưu trữ ở mức chức năng?

Trả lời

7

Như mọi khi trong những loại câu hỏi, không tối ưu hóa sớm. Trong trường hợp này, nó có nghĩa là không sử dụng bất kỳ bộ nhớ đệm nào cho đến khi bạn nhận thấy các vấn đề về hiệu suất. Nếu khách hàng mục tiêu của bạn sử dụng máy tính hoặc thiết bị di động có độ phân giải thấp, điều này có nghĩa là bạn sẽ muốn tự mình thử nghiệm trên phần cứng có độ phân giải thấp để bạn có thể xác định các vấn đề đó. Tôi sẽ khuyên bạn nên đi cho rõ ràng trước khi cố gắng để cải thiện tốc độ bằng cách thêm bộ nhớ đệm.

Một số điểm thêm:

  • Nếu bạn đang sử dụng một bộ chọn có sử dụng một ID, cần được nhanh chóng vì nó sẽ sử dụng getElementById đằng sau hậu trường, do đó không cần bộ nhớ đệm.
  • Sử dụng chuỗi phương pháp thay vì lưu vào bộ nhớ cache, thao tác này sẽ chỉ sử dụng công cụ chọn một lần
  • Nếu bạn triển khai bộ nhớ đệm, hãy thực hiện trước cục bộ. Caching giữa các phương thức sẽ tốn kém hơn về tính phức tạp của mã hơn là bộ nhớ đệm cục bộ.
  • Sử dụng .ready là tốt. Nó chạy sau khi DOM đã được tải và là nơi chính xác để thực hiện các tác vụ thiết lập.
+1

Tôi đồng ý với quan điểm của bạn rằng điều quan trọng là không tối ưu hóa sớm, và trong trường hợp của tôi không sớm.Tôi thấy các vấn đề về hiệu suất trong IE8 và trong nỗ lực khắc phục điều này, chúng tôi đang xem xét một số các phương pháp hay nhất được đề xuất cho jQuery, một trong số đó là bộ nhớ đệm. Tôi dự định sử dụng bộ đệm ẩn cục bộ ở mức tối thiểu và bộ nhớ đệm giữa các phương thức nếu có thể. Bạn nói, "Caching giữa các phương thức sẽ tốn nhiều hơn về mã phức tạp hơn bộ nhớ đệm cục bộ". Bạn có thể giải thích về điều này, vì điều này có thể giúp trả lời câu hỏi ban đầu của tôi? – user2088756

1

Một cách tiếp cận có thể là để lưu trữ bộ chọn trong $.cache:

$(function(){ 

     var $nameInput = $('#name_input'); 

     $('body').data({ nameInput: $nameInput }); 

}); 

Và sau đó truy cập nó bằng cách sử:

function myFunctionOne() { 

    var $nameInput = $('body').data('nameInput'); 
} 
+0

Điều này không có lợi ích so với chỉ sử dụng biến của riêng bạn (tránh toàn cầu nếu muốn - và cần được mong đợi - với trình bao bọc IIFE). Nhưng nó có chi phí phức tạp và hiệu suất so với việc sử dụng biến của riêng bạn. –

-1

Mã này sẽ làm xáo trộn độc đáo. Bạn có thể thêm bao nhiêu điều khiển như bạn muốn trong _initControls và sử dụng chúng sau này trong suốt khối tập lệnh này. Nếu bạn muốn nó toàn cục cho tất cả các khối tập lệnh, hãy di chuyển hàm _initControls ra khỏi hàm onreadystate của jQuery.

$(function() { 
    "use strict"; 

    var _controls = {}, 
    _init = function() { 
     _initControls(); 
     _updateData("Hello"); 
    }, 
    _initControls = function() {    
     _controls.nameInput = $("#name_input"); 
    }, 
    _updateData = function (value) { 
     var nameInput = _controls.nameInput; 
     nameInput.css("border", "1px solid #ccc"); 
     nameInput.val(value); 
    }; 

    _init(); 
}); 
+0

Tại sao bài đăng này lại được giảm giá? – Ankur

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