Cách hiệu quả nhất để tạo các phần tử HTML bằng jQuery là gì?


425

Gần đây tôi đã thực hiện rất nhiều cửa sổ bật lên phương thức và những gì không, tôi đã sử dụng jQuery. Phương pháp mà tôi đã sử dụng để tạo các thành phần mới trên trang đã được áp dụng rất nhiều dọc theo dòng:

$("<div></div>");

Tuy nhiên, tôi có cảm giác rằng đây không phải là phương pháp tốt nhất hoặc hiệu quả nhất để làm việc này. Cách tốt nhất để tạo các phần tử trong jQuery từ góc độ hiệu năng là gì?

Câu trả lời này có điểm chuẩn cho các gợi ý dưới đây.


1
Thử nghiệm với loại bỏ phong cách quá và xem nếu điều đó tăng tốc mọi thứ. Tôi tìm thấy ứng dụng CSS và cập nhật những thứ chậm nhất trên các trang lớn đối với tôi.
CVertex

3
Cảnh giác với việc tối ưu hóa sớm - nếu bạn không làm điều này cho hàng trăm thành phần DOM cùng một lúc hoặc sử dụng các trình duyệt RẤT cũ, thì có lẽ bạn sẽ không nhận thấy bất kỳ sự khác biệt nào trong hiệu suất của trình duyệt.
Blazemonger

1
@Blazemonger Không cần nhiều đến mức tôi cần một phương pháp tạo các phần tử DOM hiệu quả hơn, nhưng tình huống mà tôi gặp phải khiến tôi suy ngẫm về các lựa chọn thay thế và hiệu quả của chúng.
Darko Z

2
jQuery là một thư viện - hầu như bạn sẽ luôn phải chịu chi phí hiệu năng cao vì lý do này: nó giống như nói chuyện với ai đó thông qua một trình thông dịch. Trừ khi bạn muốn sử dụng JavaScript thô, hãy tận dụng việc viết $ ('<div>') nhanh như thế nào và chấp nhận cú đánh hiệu suất.
Daniel Bullis

1
jsben.ch/#/bgvCV <= điểm chuẩn này sẽ trả lời câu hỏi của bạn
EscapeNetscape 7/11/2016

Câu trả lời:


307

Tôi sử dụng $(document.createElement('div')); Điểm chuẩn cho thấy kỹ thuật này là nhanh nhất. Tôi suy đoán điều này là do jQuery không phải xác định nó là một phần tử và tự tạo phần tử đó.

Bạn thực sự nên chạy điểm chuẩn với các công cụ Javascript khác nhau và cân nhắc đối tượng của bạn với kết quả. Đưa ra quyết định từ đó.


16
jQuery "nối" nó vào DOM? Ở đâu? Điều này không có ý nghĩa nhiều với tôi - div sẽ đi đâu?
strager

28
một div được tạo trong jquery phải được thêm vào giống như trong javascript. $ ('<div>') tự nó không được gắn vào DOM cho đến khi bạn nối () nó vào một cái gì đó.
Owen

6
@David - rõ ràng là bạn đúng. Tôi sẽ lưu ý rằng tôi đã thêm nhận xét khoảng 2 năm trước ngay khi tôi bắt đầu học jQuery. Bạn sẽ cần phải làm một appendTo, ... Bởi vì các bình luận rõ ràng là sai, tôi đã xóa chúng.
tvanfosson

16
Tham chiếu điểm chuẩn là tuyệt vời, nhưng điều này cũng đang thử nghiệm việc tạo ra hàng chục ngàn yếu tố. Khi nào bạn sẽ phải đối phó với nhiều yếu tố đó trong một tình huống điển hình? Rất có thể, bạn có nhiều thứ phải lo lắng hơn là cách tạo một yếu tố. document.createEuity "Ran 39.682 lần trong 0,097 giây", trong khi $ ('<div>') "Ran 12.642 trong 0,068 giây." Tôi muốn nói nếu một cái gì đó có thể chạy hàng ngàn lần trong chưa đầy một giây, bạn sẽ an toàn.
Daniel Bullis

20
Hơn nữa, sử dụng $ (document.createEuity ('div')); Tôi có thể nói là kém hiệu quả hơn vì phải mất nhiều thời gian hơn để viết cho số lượng lợi ích đáng kể mà bạn sẽ nhận được trong trình duyệt nếu bạn chỉ tạo một yếu tố tại một thời điểm ở đây và ở đó. Về mặt kỹ thuật, bản thân jQuery không hiệu quả như một thư viện do chi phí tra cứu và chi phí bạn phải chịu bằng cách sử dụng nó. Nếu ai đó có ý định tiết kiệm hàng nghìn phần nghìn giây bằng cách sử dụng document.createEuity thay vì $ ('<div>'), thì họ không nên sử dụng jQuery:], vì $ ('<div>') là một trong những lý do bạn sử dụng nó!
Daniel Bullis

163

cá nhân tôi muốn đề xuất (để dễ đọc):

$('<div>');

Một số con số về các đề xuất cho đến nay (safari 3.2.1 / mac os x):

var it = 50000;

var start = new Date().getTime();
for (i = 0; i < it; ++i)  {
  // test creation of an element 
  // see below statements
}
var end = new Date().getTime();
alert( end - start );                

var e = $( document.createElement('div') );  // ~300ms
var e = $('<div>');                          // ~3100ms
var e = $('<div></div>');                    // ~3200ms
var e = $('<div/>');                         // ~3500ms              

15
Từ các tài liệu jquery: 'Khi tạo các phần tử đơn, sử dụng thẻ đóng hoặc định dạng XHTML. Ví dụ: để tạo một khoảng thời gian, hãy sử dụng $ ("<span />") hoặc $ ("<span> </ span>") thay vì không có dấu gạch chéo / thẻ đóng. '
tvanfosson

6
@Owen, hành vi đó là một lỗi, không phải là một tính năng. Rác vào, rác ra - thật ra là rác bạn nhận được là chấp nhận được. Tuy nhiên, đừng dựa vào nó giữa các phiên bản jQuery, trừ khi đặc điểm kỹ thuật của hàm thay đổi.
strager

2
Như mong đợi, nhìn thấy các con số tương tự trong Mac OS X Chrome (100ms cho createdEuity () so với phân tích văn bản 500ms) và Mac OS X Firefox (350ms so với 1000ms). Cảm ơn đã viết lên vòng kiểm tra.
Annika Backstrom

3
@tvanfosson Điều này đã thay đổi rõ ràng, trong các tài liệu hiện tại có ghi: "Khi tham số có một thẻ duy nhất (với thẻ đóng tùy chọn hoặc đóng nhanh) - $ (" <img /> ") hoặc $ (" <img> " ), $ ("<a> </a>") hoặc $ ("<a>") - jQuery tạo thành phần bằng cách sử dụng hàm JavaScript createdEuity () gốc. "
metatron

3
@MarcS / 10 Không có hành vi phạm tội. Nó vẫn ở đây: http://api.jquery.com/jQuery/#jQuery2 . Các tài liệu đề cập đến thẻ đóng tùy chọn hoặc đóng nhanh
metatron

155

Câu hỏi:

Cách hiệu quả nhất để tạo các phần tử HTML bằng jQuery là gì?

Câu trả lời:

jQuerysau đó tôi nghĩ nên sử dụng phương pháp (sạch) này (bạn đang sử dụng)

$('<div/>', {
    'id':'myDiv',
    'class':'myClass',
    'text':'Text Only',
}).on('click', function(){
    alert(this.id); // myDiv
}).appendTo('body');

BẢN GIỚI THIỆU.

Bằng cách này, bạn thậm chí có thể sử dụng trình xử lý sự kiện cho phần tử cụ thể như

$('<div/>', {
    'id':'myDiv',
    'class':'myClass',
    'style':'cursor:pointer;font-weight:bold;',
    'html':'<span>For HTML</span>',
    'click':function(){ alert(this.id) },
    'mouseenter':function(){ $(this).css('color', 'red'); },
    'mouseleave':function(){ $(this).css('color', 'black'); }
}).appendTo('body');

BẢN GIỚI THIỆU.

Nhưng khi bạn đang xử lý nhiều yếu tố động, bạn nên tránh thêm sự kiện handlersvào yếu tố cụ thể, thay vào đó, bạn nên sử dụng một trình xử lý sự kiện được ủy nhiệm, như

$(document).on('click', '.myClass', function(){
    alert(this.innerHTML);
});

var i=1;
for(;i<=200;i++){
    $('<div/>', {
        'class':'myClass',
        'html':'<span>Element'+i+'</span>'
    }).appendTo('body');
}

BẢN GIỚI THIỆU.

Vì vậy, nếu bạn tạo và nối thêm hàng trăm phần tử với cùng một lớp, tức là ( myClass) thì sẽ sử dụng ít bộ nhớ hơn để xử lý sự kiện, bởi vì chỉ có một trình xử lý sẽ ở đó để thực hiện công việc cho tất cả các phần tử được chèn động.

Cập nhật: Vì chúng ta có thể sử dụng phương pháp sau để tạo phần tử động

$('<input/>', {
    'type': 'Text',
    'value':'Some Text',
    'size': '30'
}).appendTo("body");

Nhưng sizethuộc tính không thể được đặt bằng cách sử dụng phương pháp này bằng cách sử dụng jQuery-1.8.0hoặc sau này và đây là một báo cáo lỗi cũ , hãy xem ví dụ này bằng cách sử dụng thuộc tính jQuery-1.7.2đó cho thấy sizethuộc tính đó được đặt thành 30sử dụng ví dụ trên nhưng sử dụng cùng một cách tiếp cận chúng ta không thể đặt sizethuộc tính bằng cách sử dụng jQuery-1.8.3, ở đây là một fiddle không làm việc . Vì vậy, để đặt sizethuộc tính, chúng ta có thể sử dụng phương pháp sau

$('<input/>', {
    'type': 'Text',
    'value':'Some Text',
    attr: { size: "30" }
}).appendTo("body");

Hoặc cái này

$('<input/>', {
    'type': 'Text',
    'value':'Some Text',
    prop: { size: "30" }
}).appendTo("body");

Chúng tôi có thể vượt qua attr/propnhư một đối tượng con nhưng nó hoạt động trong jQuery-1.8.0 and latercác phiên bản kiểm tra ví dụ này nhưng nó sẽ không làm việc trong jQuery-1.7.2 or earlier(không được thử nghiệm trong tất cả các phiên bản trước).

BTW, lấy từ jQuerybáo cáo lỗi

Có một số giải pháp. Đầu tiên là hoàn toàn không sử dụng nó, vì nó không giúp bạn tiết kiệm bất kỳ dung lượng nào và điều này giúp cải thiện sự rõ ràng của mã:

Họ khuyên nên sử dụng phương pháp tiếp cận sau (cũng hoạt động trong các phương pháp trước đó , đã thử nghiệm 1.6.4)

$('<input/>')
.attr( { type:'text', size:50, autofocus:1 } )
.val("Some text").appendTo("body");

Vì vậy, tốt hơn là sử dụng phương pháp này, IMO. Bản cập nhật này được thực hiện sau khi tôi đọc / tìm thấy câu trả lời này và trong câu trả lời này cho thấy rằng nếu bạn sử dụng 'Size'(capital S)thay vì 'size'thì nó sẽ hoạt động tốt , ngay cả trongversion-2.0.2

$('<input>', {
    'type' : 'text',
    'Size' : '50', // size won't work
    'autofocus' : 'true'
}).appendTo('body');

Cũng đọc về prop , bởi vì có một sự khác biệt Attributes vs. Properties, nó thay đổi qua các phiên bản.


Loại sintax này là $ ('<div />', {.........}), tôi đã tìm nó và tôi đã tìm thấy một số tương tự bằng cách sử dụng $ ('<div>). Attr ( {......})?
Rafael Ruiz Tabares

@RafaelRuizTabares, trong $('<div>', {...})bạn đang truyền một đối tượng chứa tất cả các thuộc tính và trong $('<div>').attr({...})bạn đang tạo một phần tử không có thuộc tính nào ngoài việc đặt thuộc tính bằng attr()phương thức sau.
Alpha

@TheAlpha tôi có thể tìm thông tin về những gì tôi có thể viết bên trong {}? Bởi vì tôi thấy chúng là các thuộc tính và sự kiện nhưng đối với <div> bạn cũng sử dụng html. Cảm ơn!
Rafael Ruiz Tabares

Tìm kiếm jQuery.comtrang web có thể hữu ích @RafaelRuizTabares hoặc google nó :-)
Alpha

2
Đây là cách dễ đọc nhất! Có lẽ không phải là cách nhanh chóng nhưng chắc chắn ít lỗi hơn khi thêm chuỗi. Cảm ơn @TheAlpha
Ares

37

Thực tế, nếu bạn đang làm $('<div>'), jQuery cũng sẽ sử dụng document.createElement().

(Chỉ cần nhìn vào dòng 117 ).

Có một số chi phí gọi hàm, nhưng trừ khi hiệu suất là quan trọng (bạn đang tạo ra hàng trăm [nghìn] phần tử), không có nhiều lý do để trở lại DOM đơn giản .

Chỉ cần tạo các yếu tố cho một trang web mới có lẽ là trường hợp tốt nhất bạn sẽ tuân thủ cách làm việc của jQuery .


20

Nếu bạn có nhiều nội dung HTML (không chỉ là một div), bạn có thể xem xét xây dựng HTML vào trang trong một thùng chứa ẩn, sau đó cập nhật nội dung đó và hiển thị khi cần. Bằng cách này, một phần lớn đánh dấu của bạn có thể được trình duyệt phân tích trước và tránh bị JavaScript sa lầy khi được gọi. Hi vọng điêu nay co ich!


Cảm ơn vì lời khuyên. Tôi đã sử dụng phương pháp này trước đây, tuy nhiên trong trường hợp cụ thể này, tôi đặc biệt muốn biết về việc tạo các yếu tố.
Darko Z

20

Đây không phải là câu trả lời chính xác cho câu hỏi nhưng tôi vẫn muốn chia sẻ điều này ...

Việc sử dụng chỉ document.createElement('div')và bỏ qua JQuery sẽ cải thiện hiệu năng rất nhiều khi bạn muốn tạo ra nhiều yếu tố một cách nhanh chóng và chắp thêm vào DOM.


16

Tôi nghĩ rằng bạn đang sử dụng phương pháp tốt nhất, mặc dù bạn có thể tối ưu hóa nó thành:

 $("<div/>");

11

Bạn không cần hiệu năng thô từ một hoạt động mà bạn sẽ thực hiện cực kỳ không thường xuyên theo quan điểm của CPU.


Phụ thuộc vào tần suất bạn đang làm nó.
Giàu Bradshaw

8
OP đang tạo ra một cửa sổ bật lên phương thức . Thao tác này không được lặp lại hàng ngàn lần mỗi giây. Thay vào đó, nó được lặp lại có thể cứ sau vài giây, tối đa. Sử dụng jQuery(html :: String)phương pháp là hoàn toàn tốt. Trừ khi tình huống là vô cùng bất thường, người ta sẽ khó có thể đạt được hiệu suất nhận thức tốt hơn . Dành năng lượng tối ưu hóa cho các trường hợp có thể sử dụng nó. Ngoài ra, jQuery được tối ưu hóa cho tốc độ theo nhiều cách. Làm những điều lành mạnh với nó, và tin tưởng nhưng xác minh nó là nhanh chóng.
yfeldblum

9

Bạn sẽ phải hiểu rằng tầm quan trọng của hiệu suất tạo phần tử là không liên quan trong bối cảnh sử dụng jQuery ngay từ đầu.

Hãy nhớ rằng, không có mục đích thực sự là tạo ra một yếu tố trừ khi bạn thực sự sẽ sử dụng nó.

Bạn có thể muốn thử nghiệm hiệu năng một cái gì đó như $(document.createElement('div'))so với $('<div>')và nhận được hiệu suất tuyệt vời từ việc sử dụng $(document.createElement('div'))nhưng đó chỉ là một yếu tố chưa có trong DOM.

Tuy nhiên, vào cuối ngày, bạn vẫn muốn sử dụng phần tử này để thử nghiệm thực sự phải bao gồm f.ex. .appendTo ();

Hãy xem, nếu bạn kiểm tra những điều sau đây với nhau:

var e = $(document.createElement('div')).appendTo('#target');
var e = $('<div>').appendTo('#target');
var e = $('<div></div>').appendTo('#target');
var e = $('<div/>').appendTo('#target');

Bạn sẽ nhận thấy kết quả sẽ thay đổi. Đôi khi một cách là thực hiện tốt hơn so với cách khác. Và điều này chỉ là do số lượng tác vụ nền trên máy tính của bạn thay đổi theo thời gian.

Tự kiểm tra tại đây

Vì vậy, vào cuối ngày, bạn muốn chọn cách tạo phần tử nhỏ nhất và dễ đọc nhất. Bằng cách đó, ít nhất, các tệp script của bạn sẽ nhỏ nhất có thể. Có lẽ là một yếu tố quan trọng hơn về điểm hiệu suất so với cách tạo ra một yếu tố trước khi bạn sử dụng nó trong DOM.


Tôi biết điều này đã cũ, nhưng không cần jQuery trong ví dụ đầu tiên:document.getElementById('target).appendChild(document.createElement('div'));
sức mạnh của anh ấy vào


7

Một điểm là nó có thể dễ thực hiện hơn:

$("<div class=foo id=bar style='color:white;bgcolor:blue;font-size:12pt'></div>")

Sau đó, để làm tất cả điều đó với các cuộc gọi jquery.


3

Tôi đang sử dụng jquery.min v2.0.3. Nó tốt hơn cho tôi để sử dụng như sau:

var select = jQuery("#selecter");
jQuery("`<option/>`",{value: someValue, text: someText}).appendTo(select);

như sau:

var select = jQuery("#selecter");
jQuery(document.createElement('option')).prop({value: someValue, text: someText}).appendTo(select);

Thời gian xử lý mã đầu tiên thấp hơn nhiều so với mã thứ hai.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.