ดูวิธีใช้ Chrome และเครื่องมือสำหรับนักพัฒนาเว็บเพื่อค้นหาปัญหาเกี่ยวกับหน่วยความจำที่ส่งผลต่อประสิทธิภาพของหน้าเว็บ ซึ่งรวมถึงหน่วยความจำรั่วไหล หน่วยความจำบวม และการเก็บขยะบ่อยครั้ง
สรุป
- ดูปริมาณหน่วยความจำที่หน้าเว็บใช้ด้วยตัวจัดการงาน Chrome
- แสดงภาพการใช้งานหน่วยความจำเมื่อเวลาผ่านไปด้วยการบันทึกไทม์ไลน์
- ระบุแผนผัง DOM ที่ถูกปลดออก (สาเหตุที่พบบ่อยของหน่วยความจำรั่วไหล) ด้วยสแนปชอตฮีป
- ดูว่ามีการจัดสรรหน่วยความจำใหม่ใน JS Heap เมื่อใดด้วยการบันทึกไทม์ไลน์การจัดสรร
- ระบุองค์ประกอบที่แยกออกซึ่งเก็บไว้โดยการอ้างอิง JavaScript
ภาพรวม
ตามเจตนารมณ์ของโมเดลประสิทธิภาพ RAIL การมุ่งเน้นด้านประสิทธิภาพควรเป็นผู้ใช้
ปัญหาเกี่ยวกับหน่วยความจำเป็นเรื่องสำคัญเนื่องจากผู้ใช้มักจะสังเกตเห็นได้ ผู้ใช้จะรับรู้ถึงปัญหาเกี่ยวกับหน่วยความจำได้ด้วยวิธีต่อไปนี้
- ประสิทธิภาพของหน้าเว็บแย่ลงเรื่อยๆ เมื่อเวลาผ่านไป ซึ่งอาจเป็นอาการของหน่วยความจำรั่วไหล หน่วยความจำรั่วไหลคือเมื่อข้อบกพร่องในหน้าเว็บทำให้หน้าเว็บใช้หน่วยความจำมากขึ้นเรื่อยๆ เมื่อเวลาผ่านไป
- ประสิทธิภาพของหน้าเว็บไม่ดีอย่างต่อเนื่อง ซึ่งอาจเป็นอาการของหน่วยความจำบวม การใช้หน่วยความจำมากเกินไปคือเมื่อหน้าเว็บใช้หน่วยความจำมากกว่าที่จำเป็นสำหรับ Page Speed ที่เหมาะสมที่สุด
- ประสิทธิภาพของหน้าเว็บล่าช้าหรือดูเหมือนจะหยุดชั่วคราวบ่อยครั้ง ซึ่งอาจเป็นอาการของการรวบรวมขยะบ่อยครั้ง การเก็บขยะคือเมื่อเบราว์เซอร์เรียกคืนหน่วยความจำ เบราว์เซอร์จะตัดสินใจว่าจะดำเนินการนี้เมื่อใด ในระหว่างการรวบรวม การดำเนินการสคริปต์ทั้งหมดจะหยุดชั่วคราว ดังนั้นหากเบราว์เซอร์ทำการเก็บขยะจำนวนมาก การเรียกใช้สคริปต์จะหยุดชั่วคราวบ่อยครั้ง
หน่วยความจำบวม: เท่าใดจึงจะเรียกว่า "มากเกินไป"
หน่วยความจำรั่วไหลเป็นสิ่งที่ระบุได้ง่าย หากเว็บไซต์ใช้หน่วยความจำเพิ่มขึ้นเรื่อยๆ แสดงว่ามีหน่วยความจำรั่วไหล แต่การที่หน่วยความจำบวมนั้นระบุได้ยากกว่าเล็กน้อย อะไรบ้างที่ถือว่า "ใช้หน่วยความจำมากเกินไป"
เราไม่มีตัวเลขที่แน่นอน เนื่องจากอุปกรณ์และเบราว์เซอร์แต่ละรุ่นมีความสามารถแตกต่างกัน หน้าเว็บเดียวกันที่ทำงานได้อย่างราบรื่นบนสมาร์ทโฟนระดับไฮเอนด์อาจขัดข้องบนสมาร์ทโฟนระดับล่าง
สิ่งสำคัญคือการใช้โมเดล RAIL และมุ่งเน้นที่ผู้ใช้ ดูว่าอุปกรณ์ใดเป็นที่นิยมในหมู่ผู้ใช้ แล้วทดสอบหน้าเว็บในอุปกรณ์เหล่านั้น หากประสบการณ์การใช้งานไม่ดีอย่างต่อเนื่อง แสดงว่าหน้าเว็บอาจใช้หน่วยความจำเกินความสามารถของอุปกรณ์เหล่านั้น
ตรวจสอบการใช้หน่วยความจำแบบเรียลไทม์ด้วยตัวจัดการงานของ Chrome
ใช้ตัวจัดการงานของ Chrome เป็นจุดเริ่มต้นในการตรวจสอบปัญหาเกี่ยวกับหน่วยความจำ ตัวจัดการงานคือเครื่องมือตรวจสอบแบบเรียลไทม์ที่บอกให้คุณทราบว่าหน้าเว็บใช้หน่วยความจำเท่าใด
กด Shift+Esc หรือไปที่เมนูหลักของ Chrome แล้วเลือกเครื่องมือเพิ่มเติม > ตัวจัดการงานเพื่อเปิดตัวจัดการงาน

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

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

แสดงภาพหน่วยความจำรั่วไหลด้วยการบันทึกประสิทธิภาพ
นอกจากนี้ คุณยังใช้แผงประสิทธิภาพเป็นจุดเริ่มต้นอีกจุดหนึ่งในการตรวจสอบได้ด้วย แผงประสิทธิภาพช่วยให้คุณเห็นภาพการใช้หน่วยความจำของหน้าเว็บเมื่อเวลาผ่านไป
- เปิดแผงประสิทธิภาพในเครื่องมือสำหรับนักพัฒนาเว็บ
- เลือกช่องทำเครื่องหมายหน่วยความจำ
- สร้างไฟล์บันทึก
หากต้องการสาธิตการบันทึกหน่วยความจำประสิทธิภาพ ให้พิจารณาโค้ดต่อไปนี้
var x = [];
function grow() {
for (var i = 0; i < 10000; i++) {
document.body.appendChild(document.createElement('div'));
}
x.push(new Array(1000000).join('x'));
}
document.getElementById('grow').addEventListener('click', grow);
ทุกครั้งที่มีการกดปุ่มที่อ้างอิงในโค้ด ระบบจะเพิ่มโหนด div จำนวน 10,000 โหนดลงในเนื้อหาเอกสาร และพุชสตริงอักขระ x จำนวน 1 ล้านรายการลงในอาร์เรย์ x
การเรียกใช้โค้ดนี้จะสร้างการบันทึกไทม์ไลน์ดังภาพหน้าจอต่อไปนี้

ก่อนอื่น เราจะอธิบายเกี่ยวกับอินเทอร์เฟซผู้ใช้ กราฟ HEAP ในแผงภาพรวม (ใต้ NET) แสดง JS Heap แผงตัวนับจะอยู่ใต้แผงภาพรวม ที่นี่คุณจะเห็นการใช้งานหน่วยความจำที่แยกตามฮีป JS (เหมือนกับกราฟ HEAP ในแผงภาพรวม), เอกสาร, โหนด DOM, Listener และหน่วยความจำ GPU การปิดใช้ช่องทำเครื่องหมายจะซ่อนช่องทำเครื่องหมายนั้นจากกราฟ
ต่อไปนี้เป็นการวิเคราะห์โค้ดเมื่อเทียบกับภาพหน้าจอ หากดูที่ตัวนับโหนด (กราฟสีเขียว) คุณจะเห็นว่าตัวนับโหนดตรงกับโค้ดอย่างชัดเจน จำนวนโหนดจะเพิ่มขึ้นเป็นขั้นๆ คุณสามารถสันนิษฐานได้ว่าจำนวนโหนดที่เพิ่มขึ้นแต่ละครั้งคือการเรียกใช้ grow() กราฟฮีป JS (กราฟสีน้ำเงิน) ไม่ได้ตรงไปตรงมานัก เพื่อให้เป็นไปตามแนวทางปฏิบัติแนะนำ การลดลงครั้งแรกคือการบังคับให้เก็บขยะ (ทำได้โดยกดปุ่มเก็บขยะ) เมื่อการบันทึกดำเนินไป คุณจะเห็นว่าขนาดฮีป JS เพิ่มขึ้นอย่างรวดเร็ว ซึ่งเป็นเรื่องปกติและคาดการณ์ได้ เนื่องจากโค้ด JavaScript จะสร้างโหนด DOM ทุกครั้งที่คลิกปุ่ม และทำงานจำนวนมากเมื่อสร้างสตริงที่มีอักขระ 1 ล้านตัว สิ่งสำคัญที่นี่คือข้อเท็จจริงที่ว่าฮีป JS สิ้นสุดสูงกว่าที่เริ่มต้น ("จุดเริ่มต้น" ที่นี่คือจุดหลังจากที่บังคับให้เก็บขยะ) ในโลกแห่งความเป็นจริง หากคุณเห็นรูปแบบของขนาดฮีป JS หรือขนาดโหนดที่เพิ่มขึ้นนี้ อาจหมายความว่ามีหน่วยความจำรั่วไหล
ค้นพบหน่วยความจำรั่วไหลของแผนผัง DOM ที่แยกออกมาด้วยสแนปชอตฮีป
โหนด DOM จะเก็บขยะได้ก็ต่อเมื่อไม่มีการอ้างอิงจากแผนผัง DOM ของหน้าเว็บหรือโค้ด JavaScript ระบบจะถือว่าโหนด "แยกออก" เมื่อนำออกจากแผนผัง DOM แต่ JavaScript บางส่วนยังคงอ้างอิงโหนดดังกล่าวอยู่ โหนด DOM ที่ถูกปลดออกเป็นสาเหตุที่พบบ่อยของหน่วยความจำรั่วไหล ส่วนนี้จะสอนวิธีใช้เครื่องมือสร้างโปรไฟล์ฮีปของเครื่องมือสำหรับนักพัฒนาเว็บเพื่อระบุโหนดที่แยกออก
ต่อไปนี้เป็นตัวอย่างง่ายๆ ของโหนด DOM ที่แยกออก
var detachedTree;
function create() {
var ul = document.createElement('ul');
for (var i = 0; i < 10; i++) {
var li = document.createElement('li');
ul.appendChild(li);
}
detachedTree = ul;
}
document.getElementById('create').addEventListener('click', create);
การคลิกปุ่มที่อ้างอิงในโค้ดจะสร้างโหนด ul ที่มีโหนดย่อย li 10 โหนด โค้ดอ้างอิงโหนดเหล่านี้แต่ไม่มีอยู่ในแผนผัง DOM จึงถูกแยกออก
สแนปชอตฮีปเป็นวิธีหนึ่งในการระบุโหนดที่แยกออก ตามชื่อที่บอกไว้ สแนปชอตฮีปจะแสดงให้เห็นว่าหน่วยความจำมีการกระจายอย่างไรในออบเจ็กต์ JS และโหนด DOM ของหน้าเว็บ ณ จุดเวลาของสแนปชอต
หากต้องการสร้างสแนปชอต ให้เปิดเครื่องมือสำหรับนักพัฒนาเว็บ แล้วไปที่แผงหน่วยความจำ เลือกปุ่มตัวเลือกสแนปชอตฮีป แล้วกดปุ่มถ่ายสแนปชอต

ภาพรวมอาจใช้เวลาสักครู่ในการประมวลผลและโหลด เมื่อเสร็จแล้ว ให้เลือกจากแผงด้านซ้าย (ชื่อ สแนปชอตฮีป)
พิมพ์ Detached ในช่องป้อนข้อมูลตัวกรองคลาสเพื่อค้นหาแผนผัง DOM ที่แยกออก

ขยายเครื่องหมายหมวกเพื่อตรวจสอบต้นไม้ที่แยกออกมา

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

ระบุหน่วยความจำรั่วไหลในฮีป JS ด้วยไทม์ไลน์การจัดสรร
ไทม์ไลน์การจัดสรรเป็นอีกเครื่องมือหนึ่งที่ช่วยคุณติดตามการรั่วไหลของหน่วยความจำในฮีป JS ได้
ลองดูโค้ดต่อไปนี้เพื่อแสดงไทม์ไลน์การจัดสรร
var x = [];
function grow() {
x.push(new Array(1000000).join('x'));
}
document.getElementById('grow').addEventListener('click', grow);
ทุกครั้งที่มีการกดปุ่มที่อ้างอิงในโค้ด ระบบจะเพิ่มสตริงที่มีอักขระ 1 ล้านตัวลงในอาร์เรย์ x
หากต้องการบันทึกไทม์ไลน์การจัดสรร ให้เปิดเครื่องมือสำหรับนักพัฒนาเว็บ ไปที่แผงหน่วยความจำ เลือกปุ่มตัวเลือกการจัดสรรในไทม์ไลน์ กดปุ่ม บันทึก ดำเนินการที่คุณสงสัยว่าทำให้หน่วยความจำรั่วไหล แล้วกดปุ่ม หยุดบันทึกเมื่อเสร็จแล้ว
ขณะบันทึก ให้สังเกตว่ามีแถบสีน้ำเงินปรากฏในไทม์ไลน์การจัดสรรหรือไม่ ดังภาพหน้าจอต่อไปนี้

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

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

ตรวจสอบการจัดสรรหน่วยความจำตามฟังก์ชัน
ใช้ประเภทโปรไฟล์การสุ่มตัวอย่างการจัดสรรในแผงหน่วยความจำเพื่อดูการจัดสรรหน่วยความจำตามฟังก์ชัน JavaScript

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

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

ตรวจหาการจัดการหน่วยความจำที่ไม่ใช้แล้วที่เกิดขึ้นบ่อย
หากหน้าเว็บหยุดชั่วคราวบ่อยครั้ง แสดงว่าคุณอาจมีปัญหาเกี่ยวกับ Garbage Collection
คุณสามารถใช้ตัวจัดการงานของ Chrome หรือการบันทึกหน่วยความจำไทม์ไลน์เพื่อตรวจหาการเก็บขยะที่เกิดขึ้นบ่อยได้ ในตัวจัดการงาน ค่าหน่วยความจำหรือหน่วยความจำ JavaScript ที่เพิ่มขึ้นและลดลงบ่อยครั้งแสดงถึงการเก็บขยะที่เกิดขึ้นบ่อยครั้ง ในการบันทึกไทม์ไลน์ กราฟฮีป JS หรือจำนวนโหนดที่เพิ่มขึ้นและลดลงบ่อยครั้งบ่งบอกถึงการเก็บขยะที่เกิดขึ้นบ่อยครั้ง
เมื่อระบุปัญหาได้แล้ว คุณสามารถใช้การบันทึกไทม์ไลน์การจัดสรรเพื่อดูว่ามีการจัดสรรหน่วยความจำที่ใดและฟังก์ชันใดเป็นสาเหตุของการจัดสรร