วิธีที่มีประสิทธิภาพที่สุดในการสร้างองค์ประกอบ HTML โดยใช้ jQuery คืออะไร


425

เมื่อเร็ว ๆ นี้ฉันได้ทำป๊อปอัปหน้าต่างโมดอลมากมายและอะไรที่ฉันใช้ jQuery วิธีการที่ฉันใช้ในการสร้างองค์ประกอบใหม่บนหน้าเว็บนั้นมีมากมายตามแนวของ:

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

อย่างไรก็ตามฉันรู้สึกว่านี่ไม่ใช่วิธีที่ดีที่สุดหรือมีประสิทธิภาพมากที่สุดในการทำเช่นนี้ อะไรคือวิธีที่ดีที่สุดในการสร้างองค์ประกอบใน jQuery จากมุมมองประสิทธิภาพ

คำตอบนี้มีเกณฑ์มาตรฐานสำหรับคำแนะนำด้านล่าง


1
ทดสอบการลบสไตล์ด้วยและดูว่าสิ่งนั้นเร่งความเร็วขึ้นหรือไม่ ฉันพบแอปพลิเคชั่น CSS และอัปเดตช้าลงมากที่สุดในหน้าใหญ่สำหรับฉัน
CVertex

3
ระวังการปรับให้เหมาะสมก่อนกำหนด - หากคุณไม่ได้ทำสิ่งนี้กับองค์ประกอบ DOM หลายร้อยรายการในแต่ละครั้งหรือใช้เบราว์เซอร์รุ่นเก่ามากคุณอาจไม่สังเกตเห็นความแตกต่างในประสิทธิภาพของเบราว์เซอร์
Blazemonger

1
@ Blazemonger มันไม่มากนักที่ฉันต้องการวิธีที่มีประสิทธิภาพมากขึ้นในการสร้างองค์ประกอบ DOM แต่สถานการณ์ที่ฉันทำทำให้ฉันไตร่ตรองว่าทางเลือกคืออะไรและมีประสิทธิภาพแค่ไหน
Darko Z

2
jQuery เป็นห้องสมุด - คุณมักจะต้องเสียค่าใช้จ่ายด้านประสิทธิภาพการทำงานด้วยเหตุผลนี้: มันเหมือนกับการพูดคุยกับใครบางคนผ่านล่าม ยกเว้นว่าคุณต้องการใช้ JavaScript แบบดิบให้ใช้ประโยชน์จากความรวดเร็วในการเขียน $ ('<div>') และยอมรับผลการปฏิบัติงาน
Danny Bullis

1
jsben.ch/#/bgvCV <= เกณฑ์มาตรฐานนี้ควรตอบคำถามของคุณ
EscapeNetscape

คำตอบ:


307

ฉันใช้การ$(document.createElement('div')); เปรียบเทียบการแสดงเทคนิคนี้เป็นวิธีที่เร็วที่สุด ฉันคิดว่านี่เป็นเพราะ jQuery ไม่จำเป็นต้องระบุว่าเป็นองค์ประกอบและสร้างองค์ประกอบเอง

คุณควรใช้การวัดประสิทธิภาพด้วยเครื่องมือ Javascript ที่แตกต่างกันและชั่งน้ำหนักผู้ชมด้วยผลลัพธ์ ตัดสินใจจากที่นั่น


16
jQuery "ต่อท้าย" ไปที่ DOM? ที่ไหน? สิ่งนี้ไม่สมเหตุสมผลสำหรับฉัน - กองไหนจะไปไหน
แปลกหน้า

28
div ที่สร้างขึ้นใน jquery จะต้องถูกเพิ่มเช่นเดียวกับใน javascript $ ('<div>') โดยตัวมันเองจะไม่ถูกแนบมากับ DOM จนกว่าคุณจะผนวก () ต่อท้ายมันเพื่อบางสิ่ง
โอเว่น

6
@ David - เห็นได้ชัดว่าคุณพูดถูก ฉันจะทราบว่าฉันเพิ่มความคิดเห็นประมาณ 2 ปีที่ผ่านมาเมื่อฉันเริ่มเรียนรู้ jQuery คุณจะต้องทำappendTo... เนื่องจากความคิดเห็นนั้นผิดฉันจึงลบมันออกไป
tvanfosson

16
การอ้างอิงเปรียบเทียบนั้นยอดเยี่ยม แต่นี่เป็นการทดสอบการสร้างองค์ประกอบนับหมื่น เมื่อไหร่ที่คุณจะจัดการกับองค์ประกอบหลายอย่างในสถานการณ์ปกติ? โอกาสที่คุณจะได้รับสิ่งที่น่าเป็นห่วงมากกว่าการสร้างองค์ประกอบ document.createElement "วิ่ง 39,682 ครั้งใน 0.097 วินาที" ในขณะที่ $ ('<div>') "วิ่ง 12,642 ใน 0.068 วินาที" ฉันจะบอกว่าถ้าบางสิ่งบางอย่างสามารถทำงานหลายพันครั้งในเวลาน้อยกว่าหนึ่งวินาทีคุณจะปลอดภัย
Danny Bullis

20
นอกจากนี้การใช้ $ (document.createElement ('div')); ฉันจะบอกว่ามีประสิทธิภาพน้อยลงเพราะใช้เวลาเขียนนานกว่าเพื่อรับผลประโยชน์จำนวนเล็กน้อยที่คุณจะได้รับจากเบราว์เซอร์หากคุณสร้างองค์ประกอบเพียงครั้งเดียวที่นี่และที่นั่น ในทางเทคนิค jQuery นั้นมีประสิทธิภาพน้อยกว่าในฐานะห้องสมุดเนื่องจากค่าใช้จ่ายในการค้นหาและค่าใช้จ่ายที่เกิดขึ้นจากการใช้งาน หากมีคนตั้งใจจะบันทึกค่าหนึ่งในพันของวินาทีโดยใช้ document.createElement แทน $ ('<div>') ดังนั้นพวกเขาไม่ควรใช้ jQuery:] เพราะ $ ('<div>') เป็นหนึ่งในเหตุผลที่คุณใช้มัน!
Danny Bullis

163

ส่วนตัวฉันขอแนะนำ (สำหรับการอ่าน):

$('<div>');

ตัวเลขบางตัวเกี่ยวกับข้อเสนอแนะ (ซาฟารี 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
จาก jquery docs: 'เมื่อสร้างองค์ประกอบเดียวให้ใช้แท็กปิดหรือรูปแบบ XHTML ตัวอย่างเช่นในการสร้างช่วงใช้ $ ("<span />") หรือ $ ("<span> </span>") แทนโดยไม่มีเครื่องหมายทับ / แท็กปิด '
tvanfosson

6
@Owen พฤติกรรมนั้นเป็นข้อบกพร่องไม่ใช่คุณลักษณะ ขยะในขยะออก - มันเกิดขึ้นเพียงว่าขยะที่คุณได้รับเป็นที่ยอมรับ อย่าพึ่งพาระหว่าง jQuery เวอร์ชันยกเว้นว่าข้อมูลจำเพาะสำหรับฟังก์ชั่นจะเปลี่ยนไป
แปลกหน้า

2
ตามที่คาดไว้การเห็นตัวเลขที่คล้ายกันใน Mac OS X Chrome (100ms สำหรับ createElement () เทียบกับการแยกวิเคราะห์ข้อความ 500ms) และ Mac OS X Firefox (350ms เทียบกับ 1,000 มิลลิวินาที) ขอบคุณที่เขียนลูปทดสอบ
Annika Backstrom

3
@tvanfosson สิ่งนี้มีการเปลี่ยนแปลงอย่างชัดเจนในเอกสารปัจจุบันมันบอกว่า: "เมื่อพารามิเตอร์มีแท็กเดียว (พร้อมแท็กปิดที่เป็นตัวเลือกหรือปิดอย่างรวดเร็ว) - $ (" <img /> ") หรือ $ (" <img> " ), $ ("<a> </a>") หรือ $ ("<a>") - jQuery สร้างองค์ประกอบโดยใช้ฟังก์ชัน JavaScript createElement () ดั้งเดิมของ JavaScript
metatron

3
@MarcStober ไม่มีความผิด ก็ยังคงที่นี่: http://api.jquery.com/jQuery/#jQuery2 เอกสารพูดถึงแท็กปิดตัวเลือกหรือปิดอย่างรวดเร็ว
เมตาตรอน

155

คำถาม:

วิธีที่มีประสิทธิภาพที่สุดในการสร้างองค์ประกอบ HTML โดยใช้ jQuery คืออะไร

ตอบ:

เนื่องจากมันเกี่ยวกับjQueryแล้วฉันคิดว่ามันจะดีกว่าที่จะใช้วิธีนี้ (สะอาด) (คุณกำลังใช้)

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

การสาธิต.

ด้วยวิธีนี้คุณสามารถใช้ตัวจัดการเหตุการณ์สำหรับองค์ประกอบเฉพาะเช่น

$('<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');

การสาธิต.

แต่เมื่อคุณจัดการกับองค์ประกอบแบบไดนามิกจำนวนมากคุณควรหลีกเลี่ยงการเพิ่มเหตุการณ์handlersในองค์ประกอบเฉพาะแทนคุณควรใช้ตัวจัดการเหตุการณ์ที่ได้รับมอบหมายเช่น

$(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');
}

การสาธิต.

ดังนั้นถ้าคุณสร้างและผนวกองค์ประกอบหลายร้อยรายการกับคลาสเดียวกันนั่นคือ ( myClass) หน่วยความจำน้อยกว่าจะถูกใช้สำหรับการจัดการเหตุการณ์เพราะมีผู้จัดการเพียงคนเดียวเท่านั้นที่จะทำหน้าที่สำหรับองค์ประกอบที่แทรกแบบไดนามิกทั้งหมด

อัปเดต:เนื่องจากเราสามารถใช้วิธีการต่อไปนี้เพื่อสร้างองค์ประกอบแบบไดนามิก

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

แต่sizeไม่สามารถตั้งค่าแอตทริบิวต์โดยใช้วิธีนี้โดยใช้jQuery-1.8.0หรือใหม่กว่าและนี่คือรายงานข้อผิดพลาดเก่าดูที่ตัวอย่างนี้โดยใช้jQuery-1.7.2ซึ่งแสดงว่าsizeแอตทริบิวต์นั้นถูกตั้งค่าให้30ใช้ตัวอย่างด้านบน แต่ใช้วิธีเดียวกันกับที่เราไม่สามารถตั้งค่าsizeแอตทริบิวต์jQuery-1.8.3ได้ที่นี่ เป็นซอไม่ทำงาน ดังนั้นเพื่อตั้งค่าsizeแอตทริบิวต์เราสามารถใช้วิธีการดังต่อไปนี้

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

หรืออันนี้

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

เราสามารถส่งผ่านattr/propเป็นวัตถุเด็ก แต่การทำงานในjQuery-1.8.0 and laterรุ่นตรวจสอบตัวอย่างนี้แต่มันจะไม่ทำงานในjQuery-1.7.2 or earlier(ไม่ได้ทดสอบในทุกรุ่นก่อนหน้า)

BTW นำมาจากjQueryรายงานข้อผิดพลาด

มีหลายวิธี สิ่งแรกคืออย่าใช้งานเลยเพราะมันไม่ได้ช่วยให้คุณประหยัดพื้นที่และนี่ช่วยปรับปรุงความชัดเจนของรหัส:

พวกเขาแนะนำให้ใช้วิธีการต่อไปนี้ ( ทำงานในวิธีก่อนหน้าเช่นกันทดสอบด้วย1.6.4)

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

ดังนั้นจึงเป็นการดีกว่าที่จะใช้วิธีนี้ IMO การอัปเดตนี้เกิดขึ้นหลังจากที่ฉันอ่าน / พบคำตอบนี้และในคำตอบนี้แสดงให้เห็นว่าหากคุณใช้'Size'(capital S)แทนที่จะเป็น'size'แล้วมันก็จะทำงานได้ดีแม้ในversion-2.0.2

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

อ่านเกี่ยวกับเสาเพราะมีความแตกต่างกันAttributes vs. Propertiesมันแตกต่างกันไปตามรุ่น


ซินแทกซ์ชนิดนี้คืออะไร $ ('<div />', {......... }) ฉันได้ค้นหามันแล้วฉันก็พบว่ามันคล้ายกันโดยใช้ $ ('<div>) .attr ( {...... })?
Rafael Ruiz Tabares

@RafaelRuizTabares ใน$('<div>', {...})คุณผ่านวัตถุที่มีคุณลักษณะทั้งหมดและ$('<div>').attr({...})คุณกำลังสร้างองค์ประกอบโดยไม่มีคุณลักษณะใด ๆ แต่การตั้งค่าคุณลักษณะที่ใช้attr()วิธีการในภายหลัง
อัลฟ่า

@TheAlpha ฉันสามารถหาข้อมูลเกี่ยวกับสิ่งที่ฉันสามารถเขียนภายใน {} ได้ที่ไหน เพราะฉันเห็นว่ามันเป็นคุณลักษณะและกิจกรรม แต่สำหรับ <div> คุณก็ใช้ html ด้วยเช่นกัน ขอบคุณ!
Rafael Ruiz Tabares

ค้นหาjQuery.comเว็บไซต์อาจมีประโยชน์ @RafaelRuizTabares หรือ google it :-)
The Alpha

2
นี่เป็นวิธีที่อ่านง่ายที่สุดที่สะอาดที่สุด! อาจไม่ใช่วิธีที่รวดเร็ว แต่มีข้อผิดพลาดน้อยกว่าที่จะเกิดขึ้นกับการเพิ่มสตริง ขอบคุณ @TheAlpha
Ares

37

ที่จริงแล้วถ้าคุณทำ$('<div>')jQuery ก็จะใช้เช่นกันdocument.createElement()เช่นกัน

(ดูที่บรรทัดที่ 117 )

มีค่าใช้จ่ายในการเรียกใช้ฟังก์ชัน แต่มีประสิทธิภาพที่สำคัญ (คุณกำลังสร้างองค์ประกอบหลายแสน [พัน]) ไม่มีเหตุผลมากที่จะเปลี่ยนกลับเป็นDOMธรรมดา DOM

เพียงแค่การสร้างองค์ประกอบสำหรับหน้าเว็บใหม่อาจเป็นกรณีที่คุณควรทำตามjQueryในการทำสิ่งต่าง ๆ


20

หากคุณมีเนื้อหา HTML จำนวนมาก (มากกว่า div เดียว) คุณอาจลองสร้าง HTML ในหน้าภายในคอนเทนเนอร์ที่ซ่อนไว้จากนั้นอัปเดตและทำให้มองเห็นได้เมื่อจำเป็น ด้วยวิธีนี้ส่วนใหญ่ของมาร์กอัปของคุณสามารถแยกวิเคราะห์ล่วงหน้าโดยเบราว์เซอร์และหลีกเลี่ยงการจมลงโดย JavaScript เมื่อมีการเรียก หวังว่านี่จะช่วยได้!


ขอบคุณสำหรับคำแนะนำ. ฉันเคยใช้วิธีนี้มาก่อน แต่ในกรณีนี้ฉันต้องการรู้เกี่ยวกับการสร้างองค์ประกอบโดยเฉพาะ
Darko Z

20

นี่ไม่ใช่คำตอบที่ถูกต้องสำหรับคำถาม แต่ฉันยังต้องการแชร์สิ่งนี้ ...

ใช้เพียง document.createElement('div')ข้าม JQuery จะช่วยเพิ่มประสิทธิภาพได้มากขึ้นเมื่อคุณต้องการสร้างองค์ประกอบจำนวนมากในทันทีและผนวกเข้ากับ DOM


16

ฉันคิดว่าคุณกำลังใช้วิธีที่ดีที่สุดแม้ว่าคุณจะสามารถปรับให้เหมาะสมกับ:

 $("<div/>");

11

คุณไม่ต้องการประสิทธิภาพดิบจากการดำเนินการคุณจะทำงานไม่บ่อยนักจากมุมมองของ CPU


ขึ้นอยู่กับว่าคุณทำบ่อยแค่ไหน
แบรดชอว์รวย

8
สหกรณ์คือการสร้างป๊อปอัพคำกริยา การดำเนินการนี้ไม่ซ้ำหลายพันครั้งต่อวินาที แต่จะทำซ้ำได้สูงสุดทุกๆสองสามวินาที ใช้jQuery(html :: String)วิธีการได้อย่างสมบูรณ์แบบ เว้นแต่สถานการณ์จะผิดปกติอย่างยิ่งคนคนหนึ่งจะไม่ได้รับประสิทธิภาพที่รับรู้ได้ดีขึ้น ใช้พลังงานในการปรับให้เหมาะสมกับกรณีที่สามารถใช้งานได้ นอกจากนี้ jQuery ยังได้รับการปรับให้เหมาะสมกับความเร็วในหลาย ๆ ด้าน ทำสิ่งที่มีสติด้วยและเชื่อใจ แต่ยืนยันว่ามันเร็ว
yfeldblum

9

คุณจะต้องเข้าใจว่าความสำคัญของประสิทธิภาพการสร้างองค์ประกอบนั้นไม่เกี่ยวข้องในบริบทของการใช้ jQuery ตั้งแต่แรก

โปรดทราบว่าไม่มีวัตถุประสงค์ที่แท้จริงในการสร้างองค์ประกอบเว้นแต่ว่าคุณจะใช้งานจริง

คุณอาจถูกล่อลวงให้ทดสอบประสิทธิภาพเช่น$(document.createElement('div'))vs. $('<div>')และรับประสิทธิภาพที่ยอดเยี่ยมจากการใช้$(document.createElement('div'))แต่นั่นเป็นเพียงองค์ประกอบที่ยังไม่ได้อยู่ใน DOM

อย่างไรก็ตามในตอนท้ายของวันคุณจะต้องการใช้องค์ประกอบต่อไปดังนั้นการทดสอบจริงควรรวม f.ex .appendTo ();

ลองดูถ้าคุณทดสอบสิ่งต่อไปนี้กับแต่ละอื่น ๆ :

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

คุณจะสังเกตเห็นผลลัพธ์จะแตกต่างกันไป บางครั้งวิธีการหนึ่งก็มีประสิทธิภาพดีกว่าวิธีอื่น และนี่เป็นเพราะปริมาณงานพื้นหลังในคอมพิวเตอร์ของคุณเปลี่ยนไปตามเวลา

ทดสอบด้วยตัวเองที่นี่

ดังนั้นในตอนท้ายของวันคุณต้องการเลือกวิธีที่เล็กที่สุดและอ่านง่ายที่สุดในการสร้างองค์ประกอบ ด้วยวิธีนี้อย่างน้อยไฟล์สคริปต์ของคุณจะเล็กที่สุดเท่าที่จะเป็นไปได้ อาจเป็นปัจจัยที่มีความสำคัญมากกว่าในจุดประสิทธิภาพมากกว่าวิธีการสร้างองค์ประกอบก่อนที่คุณจะใช้องค์ประกอบใน DOM


ฉันรู้ว่านี่เก่า แต่ไม่จำเป็นต้อง jQuery ในตัวอย่างแรก:document.getElementById('target).appendChild(document.createElement('div'));
hisdrewness


7

ประเด็นหนึ่งคือมันอาจจะง่ายกว่าที่จะทำ:

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

จากนั้นให้ทำทุกสิ่งด้วย jquery call


3

ฉันใช้ jquery.min v2.0.3 มันสำหรับฉันดีกว่าที่จะใช้ต่อไปนี้:

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

ดังต่อไปนี้:

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

เวลาประมวลผลของรหัสแรกต่ำกว่ารหัสที่สองมาก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.