JavaScript มักทำให้เกิดการเปลี่ยนแปลงภาพ บางครั้งก็เป็นเพราะการปรับแต่งรูปแบบโดยตรง และบางครั้งก็เป็นการคำนวณที่ส่งผลให้เกิดการเปลี่ยนแปลงด้านการมองเห็น เช่น การค้นหาหรือการจัดเรียงข้อมูล JavaScript ที่มีเวลาไม่เหมาะสมหรือใช้เวลานานเป็นสาเหตุที่พบบ่อยของปัญหาด้านประสิทธิภาพ คุณควรหาวิธีลดผลกระทบให้เหลือน้อยที่สุดเท่าที่ทำได้
JavaScript มักทำให้เกิดการเปลี่ยนแปลงภาพ บางครั้งก็เป็นเช่นนั้น ผ่านการปรับแต่งสไตล์ และบางครั้งก็เป็นการคำนวณ ส่งผลให้เกิดการเปลี่ยนแปลงด้านรูปลักษณ์ เช่น การค้นหาหรือการจัดเรียงข้อมูล ไม่ตรงจังหวะ หรือ JavaScript ที่ทำงานเป็นเวลานานเป็นสาเหตุที่พบบ่อยของปัญหาด้านประสิทธิภาพ คุณควรหาวิธีลดผลกระทบให้เหลือน้อยที่สุดเท่าที่ทำได้
การทำโปรไฟล์ประสิทธิภาพของ JavaScript อาจเป็นศิลปะ เพราะ JavaScript ที่คุณเขียนนั้น ไม่เหมือนกับโค้ดที่เรียกใช้จริง เบราว์เซอร์สมัยใหม่ใช้คอมไพเลอร์ JIT ในทุกรูปแบบ ในการเพิ่มประสิทธิภาพและกลเม็ดเคล็ดลับ ที่จะช่วยให้คุณสามารถดำเนินการได้อย่างรวดเร็วที่สุด เปลี่ยนแปลงพลวัตของโค้ดได้อย่างมาก
อย่างไรก็ตาม ยังมีสิ่งหนึ่งที่คุณสามารถทำได้เพื่อช่วยให้แอปของคุณทำงาน JavaScript ได้ดี
สรุป
- หลีกเลี่ยง setTimeout หรือ setInterval สำหรับการอัปเดตภาพ ให้ใช้ requestAnimationFrame แทนเสมอ
- ย้าย JavaScript ที่ใช้งานมานานออกจากเทรดหลักไปยัง Web Workers
- ใช้ไมโครงานเพื่อทำการเปลี่ยนแปลง DOM ในหลายเฟรม
- ใช้ไทม์ไลน์และเครื่องมือสร้างโปรไฟล์ JavaScript ของ Chrome DevTools เพื่อประเมินผลกระทบของ JavaScript
ใช้ requestAnimationFrame
เพื่อดูการเปลี่ยนแปลงภาพ
เมื่อมีการเปลี่ยนแปลงภาพบนหน้าจอ
คุณก็ต้องทำงานให้ถูกเวลา
เบราว์เซอร์ซึ่งอยู่ตรงจุดเริ่มต้นของเฟรม วิธีเดียวที่จะทำให้มั่นใจได้ว่า JavaScript ของคุณ
จะทํางานเมื่อเริ่มต้นเฟรมคือใช้ requestAnimationFrame
/**
* If run as a requestAnimationFrame callback, this
* will be run at the start of the frame.
*/
function updateScreen(time) {
// Make visual updates here.
}
requestAnimationFrame(updateScreen);
เฟรมเวิร์กหรือตัวอย่างอาจใช้ setTimeout
หรือ setInterval
เพื่อทำการเปลี่ยนแปลงภาพ เช่น ภาพเคลื่อนไหว
แต่ปัญหาก็คือ Callback จะทำงานที่บางจุดในเฟรม ซึ่งน่าจะเป็น
ในช่วงท้าย ซึ่งมักจะส่งผลให้เราพลาดเฟรม ซึ่งส่งผลให้เกิดการกระตุก
![setTimeout ทำให้เบราว์เซอร์ข้ามเฟรม](https://web.developers.google.cn/static/articles/optimize-javascript-execution/image/settimeout-causing-brows-6424030c04e02.jpg?authuser=5&hl=th)
อันที่จริง jQuery เคยใช้ setTimeout
สำหรับลักษณะการทำงานของ animate
เปลี่ยนเป็นใช้
requestAnimationFrame
ในเวอร์ชัน 3
ถ้าคุณใช้ jQuery รุ่นเก่า คุณสามารถ
แพตช์ให้ใช้ requestAnimationFrame
ซึ่งแนะนำอย่างยิ่ง
ลดความซับซ้อนหรือใช้ Web Workers
JavaScript ทำงานบนเทรดหลักของเบราว์เซอร์ โดยอยู่ข้างๆ การคำนวณรูปแบบ เลย์เอาต์ และใน สีต่างๆ ได้หลายเคส หาก JavaScript ทำงานเป็นเวลานาน JavaScript จะบล็อกงานอื่นๆ เหล่านี้ ซึ่งอาจทำให้พลาดเฟรม
คุณควรใช้กลยุทธ์เกี่ยวกับเวลาที่ JavaScript ทำงานและระยะเวลา ตัวอย่างเช่น หากคุณอยู่ใน ภาพเคลื่อนไหวอย่างเช่นการเลื่อน คุณควรทำให้ JavaScript เป็นไปใน ภูมิภาค 3-4 มิลลิวินาที หากใช้เวลานานกว่านั้นและคุณอาจใช้เวลานานเกินไป หากคุณไม่ได้ใช้งาน คุณก็จะผ่อนคลายมากขึ้นเกี่ยวกับเวลาที่ใช้ไปได้
ในหลายกรณี คุณสามารถย้ายงานด้านการคำนวณทั้งหมดไปยัง Web Worker เช่น ในกรณีที่ไม่ต้องใช้การเข้าถึง DOM การบิดเบือนหรือการส่งผ่านข้อมูล เช่น การจัดเรียงหรือค้นหา มักจะเหมาะกับโมเดลนี้ เช่น การโหลดและการสร้างโมเดล
var dataSortWorker = new Worker("sort-worker.js");
dataSortWorker.postMesssage(dataToSort);
// The main thread is now free to continue working on other things...
dataSortWorker.addEventListener('message', function(evt) {
var sortedData = evt.data;
// Update data on screen...
});
งานบางอย่างอาจไม่เหมาะกับโมเดลนี้: Web Workers ไม่มีสิทธิ์เข้าถึง DOM ในกรณีที่งานของคุณต้องอยู่ในเทรดหลัก ให้พิจารณาวิธีการแบบกลุ่มที่คุณแบ่งกลุ่มงานขนาดใหญ่ออกเป็นงานขนาดเล็กแต่ละงาน ซึ่งใช้เวลาไม่เกิน 2-3 มิลลิวินาที และทำงานภายในเครื่องจัดการ requestAnimationFrame
ในแต่ละเฟรม
วิธีนี้จะมีผลที่ตามมาจาก UX และ UI ดังนั้นคุณจะต้องตรวจสอบว่าผู้ใช้ทราบ ว่าระบบกำลังประมวลผลงาน โดยจะใช้ตัวบ่งชี้ความคืบหน้าหรือสัญญาณบอกสถานะกิจกรรมก็ได้ ไม่ว่าในกรณีใดก็ตาม วิธีนี้ทำให้เทรดหลักของแอปใช้งานได้ฟรี ทำให้เทรดหลักตอบสนองต่อ การโต้ตอบของผู้ใช้
ศึกษา "ภาษีเฟรม" ของ JavaScript
เมื่อประเมินเฟรมเวิร์ก ไลบรารี หรือโค้ดของคุณเอง คุณต้องประเมิน ค่าใช้จ่ายในการเรียกใช้โค้ด JavaScript แบบเฟรมต่อเฟรม นี่คือ โดยเฉพาะอย่างยิ่งเมื่อทำงาน ภาพเคลื่อนไหวที่สำคัญต่อประสิทธิภาพ การเปลี่ยนหรือการเลื่อน
แผงประสิทธิภาพของ Chrome DevTools เป็นวิธีที่ดีที่สุดในการวัด ค่าใช้จ่ายของ JavaScript โดยทั่วไปคุณจะได้รับระเบียนระดับต่ำดังนี้
![การบันทึกประสิทธิภาพในเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome](https://web.developers.google.cn/static/articles/optimize-javascript-execution/image/a-performance-recording-ed012f2de06f6.png?authuser=5&hl=th)
ส่วนหลักจะแสดงแผนภูมิชั่วคราวของการเรียก JavaScript เพื่อให้คุณ สามารถวิเคราะห์ได้อย่างแน่ชัดว่าฟังก์ชันใดถูกเรียกใช้ และใช้เวลานานเท่าใด
ข้อมูลนี้จะช่วยคุณประเมินผลกระทบด้านประสิทธิภาพของ JavaScript ในแอปพลิเคชันของคุณ และเริ่มค้นหาและแก้ไขฮอตสปอตที่ ใช้เวลานานเกินไปในการดำเนินการ ดังที่กล่าวไว้ก่อนหน้านี้ คุณควรหา เพื่อนำ JavaScript ที่ทำงานเป็นเวลานานออก หรือหากไม่ได้ผล ให้ย้าย JavaScript Web Worker ทำให้เทรดหลักว่างมากขึ้นเพื่อทำงานอื่นๆ ต่อ
โปรดดูเริ่มต้นใช้งานการวิเคราะห์ประสิทธิภาพรันไทม์เพื่อดูวิธีใช้ แผงประสิทธิภาพ
หลีกเลี่ยงการเพิ่มประสิทธิภาพ JavaScript ของคุณเพียงเล็กน้อย
คงจะดีไม่น้อยที่ได้ทราบว่าเบราว์เซอร์สามารถทำงานกับสิ่งต่างๆ หนึ่งเวอร์ชันได้เร็วกว่า 100 เท่า
อีกอย่างคือการขอ offsetTop
ขององค์ประกอบนั้นเร็วกว่าการประมวลผล
getBoundingClientRect()
แต่ก็เพื่อเกือบตลอดเวลา คุณจะเรียกเฉพาะฟังก์ชันอย่างเช่น
แค่จำนวนน้อยๆ ต่อเฟรม ดังนั้น โดยทั่วไปแล้วจึงต้องสูญเปล่า ความพยายามที่จะโฟกัสที่แง่มุมนี้
ประสิทธิภาพของ JavaScript โดยทั่วไปแล้ว คุณจะบันทึกได้เป็นเศษส่วนของมิลลิวินาทีเท่านั้น
ถ้าคุณสร้างเกม หรือแอปพลิเคชันหนึ่งที่มีราคาแพงสำหรับการคำนวณ ก็มีโอกาสสูงเป็นพิเศษ ตามคำแนะนำนี้ เนื่องจากโดยปกติแล้วคุณจะนำระบบคำนวณจำนวนมากมาใส่ในเฟรมเดียว เหมือนว่าทุกอย่างจะช่วยได้
กล่าวโดยสรุปคือ คุณควรระมัดระวังการเพิ่มประสิทธิภาพแบบไมโคร เพราะมักไม่แมปกับ ของแอปพลิเคชันที่คุณกำลังสร้างอยู่