2008-09-22 29 views
21

Tôi có cảm giác xấu về cách chèn số lượng HTML lớn hơn. Cho phép giả định chúng tôi đã nhận:jquery: chèn DOM nhanh nhất?

var html="<table>..<a-lot-of-other-tags />..</table>"

và tôi muốn đưa điều này vào

$("#mydiv")

trước đây tôi đã làm một cái gì đó giống như

var html_obj = $(html); $("#mydiv").append(html_obj);

Is it correct th tại jQuery đang phân tích cú pháp html để tạo đối tượng DOM? Vâng đây là những gì tôi đọc ở đâu đó (UPDATE: tôi muốn nói rằng tôi đã đọc, jQuery phân tích html để tạo ra cây DOM toàn bằng tay - ngay vô nghĩa của nó ?! ), vì vậy tôi đã thay đổi mã của tôi:

$("#mydiv").attr("innerHTML", $("#mydiv").attr("innerHTML") + html);

Cảm thấy nhanh hơn, phải không? Và có đúng là điều này tương đương với:

document.getElementById("mydiv").innerHTML += html? hoặc là jquery làm một số công cụ đắt tiền bổ sung trong nền?

Rất thích học các giải pháp thay thế.

Trả lời

21

innerHTML rất nhanh và trong nhiều trường hợp, bạn sẽ nhận được kết quả tốt nhất chỉ cần thiết lập điều đó (tôi sẽ chỉ sử dụng phụ thêm).

Tuy nhiên, nếu có nhiều trong "mydiv" thì bạn buộc trình duyệt phân tích cú pháp và hiển thị lại tất cả nội dung đó (mọi thứ đã có trước đó, cộng với tất cả nội dung mới của bạn). Bạn có thể tránh điều này bằng cách thêm một đoạn tài liệu lên "mydiv" thay vì:

var frag = document.createDocumentFragment(); 
frag.innerHTML = html; 
$("#mydiv").append(frag); 

Bằng cách này, chỉ có nội dung mới của bạn bị phân tích cú pháp (không thể tránh khỏi) và nội dung hiện có thì không.

EDIT: xấu của tôi ... Tôi đã phát hiện ra rằng innerHTML không được hỗ trợ tốt trên các đoạn tài liệu. Bạn có thể sử dụng cùng một kỹ thuật với bất kỳ loại nút nào. Ví dụ của bạn, bạn có thể tạo nút bảng gốc và chèn innerHTML vào đó:

var frag = document.createElement('table'); 
frag.innerHTML = tableInnerHtml; 
$("#mydiv").append(frag); 
+1

Điều này làm việc cho tôi, nhưng tôi đã phải sử dụng append(), không appendChild(). Typo, hoặc đã thay đổi tên phương thức? –

+0

Tôi không chắc chắn làm thế nào mà có thể đã bị trượt bởi, nhưng tôi không nghĩ rằng đó là một phương pháp được đổi tên. Tôi sẽ cập nhật bài đăng của mình. – Prestaul

+1

appendChild() là phương thức DOM w3c thực hiện tương tự như append() trong jQuery (xấp xỉ) – xj9

1

Để bắt đầu, hãy viết tập lệnh cho biết phải mất bao lâu để thực hiện nó 100 hoặc 1.000 lần với mỗi phương pháp.

Để đảm bảo lặp lại không được tối ưu hóa một cách nào đó - Tôi không có chuyên gia về công cụ JavaScript - thay đổi html bạn đang chèn mỗi lần, nói '0001' rồi '0002' rồi '0003 'trong một ô nhất định của bảng.

9

Bạn đang cố gắng tránh điều gì? "Một cảm giác xấu" là vô cùng mơ hồ. Nếu bạn đã nghe "DOM chậm" và quyết định "tránh DOM", thì điều này là không thể. Mỗi phương pháp chèn mã vào một trang, bao gồm innerHTML, sẽ dẫn đến các đối tượng DOM được tạo. DOM là biểu diễn của tài liệu trong bộ nhớ của trình duyệt. Bạn muốn đối tượng DOM được tạo.

Lý do mọi người nói "DOM chậm" là do tạo các thành phần với document.createElement(), là giao diện DOM chính thức để tạo thành phần, chậm hơn sử dụng thuộc tính innerHTML không chuẩn trong một số trình duyệt. Điều này không có nghĩa là việc tạo các đối tượng DOM là xấu, đó là cần thiết để tạo các đối tượng DOM, nếu không mã của bạn sẽ không làm gì cả.

-1

Bạn đề cập đến việc quan tâm đến các lựa chọn thay thế. Nếu bạn nhìn vào danh sách của DOM-related jQuery plugins bạn sẽ tìm thấy một số được dành riêng cho lập trình tạo cây DOM. Xem ví dụ SuperFlyDom hoặc DOM Elements Creator; nhưng có những người khác.

+0

chúng sẽ sử dụng các đoạn DOM, phải không? –

2

Câu trả lời về việc sử dụng đoạn DOM là đi đúng hướng. Nếu bạn có một loạt các đối tượng html mà bạn đang liên tục chèn vào DOM thì bạn sẽ thấy một số cải tiến tốc độ bằng cách sử dụng đoạn. bài này John Resig giải thích nó khá tốt: http://ejohn.org/blog/dom-documentfragments/

+0

Anh ta không đề cập rằng anh ta muốn đặt một mảnh cho nhiều hơn một yếu tố. Câu hỏi của anh ta chỉ ra rằng anh ta muốn đặt một mẩu html vào một phần tử. Bên cạnh đó, 'tài liệu fragment' được tạo ra bên trong jQuery ngầm. – galambalazs

32

Hãy thử như sau:

$("#mydiv").append(html); 

Những câu trả lời khác, trong đó có câu trả lời được chấp nhận, là chậm bởi 2-10x: jsperf.

Câu trả lời được chấp nhận không làm việc trong IE 6, 7, và 8 bởi vì bạn không thể thiết lập innerHTML của một yếu tố <table>, do một lỗi trong IE: jsbin.

+1

+1, xây dựng html dưới dạng chuỗi và sử dụng một 'phụ thêm' thay vì xây dựng từng phần tử bằng jquery tăng hiệu suất trong trường hợp của tôi theo thứ tự độ lớn (tạo 280 div, mỗi bảng có một bảng và một vài hàng , mất 12 giây, bây giờ nó xuống còn 1,1).Mặc dù bạn có thể muốn cắt giảm những lời lăng mạ ...;) – falstro

+1

+1 để đăng liên kết jsperf.com khi đó chính xác là những gì cần thiết –

+0

Bài kiểm tra của bạn là không trung thực. Nó tạo ra một mảnh dom mới cho mỗi phần tử. bạn giả sử thêm tất cả các phần tử vào một đoạn dom, sau đó chèn nó vào cây dom. Đây là một thử nghiệm REAL http://jsperf.com/scriptjunkie-premature-7 –

1

Cách nhanh nhất để thêm mục

Cách nhanh nhất để phụ thêm vào cây DOM là để đệm tất cả các append của bạn vào một mảnh DOM duy nhất, sau đó nối các mảnh dom cho dom.

Đây là phương pháp tôi sử dụng trong công cụ trò chơi của mình.

//Returns a new Buffer object 
function Buffer() { 

    //the framgment 
    var domFragment = document.createDocumentFragment(); 

    //Adds a node to the dom fragment 
    function add(node) { 
     domFragment.appendChild(node); 
    } 

    //Flushes the buffer to a node 
    function flush(targetNode) { 

     //if the target node is not given then use the body 
     var targetNode = targetNode || document.body; 

     //append the domFragment to the target 
     targetNode.appendChild(domFragment); 

    } 

    //return the buffer 
    return { 
     "add": add, 
     "flush": flush 
    } 
} 


//to make a buffer do this 
var buffer = Buffer(); 

//to add elements to the buffer do the following 
buffer.add(someNode1); 

//continue to add elements to the buffer 
buffer.add(someNode2); 
buffer.add(someNode3); 
buffer.add(someNode4); 
buffer.add(someN...); 

//when you are done adding nodes flush the nodes to the containing div in the dom 
buffer.flush(myContainerNode); 

Sử dụng đối tượng này tôi có thể làm cho ~ 1000 mục vào màn hình ~ 40 lần một giây trong firefox 4.

Dưới đây là một trường hợp sử dụng.

+0

Tôi đã viết mã cảm ơn! Câu hỏi đặt ra là "cách nhanh nhất để nối thêm vào vị trí" Anh chàng đang chèn một cái bàn là gì. Nó không quan trọng nếu một bảng hoặc một div. Rõ ràng là bạn đã không đọc câu trả lời của tôi rất tốt. Và nói rằng việc chèn nhận thức nhanh hơn việc lưu vào bộ đệm và nối thêm vẫn không đúng. Nếu bạn không thể hiểu sự liên quan đó là xấu cho bạn. –

+0

Nó không làm tôi ngạc nhiên nếu bạn "viết" nó, không có gì huyền diệu về nó, thậm chí tôi không nói nó sai, nó vẫn không liên quan đến câu hỏi. Và vẫn không cho bạn quyền gọi câu trả lời của ai khác, ai quan tâm để đọc câu hỏi, không trung thực. Bạn không trung thực với ý thức chung. – galambalazs

+0

Điều đó thậm chí có nghĩa là không trung thực với ý nghĩa thông thường? Anh chàng muốn chèn một số nút liên quan đến bảng. Một đoạn DOM sẽ làm điều này. Bạn có vẻ như bạn có một phức tạp vượt trội. –

0

Tôi tạo một chuỗi khổng lồ và sau đó nối chuỗi này với jquery. Hoạt động tốt và nhanh chóng, đối với tôi.

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