เด็กที่เร็วที่สุด () หรือ find () ใน jQuery คืออะไร


320

ในการเลือกโหนดลูกใน jQuery เราสามารถใช้ children () แต่ยังพบ ()

ตัวอย่างเช่น:

$(this).children('.foo');

ให้ผลเหมือนกับ:

$(this).find('.foo');

ตอนนี้ตัวเลือกใดเร็วที่สุดหรือเป็นที่ต้องการและทำไม


27
.find()และ.children()ไม่เหมือนกัน สิ่งหลังเท่านั้นที่ผ่านระดับ DOM ลงไปเพียงระดับเดียวเท่านั้นเช่นตัวเลือกลูก
Timothy003

1
@ Timothy003 คุณอธิบายผิดแล้วอดีตคนหนึ่งเดินทางระดับเดียวไม่ลงหลัง
Dipesh Rana

5
@DipeshRana คำว่า 'หลัง' นำไปใช้กับประโยคของ Timothy003 ไม่ใช่คำถาม
Jayesh Bhoot

1
ขอขอบคุณที่แจ้งปัญหานี้ ในหลายกรณีความแตกต่างด้านประสิทธิภาพนั้นเล็กน้อย แต่เอกสารไม่ได้กล่าวถึงว่าทั้งสองวิธีนี้มีการใช้งานที่แตกต่างกัน เพื่อเป็นการปฏิบัติที่ดีที่สุดเรารู้ดีว่าfind()เกือบเร็วกว่าเสมอ
Steve Benner

นั่นเป็นเหตุผลที่ฉันไม่เคยชอบการก่อสร้าง "อดีต" หรือ "หลัง" ในภาษาอังกฤษ แค่บอกว่าอันไหนที่คุณหมายถึง Sheesh
Chris Walker

คำตอบ:


415

children()ดูที่ชายด์ทันทีของโหนดในขณะที่find()สำรวจทั้ง DOM ด้านล่างโหนดดังนั้นchildren() ควรเร็วขึ้นเมื่อมีการใช้งานที่เทียบเท่า อย่างไรก็ตามfind()ใช้วิธีเบราว์เซอร์ดั้งเดิมในขณะที่children()ใช้JavaScriptตีความในเบราว์เซอร์ ในการทดลองของฉันมีกรณีทั่วไปไม่แตกต่างกันมาก

สิ่งที่ใช้ขึ้นอยู่กับว่าคุณต้องการพิจารณาเฉพาะผู้สืบทอดโดยตรงหรือโหนดทั้งหมดด้านล่างนี้ใน DOM คือเลือกวิธีที่เหมาะสมตามผลลัพธ์ที่คุณต้องการไม่ใช่ความเร็วของวิธีการนั้น หากประสิทธิภาพเป็นปัญหาอย่างแท้จริงให้ทดลองเพื่อหาทางออกที่ดีที่สุดและใช้วิธีนั้น (หรือดูเกณฑ์มาตรฐานบางอย่างในคำตอบอื่น ๆ ที่นี่)


9
แน่นอน แต่จะเกิดอะไรขึ้นถ้าองค์ประกอบหลักมีโหนดลูกเท่านั้น ฉันจะทำโปรไฟล์นี้
jason

11
ประสิทธิภาพของ children vs find ขึ้นอยู่กับเบราว์เซอร์และความซับซ้อนของ DOM-subtree ที่คุณค้นหา ในเบราว์เซอร์รุ่นใหม่ find () ภายในใช้ querySelectorAll ซึ่งสามารถมีประสิทธิภาพเหนือกว่าเด็ก ๆ () ในตัวเลือกที่ซับซ้อนและในทรีย่อย DOM ขนาดเล็กถึงปานกลาง
LeJared

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

สำหรับฉันในการทดสอบทั้งหมดที่มีการซ้อนลำดับชั้นระหว่าง 5 ถึง 20 find () เด็กที่มีประสิทธิภาพสูงกว่าเสมอ () (ทดสอบใน Google Chrome 54) ฉันคาดหวังสิ่งที่ตรงกันข้าม ดังนั้นจากนี้ไปฉันจะใช้วิธีที่ง่ายและค้นหา (... ) องค์ประกอบของฉันแทนที่จะไปตามลูก (). children (). children (). children () ...
Ruwen

179

การทดสอบ jsPerfนี้แสดงให้เห็นว่า find () เร็วขึ้น ฉันสร้างการทดสอบอย่างละเอียดมากขึ้นและมันก็ดูเหมือนว่า find () มีประสิทธิภาพเหนือกว่าเด็ก ๆ ()

อัปเดต:ตามความคิดเห็นของ tvanfosson ฉันสร้างกรณีทดสอบอีกชุดหนึ่งซึ่งมีการทำรัง 16 ระดับ find () ช้าลงเมื่อค้นหา div ที่เป็นไปได้ทั้งหมด แต่ find () ยังดีกว่า children () เมื่อเลือกระดับ div แรก

children () เริ่มมีประสิทธิภาพสูงกว่า find () เมื่อมีการซ้อนมากกว่า 100 ระดับและประมาณ 4,000+ divs สำหรับ find () เพื่อสำรวจ เป็นกรณีทดสอบพื้นฐาน แต่ฉันก็ยังคิดว่า find () เร็วกว่าเด็ก () ในกรณีส่วนใหญ่

ฉันก้าวผ่านรหัส jQuery ในเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ของ Chrome และสังเกตเห็นว่า children () โทรภายในไปยัง sibling (), filter () และผ่าน regexes อีกสองสามกว่า find ()

find () และ children () เติมเต็มความต้องการที่แตกต่างกัน แต่ในกรณีที่ find () และ children () จะแสดงผลลัพธ์เดียวกันฉันขอแนะนำให้ใช้ find ()


4
ดูเหมือนว่าเด็กใช้วิธีการสำรวจเส้นทางและค้นหาใช้ตัวเลือก API ซึ่งเร็วกว่า
topek

4
เคสทดสอบแย่ลงเนื่องจากคุณมีการซ้อนเพียงระดับเดียว หากคุณต้องการกรณีทั่วไปคุณจะต้องตั้งค่าความลึกในการซ้อนโดยพลการและตรวจสอบประสิทธิภาพในการค้นหา () สำรวจต้นไม้ที่ลึกกว่าเด็ก ()
tvanfosson

หากคุณกำลังตรวจสอบว่าองค์ประกอบลูกเอกพจน์ที่เฉพาะเจาะจง (เช่น. event.target) อยู่ในองค์ประกอบ dom ที่เฉพาะเจาะจง (เช่น $ ('. navbar')) ดังนั้น $ .contain (นี่คือ event.target) นั้นเร็วที่สุด (8,433,609 / วินาทีเทียบกับ 140k เพื่อการค้นหา jquery ที่เร็วที่สุด) jsperf.com/child-is-in-parent
Chris Sattinger

92

นี่คือลิงค์ที่มีการทดสอบประสิทธิภาพที่คุณสามารถเรียกใช้ได้ find()เป็นจริงประมาณ 2 children()ครั้งเร็วกว่า

Chrome บน OSX10.7.6


$ .contain (document.getElementById ('list'), $ ('. test') [0]) คือ 8,433,609 / วินาที หากคุณมีองค์ประกอบเฉพาะและต้องการทราบว่า B อยู่ใน A หรือไม่นี่เป็นวิธีที่ดีที่สุด jsperf.com/child-is-in-parent
Chris Sattinger

การทดสอบที่ดี โปรดทราบว่ามันอาจเร็วยิ่งขึ้นถ้าคุณทำบางสิ่งเช่นvar $test = $list.find('.test');ที่ $ list เป็นวัตถุ jQuery jsperf.com/jquery-selectors-context/101
Maciej Krawczyk

24

สิ่งเหล่านั้นไม่จำเป็นต้องให้ผลลัพธ์เหมือนกัน: find()จะทำให้คุณได้รับโหนดผู้สืบทอดใด ๆในขณะที่children()จะทำให้คุณได้รับลูก ๆที่ตรงกันเท่านั้น

จนถึงจุดหนึ่งfind()ช้ากว่ามากเนื่องจากมันต้องค้นหาโหนดที่สืบทอดทั้งหมดที่อาจเป็นการจับคู่ไม่ใช่เฉพาะลูกที่อยู่ติดกัน อย่างไรก็ตามสิ่งนี้ไม่เป็นความจริงอีกต่อไป find()เร็วกว่ามากเนื่องจากใช้วิธีเบราว์เซอร์ดั้งเดิม


1
ไม่เป็นไปตามคำตอบอื่น ๆ ฮ่าฮ่า: p เฉพาะเมื่อคุณมีต้นไม้ DOM ที่ยิ่งใหญ่มาก ๆ ..
pgarciacamou

1
@Camou คำตอบนี้อายุสี่ขวบ find()ในเวลานั้นช้าลงมาก!
John Feminella

@camou บอกว่าส่วนการแสดงคือ "ไม่เป็นไปตามคำตอบอื่น ๆ " ย่อหน้าแรกของคำตอบนี้ถูกต้อง
Don Cheadle

14

ไม่มีคำตอบอื่น ๆ จัดการกับกรณีของการใช้.children()หรือ.find(">")จะเพียงค้นหาสำหรับเด็กทันทีขององค์ประกอบผู้ปกครอง ดังนั้นฉันจึงสร้างการทดสอบ jsPerf เพื่อค้นหาโดยใช้วิธีที่แตกต่างกันสามวิธีในการแยกแยะเด็ก ๆ

เมื่อมันเกิดขึ้นแม้เมื่อมีการใช้เป็นพิเศษ ">" เลือกคำ.find()ยังคงเป็นจำนวนมากได้เร็วกว่า.children(); ในระบบของฉัน 10x ดังนั้น

ดังนั้นจากมุมมองของฉันดูเหมือนจะไม่มีเหตุผลมากนักที่จะใช้กลไกการกรอง.children()ทั้งหมด


3
ขอบคุณสำหรับความคิดเห็นนี้! ฉันสงสัยว่า jQuery ควรเปลี่ยนมาใช้การสร้าง. child (x) เป็นนามแฝงสำหรับ. find (">" + x) แม้ว่าอาจมีภาวะแทรกซ้อนอื่น ๆ ที่ฉันไม่ได้คิด
Michael Scott Cuthbert

1
ดูเหมือนว่าเป็นการเปรียบเทียบที่เหมาะสมที่สุด ขอบคุณ!
GollyJer

3

ทั้งวิธีการfind()และchildren()วิธีใช้ในการกรองลูกขององค์ประกอบที่ตรงกันยกเว้นก่อนหน้านี้คือการเดินทางในระดับใด ๆ ลงหลังคือการเดินทางลงในระดับเดียว

เพื่อทำให้ง่ายขึ้น:

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