สิ่งที่นักพัฒนาซอฟต์แวร์จำเป็นต้องทราบเกี่ยวกับโหมดหน่วยความจำและโหมดประหยัดพลังงานของ Chrome

Chrome 108 เปิดตัว 2 โหมดใหม่ ได้แก่ โหมดประหยัดหน่วยความจำและโหมดประหยัดพลังงาน เพื่อให้ผู้ใช้ควบคุมการใช้ทรัพยากรระบบของ Chrome ได้มากขึ้น

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

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

โหมดประหยัดหน่วยความจำ

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

เมื่อทิ้งแท็บ ชื่อและไอคอน Fav จะยังคงปรากฏในแนวแท็บ แต่หน้าจะหายไปเหมือนกับว่าแท็บปิดไปตามปกติ หากผู้ใช้กลับมาที่แท็บนั้นอีกครั้ง หน้าเว็บจะโหลดซ้ำโดยอัตโนมัติ

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

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

ตั้งแต่ Chrome 108 เป็นต้นไป การทิ้งแท็บจะกลายเป็นเรื่องที่พบได้ทั่วไปมากขึ้น เว็บไซต์จึงจำเป็นต้องจัดการกับปัญหาเหล่านี้อย่างดี

แนวทางปฏิบัติแนะนำในการจัดการการยกเลิกแท็บ

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

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

เวลาที่ดีที่สุดในการจัดเก็บสถานะผู้ใช้คือ

  • สถานะเปลี่ยนแปลงเป็นระยะๆ
  • เมื่อใดก็ตามที่แท็บอยู่ในเบื้องหลัง (เหตุการณ์ visibilitychange)

เวลาที่แย่ที่สุดในการจัดเก็บรัฐคือ:

  • ใน Callback ของเหตุการณ์ beforeunload
  • ใน Callback ของเหตุการณ์ unload

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

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

สถานะ API อายุการใช้งานของหน้าเว็บและโฟลว์เหตุการณ์ ภาพสถานะและโฟลว์เหตุการณ์ตามที่อธิบายไว้ในเอกสารนี้

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

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

let state = {};
let hasUnstoredState = false;

function storeState() {
  if (hasUnstoredState) {
    // Store `state` to localStorage or IndexedDB...
  }
  hasUnstoredState = false;
}

export function updateState(newState) {
  state = newState;
  hasUnstoredState = true;
  requestIdleCallback(storeState);
}

document.addEventListener('visibilitychange', () => {
  if (document.visibilityState === 'hidden') {
    storeState();
  }
});

ตรวจพบว่ามีการปิดแท็บ

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

if (document.wasDiscarded) {
  // The page was reloaded after a discard.
} else {
  // The page was not reloaded after a discard.
}

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

เช่น ใน Google Analytics คุณกําหนดค่าพารามิเตอร์เหตุการณ์ที่กําหนดเองได้ ซึ่งจะช่วยให้ระบุเปอร์เซ็นต์ของการดูหน้าเว็บที่มาจากการยกเลิกแท็บได้

gtag('config', 'G-XXXXXXXXXX', {
  was_discarded: document.wasDiscarded,
});

หากคุณเป็นผู้ให้บริการวิเคราะห์ คุณอาจต้องเพิ่มมิติข้อมูลนี้ลงในผลิตภัณฑ์โดยค่าเริ่มต้น

การทดสอบเว็บไซต์ในโหมดประหยัดหน่วยความจำ

คุณทดสอบวิธีจัดการทิ้งหน้าเว็บได้โดยโหลดหน้าเว็บดังกล่าวและไปที่ chrome://discards ในแท็บหรือหน้าต่างแยกต่างหาก

จาก UI ของ chrome://discards คุณสามารถค้นหาแท็บที่คุณต้องการทิ้งจากรายการ จากนั้นคลิกทิ้งอย่างเร่งด่วนจากคอลัมน์การดำเนินการ

ภาพหน้าจอ UI ของ chrome://discards ที่แสดงตำแหน่งของลิงก์เพื่อยกเลิกแท็บ

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

โปรดทราบว่าปัจจุบันยังไม่มีวิธียกเลิกแท็บโดยอัตโนมัติผ่านเครื่องมือทดสอบ เช่น Webdriver หรือ puppeteer อย่างไรก็ตาม เนื่องจากการยกเลิกและการคืนค่าแท็บนั้นแทบจะเหมือนกับการโหลดหน้าเว็บซ้ำ หากคุณทดสอบว่ามีการคืนค่าสถานะผู้ใช้แล้วหลังจากที่โหลดซ้ำในระหว่างการใช้งานของผู้ใช้ ก็น่าจะสามารถทิ้ง/คืนค่าสถานะผู้ใช้ได้เช่นกัน ความแตกต่างหลักระหว่างเหตุการณ์ 2 อย่างนี้คือเหตุการณ์ beforeunload, pagehide และ unload จะไม่เริ่มทํางานเมื่อมีการทิ้งแท็บ ตราบใดที่คุณไม่ได้อาศัยเหตุการณ์เหล่านั้นเพื่อรักษาสถานะผู้ใช้ คุณสามารถใช้การโหลดซ้ำเพื่อทดสอบลักษณะการยกเลิก/กู้คืนได้

โหมดประหยัดพลังงาน

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

โดยทั่วไปแล้ว นักพัฒนาแอปไม่จำเป็นต้องดำเนินการใดๆ เพื่อรองรับโหมดประหยัดพลังงาน CSS และ JavaScript API สำหรับภาพเคลื่อนไหว การเปลี่ยน และ requestAnimationFrame() จะปรับตามการเปลี่ยนแปลงอัตราการรีเฟรชจอแสดงผลโดยอัตโนมัติเมื่อเปิดใช้โหมดนี้

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

ตัวอย่างเช่น หากเว็บไซต์ใช้การวนซ้ำ requestAnimationFrame() และคิดว่าเวลาจะผ่านไป 16.67 มิลลิวินาทีระหว่างการเรียกกลับ ภาพเคลื่อนไหวจะทำงานช้าลง 2 เท่าเมื่อเปิดใช้โหมดประหยัดพลังงาน

โปรดทราบว่าปัญหานี้มักจะทำให้เกิดปัญหาสำหรับนักพัฒนาแอปในการคาดเดาอัตราการรีเฟรชเริ่มต้นเป็น 60 Hz สำหรับผู้ใช้ทุกราย เนื่องจากไม่เป็นเช่นนั้นในอุปกรณ์ปัจจุบันหลายเครื่อง

การวัดอัตราการรีเฟรชจอแสดงผล

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

สิ่งที่นักพัฒนาแอปใช้ได้ดีที่สุดกับ API ที่มีอยู่คือการเปรียบเทียบการประทับเวลาระหว่าง Callback ของ requestAnimationFrame() ที่ต่อเนื่องกัน แม้ว่าในกรณีส่วนใหญ่จะใช้เพื่อประมาณอัตราการรีเฟรชในเวลาที่กำหนด แต่จะไม่แจ้งให้คุณทราบเมื่ออัตราการรีเฟรชมีการเปลี่ยนแปลง ในการทำเช่นนั้น คุณจะต้องใช้งานโพล requestAnimationFrame() อย่างต่อเนื่อง ซึ่งจะทำให้ผู้ใช้ไม่เสียพลังงานหรืออายุการใช้งานแบตเตอรี่

การทดสอบเว็บไซต์ในโหมดประหยัดพลังงาน

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

หากคุณไม่มีอุปกรณ์ที่สามารถถอดปลั๊กได้ คุณสามารถเปิดใช้โหมดด้วยตนเองได้โดยทำตามขั้นตอนต่อไปนี้

  1. เปิดใช้แฟล็ก chrome://flags/#battery-saver-mode-available
  2. ไปที่ chrome://discards แล้วคลิกลิงก์สลับโหมดประหยัดแบตเตอรี่ (สำคัญ: ต้องเปิดใช้ธง #battery-saver-mode-available เพื่อให้ลิงก์ทำงาน)

ภาพหน้าจอ UI ของ chrome://discards ซึ่งแสดงตำแหน่งของลิงก์เพื่อเปิดใช้โหมดประหยัดพลังงาน

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

สรุป

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

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

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

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