เบราว์เซอร์แยกวิเคราะห์จาวาสคริปต์ทุกครั้งที่โหลดหน้าเว็บหรือไม่


190

เบราว์เซอร์ (IE และ Firefox) แยกวิเคราะห์ไฟล์จาวาสคริปต์ที่เชื่อมโยงทุกครั้งที่รีเฟรชหน้าเว็บหรือไม่

พวกเขาสามารถแคชไฟล์ได้ดังนั้นฉันเดาว่าจะไม่พยายามดาวน์โหลดทุกครั้ง แต่เนื่องจากแต่ละหน้าแยกจากกันเป็นหลักฉันคาดว่าพวกเขาจะทำลายรหัสเก่าและแยกวิเคราะห์อีกครั้ง

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


4
My 2c: ฉันรู้สึกว่าประสิทธิภาพการทำงานของไฟล์ Javascript ที่วิเคราะห์แล้วมีขนาดเล็กเกินไปสำหรับการเพิ่มประสิทธิภาพที่มีความหมาย
Itay Maman

2
จากมาตรฐานของฉันมันอาจสำคัญ ตัวอย่างเช่นความเร็วในการโหลด jQuery อยู่ที่ประมาณ 30msecs (บนเครื่องเดสก์ท็อปเร็ว) ซึ่ง 20% เป็นเพียงการแยกวิเคราะห์โค้ดในการแทนค่าที่สามารถเรียกใช้งานได้และส่วนที่เหลือกำลังดำเนินการอยู่นั่นคือการเริ่มต้นวัตถุ jQuery ในกรณีนี้ หากคุณใช้มือถือและคุณใช้ห้องสมุดสองหรือสามแห่งความล่าช้านี้อาจเกี่ยวข้องเนื่องจากการดำเนินการ JavaScript กำลังบล็อกและหน้าเว็บจะว่างเปล่าเป็นหลักจนกว่าสคริปต์ JS ทั้งหมดจะโหลดในหน่วยความจำ
djjeck

คำตอบ:


338

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


Chrome: V8 Engine

V8 มีแคชรวบรวม การจัดเก็บนี้รวบรวม JavaScript โดยใช้แฮชของแหล่งที่มาสำหรับคอลเลกชันขยะสูงสุด 5 รายการ ซึ่งหมายความว่าซอร์สโค้ดสองชิ้นที่เหมือนกันจะแชร์รายการแคชในหน่วยความจำไม่ว่าจะรวมอยู่ในที่ใด แคชนี้ไม่ถูกล้างออกเมื่อทำการโหลดหน้าใหม่

แหล่ง


อัปเดต - 19/03/2015

ทีมงาน Chrome ได้เปิดเผยรายละเอียดเกี่ยวกับเทคนิคใหม่ของการสตรีมและการแคช JavaScriptแคช

  1. การสตรีมสคริปต์

การสตรีมสคริปต์เพิ่มประสิทธิภาพการแยกวิเคราะห์ไฟล์ JavaScript [ ... ]

เริ่มต้นในรุ่น 41 Chrome จะแยกวิเคราะห์ async และสคริปต์ที่เลื่อนออกไปบนเธรดแยกต่างหากทันทีที่การดาวน์โหลดเริ่มขึ้น ซึ่งหมายความว่าการวิเคราะห์คำสามารถเสร็จสมบูรณ์เพียงแค่มิลลิวินาทีหลังจากการดาวน์โหลดเสร็จสิ้นและส่งผลให้หน้าโหลดเร็วขึ้นมากถึง 10%

  1. การแคชรหัส

โดยปกติแล้วเครื่องยนต์ V8 จะรวบรวม JavaScript ของหน้าเว็บทุกครั้งที่เข้าชมโดยเปลี่ยนเป็นคำแนะนำที่โปรเซสเซอร์เข้าใจ รหัสที่คอมไพล์แล้วจะถูกยกเลิกเมื่อผู้ใช้นำทางออกจากหน้าเว็บเนื่องจากโค้ดที่รวบรวมนั้นขึ้นอยู่กับสถานะและบริบทของเครื่องในเวลารวบรวม

Chrome 42 แนะนำเทคนิคขั้นสูงในการจัดเก็บสำเนาของรหัสที่คอมไพล์ในเครื่องดังนั้นเมื่อผู้ใช้กลับไปที่หน้าการดาวน์โหลดการแยกวิเคราะห์และขั้นตอนการรวบรวมสามารถข้ามได้ ในการโหลดหน้าเว็บทั้งหมดนี้ทำให้ Chrome สามารถหลีกเลี่ยงการรวบรวมเวลาได้ 40% และประหยัดแบตเตอรี่ที่มีค่าบนอุปกรณ์มือถือ


Opera: Carakan Engine

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

ดังนั้น JavaScript ถูกแคชระหว่างการโหลดหน้าซ้ำสองคำขอไปยังสคริปต์เดียวกันจะไม่ส่งผลให้มีการรวบรวมใหม่

แหล่ง


Firefox: SpiderMonkey Engine

SpiderMonkey ใช้Nanojitเป็น back-end ดั้งเดิมของคอมไพเลอร์ JIT ขั้นตอนของการรวบรวมรหัสเครื่องที่สามารถมองเห็นได้ที่นี่ กล่าวโดยย่อดูเหมือนว่าจะคอมไพล์สคริปต์อีกครั้งขณะที่โหลด อย่างไรก็ตามถ้าเรามองลึกเข้าไปภายในของNanojitเราเห็นว่าจอภาพระดับสูงjstracerซึ่งใช้ในการติดตามการรวบรวมสามารถเปลี่ยนผ่านสามขั้นตอนในระหว่างการรวบรวมให้ประโยชน์Nanojit:

สถานะเริ่มต้นของการตรวจสอบติดตามคือการตรวจสอบ ซึ่งหมายความว่า spidermonkey กำลังตีความ bytecode ทุกครั้งที่ spidermonkey ตีความ bytecode ย้อนหลังกระโดดจอภาพจะบันทึกจำนวนครั้งที่ค่าโปรแกรมข้ามเคาน์เตอร์เป้าหมาย (PC) ถูกข้ามไปยัง หมายเลขนี้เรียกว่าจำนวนการเข้าชมสำหรับพีซี หากจำนวนการเข้าชมของพีซีใดเครื่องหนึ่งถึงค่าเกณฑ์เป้าหมายจะถือว่าร้อน

เมื่อจอภาพตัดสินพีซีเป้าหมายร้อนมันจะดูเป็นส่วนย่อยเพื่อดูว่ามีชิ้นส่วนที่ถือรหัสเนทีฟสำหรับพีซีเป้าหมายนั้นหรือไม่ หากพบชิ้นส่วนดังกล่าวจะเปลี่ยนเป็นโหมดการดำเนินการ มิฉะนั้นจะเปลี่ยนเป็นโหมดบันทึก

ซึ่งหมายความว่าสำหรับhotรหัสเศษเล็กเศษน้อยรหัสพื้นเมืองจะถูกแคช ความหมายที่ไม่จำเป็นต้องคอมไพล์ใหม่ ไม่ชัดเจนว่าส่วนที่ถูกแฮชแบบดั้งเดิมถูกเก็บไว้ระหว่างการรีเฟรชหน้าหรือไม่ แต่ฉันคิดว่าพวกเขาเป็นหากใครสามารถหาหลักฐานสนับสนุนสำหรับเรื่องนี้แล้วยอดเยี่ยม

แก้ไข : มันได้รับการชี้ให้เห็นว่านักพัฒนา Mozilla บอริส Zbarsky ได้กล่าวว่าตุ๊กแกไม่ได้รวบรวมแคชสคริปต์เลย นำมาจากคำตอบ SOนี้


Safari: JavaScriptCore / SquirelFish Engine

ฉันคิดว่าคำตอบที่ดีที่สุดสำหรับการติดตั้งใช้งานนี้ได้รับจากบุคคลอื่นแล้ว

ขณะนี้เราไม่ได้แคชไบต์ (หรือรหัสพื้นเมือง) มันเป็น
ตัวเลือกที่เราได้พิจารณาอย่างไรก็ตามในปัจจุบันการสร้างรหัสเป็น
ส่วนที่สำคัญของเวลาดำเนินการ JS (<2%) ดังนั้นเราจึงไม่ดำเนินการต่อ
นี้ในขณะนี้

สิ่งนี้เขียนโดยMaciej Stachowiakผู้นำการพัฒนาของ Safari ดังนั้นฉันคิดว่าเราสามารถเป็นจริงได้

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


IE: Chakra Engine

ไม่มีข้อมูลปัจจุบันเกี่ยวกับ JavaScript Engine (Chakra) ของ IE9 ในด้านนี้ หากใครรู้อะไรกรุณาแสดงความคิดเห็น

นี่เป็นเรื่องที่ค่อนข้างไม่เป็นทางการ แต่สำหรับการใช้งานเครื่องมือรุ่นเก่าของ IE นั้น Eric Lippert ( ผู้พัฒนา MS ของ JScript ) ระบุไว้ในบล็อกตอบกลับที่นี่ว่า:

JScript Classic ทำหน้าที่เหมือนภาษาที่คอมไพล์ในแง่ที่ว่าก่อนที่โปรแกรม JScript Classic ใด ๆ จะทำงานเราจะตรวจสอบไวยากรณ์ทั้งหมดของโค้ดสร้างแผนผังการแยกแบบเต็มและสร้าง bytecode จากนั้นเราจะเรียกใช้ bytecode ผ่านล่าม bytecode ในแง่นั้น JScript นั้นเป็น "คอมไพล์" เหมือนกับ Java ความแตกต่างคือ JScript ไม่อนุญาตให้คุณยังคงมีอยู่หรือตรวจสอบ bytecode นอกจากนี้ bytecode ยังสูงกว่า JVM bytecode มาก - ภาษา JScript Classic bytecode นั้นเล็กไปกว่าการวางตัวเป็นแนวตรงของต้นไม้ในขณะที่ JVM bytecode นั้นมีจุดประสงค์ที่ชัดเจนในการใช้งานบนเครื่องสแต็กระดับต่ำ

สิ่งนี้ชี้ให้เห็นว่า bytecode ไม่คงอยู่ในลักษณะใด ๆ และทำให้ bytecode ไม่ถูกแคช


10
+1 การเขียนที่ยอดเยี่ยม อย่างไรก็ตามสำหรับ Firefox โปรดดูคำถาม StackOverflow นี้ที่ Mozilla Developer Boris Zbarsky อธิบายว่าขณะนี้ Gecko ไม่ได้ทำเช่นนี้
cha0site

ขอบคุณฉันเห็นว่าในการเดินทางของฉัน แต่ไม่พบหลักฐานสนับสนุนอื่น ๆ ฉันจะแก้ไขคำตอบด้วย
Jivings

1
โปรดทราบว่าสิ่งที่เขาพูดเกี่ยวกับ IE ที่ถูกกล่าวว่าในปี 2003: เครื่องยนต์ JS IE9 ปล่อยเป็นครั้งแรกใน IE9 ในปี 2011
gsnedders

นอกจากนี้ Opera ยังแคช JS bytecode มากกว่าการโหลดซ้ำ (อย่างไรก็ตามรหัสเครื่องที่สร้างไม่ได้ถูกแคชไว้)
gsnedders

2
@Jivings ทำตามข้างต้นเป็นแหล่งที่มา (ฉันเป็นคนหนึ่งในทีมงานของ Carakan)
gsnedders

12

Opera ทำตามที่ระบุไว้ในคำตอบอื่น ๆ (ที่มา )

Firefox (เอนจิ้น SpiderMonkey) ไม่ได้ทำการแคชตามรหัสไบต์ (ที่มา )

WebKit (Safari, Konqueror) ไม่ได้ทำการแคช bytecode (ที่มา )

ฉันไม่แน่ใจเกี่ยวกับ IE [6/7/8] หรือ V8 (Chrome) ฉันคิดว่า IE อาจทำการแคชบางอย่างในขณะที่ V8 อาจไม่ IE ถูกปิดแหล่งที่มาดังนั้นฉันไม่แน่ใจ แต่ใน V8 มันอาจไม่เหมาะสมที่จะแคช "รวบรวม" รหัสเพราะพวกเขารวบรวมตรงกับรหัสเครื่อง


1
IE6–8 แทบจะไม่แน่นอน IE9 อาจ แต่ฉันไม่มีหลักฐานใด ๆ ทั้งสองวิธี รวบรวม JS น่าจะไม่แคชที่ใดก็ได้เพราะมักจะค่อนข้างใหญ่
gsnedders

@gsnedders: ฉันไม่แน่ใจว่า IE8 ไม่สามารถทำได้ในทางเทคนิคดูเหมือนว่ามันเกินไปที่จะรวมกับ bytecode (ไม่ใช่เป็นทางการ แต่ปิด) ดังนั้นจึงไม่มีเหตุผลทางเทคนิคที่จะไม่แคช IE9 ดูเหมือนว่าจะเพิ่ม JIT เพื่อรวบรวมรหัสพื้นเมือง
cha0site

2
Bytecode ถูกใช้งานโดย IE มาตลอด ... ไม่มีอะไรใหม่ใน IE8 เป็นเพียงการให้ล่ามประสิทธิภาพของล่ามจะช้ากว่าการแยกวิเคราะห์เวลามากมันไม่เกี่ยวข้องทั้งหมด IE9 มีเอ็นจิน JS ใหม่ (ตั้งแต่เริ่มต้น) ดังนั้นจึงไม่มีสิ่งใดตามมาระหว่างทั้งสอง
gsnedders

3

เท่าที่ฉันทราบมีเพียง Opera เท่านั้นที่ใช้ JavaScript ในการแยกวิเคราะห์ ดูส่วน "แคชรวบรวมโปรแกรม" ที่นี่


ขอบคุณคุณมีรายละเอียดเพิ่มเติมเกี่ยวกับตระกูลเบราว์เซอร์อื่นหรือไม่
ajreal

2

Google Dartไม่มีค่าอะไรเลยจัดการกับปัญหานี้อย่างชัดเจนผ่าน "Snapshots" - เป้าหมายคือเพื่อเพิ่มความเร็วในการเริ่มต้นและเวลาในการโหลดโดยการโหลดรหัสรุ่นที่เตรียมไว้

InfoQ มีการเขียนที่ดี @ http://www.infoq.com/articles/google-dart


0

ฉันคิดว่าคำตอบที่ถูกต้องคือ "ไม่เสมอไป" จากสิ่งที่ฉันเข้าใจทั้งเบราว์เซอร์และเซิร์ฟเวอร์มีบทบาทในการกำหนดสิ่งที่แคช หากคุณต้องการโหลดไฟล์ใหม่ทุกครั้งฉันคิดว่าคุณควรจะสามารถกำหนดค่าไฟล์นั้นจากภายใน Apache (เช่น) แน่นอนฉันคิดว่าเบราว์เซอร์ของผู้ใช้สามารถกำหนดค่าให้ละเว้นการตั้งค่านั้น แต่อาจไม่น่าเป็นไปได้

ดังนั้นฉันจึงจินตนาการว่าในกรณีที่ใช้งานได้จริงส่วนใหญ่ไฟล์จาวาสคริปต์จะถูกแคช แต่จะถูกตีความใหม่ทุกครั้งที่โหลดหน้าเว็บ


0

เบราว์เซอร์ใช้ประโยชน์จากแคชอย่างแน่นอน แต่ใช่เบราว์เซอร์จะแยกวิเคราะห์ JavaScript ทุกครั้งที่มีการรีเฟรชหน้าเว็บ เพราะเมื่อใดก็ตามที่เบราว์เซอร์โหลดหน้าเว็บมันจะสร้างต้นไม้ 2 ต้นคือ 1.Content tree และ 2.render tree

ทรีเรนเดอร์นี้ประกอบด้วยข้อมูลเกี่ยวกับเลย์เอาต์ภาพขององค์ประกอบ dom ดังนั้นเมื่อใดก็ตามที่โหลดหน้าเว็บจาวาสคริปต์จะถูกแยกวิเคราะห์และการเปลี่ยนแปลงแบบไดนามิกใด ๆ โดยจาวาสคริปต์จะชอบการวางตำแหน่งองค์ประกอบ Dom องค์ประกอบแสดง / ซ่อนองค์ประกอบเพิ่ม / ลบองค์ประกอบจะทำให้เบราว์เซอร์สร้างต้นไม้การแสดงผล แต่ broswers ที่ทันสมัยเช่น FF และโครเมียมจัดการมันแตกต่างกันเล็กน้อยพวกเขามีแนวคิดของการเรนเดอร์ที่เพิ่มขึ้นดังนั้นเมื่อใดก็ตามที่มีการเปลี่ยนแปลงแบบไดนามิกโดย js ดังกล่าวข้างต้นมันจะทำให้องค์ประกอบเหล่านั้น

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