Chrome 108 เปิดตัวโหมดใหม่ 2 โหมด ได้แก่ โหมดประหยัดหน่วยความจำและโหมดประหยัดพลังงาน เพื่อให้ผู้ใช้ควบคุมวิธีใช้ทรัพยากรระบบของ Chrome ได้ดียิ่งขึ้น
แม้ว่าโหมดใหม่เหล่านี้จะแสดงต่อผู้ใช้เป็นหลัก แต่ก็มีผลกระทบบางอย่างที่นักพัฒนาเว็บควรทราบ เนื่องจากอาจส่งผลต่อประสบการณ์การใช้งานเว็บไซต์
โพสต์นี้จะกล่าวถึงผลกระทบที่อาจเกิดขึ้นจากโหมดใหม่เหล่านี้และสิ่งที่นักพัฒนาเว็บทำได้เพื่อให้มั่นใจว่าผู้ใช้จะได้รับประสบการณ์การใช้งานที่ดีที่สุด
โหมดประหยัดหน่วยความจำ
เมื่อเปิดใช้โหมดการประหยัดหน่วยความจำ Chrome จะทิ้งแท็บที่ไม่ได้ใช้งานในเบื้องหลังเป็นระยะๆ ซึ่งจะช่วยเพิ่มพื้นที่หน่วยความจำให้กับแท็บที่ใช้งานอยู่และแอปพลิเคชันอื่นๆ ที่อาจทำงานอยู่ ผู้ใช้สามารถสั่งให้ Chrome ไม่ทิ้งแท็บของบางเว็บไซต์ได้ แต่การตั้งค่านี้เป็นค่ากำหนดของผู้ใช้และคุณในฐานะนักพัฒนาซอฟต์แวร์ไม่สามารถควบคุมได้
เมื่อทิ้งแท็บ ชื่อและ Favicon ของแท็บจะยังคงปรากฏในแถบแท็บ แต่หน้าเว็บจะหายไป เหมือนกับว่ามีการปิดแท็บตามปกติ หากผู้ใช้กลับมาที่แท็บนั้น ระบบจะโหลดหน้าเว็บซ้ำโดยอัตโนมัติ
สําหรับหน้าเนื้อหาล้วนๆ การทิ้งและโหลดแท็บซ้ำอาจไม่ส่งผลต่อประสบการณ์ของผู้ใช้ แต่สําหรับเว็บไซต์ที่ใช้งานง่ายและมีการโต้ตอบซึ่งมีขั้นตอนที่ซับซ้อน การโหลดซ้ำในระหว่างขั้นตอนนั้นอาจทําให้ผู้ใช้รู้สึกหงุดหงิดมากหากเว็บไซต์กู้คืนหน้าเว็บไปยังจุดที่ผู้ใช้ดูค้างไว้ไม่ได้
การทิ้งแท็บเพื่อประหยัดหน่วยความจำเป็นสิ่งที่ Chrome ทำมาหลายปีแล้ว แต่จะทำก็ต่อเมื่อระบบมีหน่วยความจำไม่เพียงพอเท่านั้น เนื่องจากเหตุการณ์นี้เกิดขึ้นค่อนข้างน้อย นักพัฒนาเว็บอาจไม่ทราบว่าเกิดปัญหานี้ขึ้น
ตั้งแต่ Chrome 108 เป็นต้นไป การทิ้งแท็บจะพบได้บ่อยขึ้น ดังนั้นเว็บไซต์จึงต้องจัดการกับเหตุการณ์เหล่านี้อย่างราบรื่น
แนวทางปฏิบัติแนะนำในการจัดการกับการทิ้งแท็บ
การทิ้งแท็บไม่ใช่ปัญหาใหม่สำหรับนักพัฒนาเว็บ ผู้ใช้สามารถโหลดหน้าเว็บซ้ำได้เสมอ ไม่ว่าจะตั้งใจหรือไม่ตั้งใจ ก่อนที่จะทํางานให้เสร็จ ดังนั้นเว็บไซต์จึงจำเป็นต้องจัดเก็บสถานะของผู้ใช้ไว้เสมอเพื่อให้สามารถกู้คืนได้หากผู้ใช้ออกจากเว็บไซต์แล้วกลับมาอีกครั้ง
สิ่งที่ควรพิจารณามากที่สุดไม่ใช่ควรจัดเก็บสถานะของผู้ใช้หรือไม่ แต่ควรพิจารณาเมื่อใดควรจัดเก็บ และนี่เป็นสิ่งที่สําคัญเนื่องจากไม่มีเหตุการณ์ใดที่เริ่มทํางานเมื่อมีการทิ้งแท็บ ดังนั้นนักพัฒนาแอปจึงไม่มีวิธีตอบสนองต่อเหตุการณ์ดังกล่าว แต่นักพัฒนาแอปต้องคาดการณ์ความเป็นไปได้นี้และเตรียมพร้อมล่วงหน้า
เวลาที่เหมาะสําหรับจัดเก็บสถานะผู้ใช้มีดังนี้
- เป็นระยะๆ เมื่อสถานะมีการเปลี่ยนแปลง
- ทุกครั้งที่แท็บทำงานอยู่เบื้องหลัง (เหตุการณ์
visibilitychange
)
เวลาที่ไม่ควรจัดเก็บสถานะมีดังนี้
- ใน Callback ของเหตุการณ์
beforeunload
- ใน Callback ของเหตุการณ์
unload
ช่วงเวลาเหล่านี้เป็นช่วงเวลาที่แย่ที่สุดในการเก็บสถานะ เนื่องจากเหตุการณ์เหล่านี้ไม่น่าเชื่อถือโดยสิ้นเชิงและไม่ทริกเกอร์ในหลายสถานการณ์ รวมถึงเมื่อมีการทิ้งแท็บ
คุณสามารถดูแผนภาพเหตุการณ์วงจรชีวิตของหน้าเว็บเพื่อดูเหตุการณ์ที่คาดว่าจะเกิดขึ้นเมื่อระบบทิ้งหน้าเว็บ ดังที่เห็นจากแผนภาพดังกล่าว แท็บอาจเปลี่ยนจากสถานะ "ซ่อน" เป็นสถานะ "ทิ้ง" โดยไม่เกิดเหตุการณ์ใดๆ
อันที่จริงแล้ว ทุกครั้งที่หน้าเว็บอยู่ในสถานะ "ซ่อน" เราไม่รับประกันว่าเหตุการณ์อื่นๆ จะเริ่มต้นขึ้นก่อนที่เบราว์เซอร์จะทิ้งหน้าเว็บหรือผู้ใช้จะปิดหน้าเว็บไป ด้วยเหตุนี้ คุณจึงควรจัดเก็บสถานะผู้ใช้ที่ไม่ได้บันทึกไว้ในเหตุการณ์ 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
คุณสามารถค้นหาแท็บที่ต้องการทิ้งจากรายการ แล้วคลิกทิ้งอย่างเร่งด่วนจากคอลัมน์การดําเนินการ
ซึ่งจะเป็นการทิ้งแท็บนั้นไปเพื่อให้คุณกลับมาดูอีกครั้งและยืนยันว่าหน้าเว็บโหลดซ้ำในสถานะเดียวกับตอนที่คุณออกจากหน้านั้น
โปรดทราบว่าปัจจุบันยังไม่มีวิธีทำให้การทิ้งแท็บเป็นแบบอัตโนมัติผ่านเครื่องมือทดสอบ เช่น Webdriver หรือ Puppeteer อย่างไรก็ตาม เนื่องจากการทิ้งและกู้คืนแท็บเกือบจะเหมือนกับการโหลดหน้าเว็บซ้ำ หากคุณทดสอบว่าระบบกู้คืนสถานะผู้ใช้หลังจากการโหลดซ้ำในช่วงกลางของเส้นทางของผู้ใช้ ก็มีความเป็นไปได้ว่าระบบจะทำงานกับการทิ้ง/กู้คืนด้วยเช่นกัน ความแตกต่างหลักระหว่าง 2 รายการนี้คือ เหตุการณ์ beforeunload
, pagehide
และ unload
จะไม่ทํางานเมื่อมีการทิ้งแท็บ ดังนั้นตราบใดที่คุณไม่ได้ใช้เหตุการณ์เหล่านั้นเพื่อเก็บสถานะผู้ใช้ไว้ คุณก็ใช้การโหลดซ้ำเพื่อทดสอบลักษณะการทิ้ง/กู้คืนได้
โหมดประหยัดพลังงาน
เมื่อเปิดใช้โหมดประหยัดพลังงาน Chrome จะประหยัดพลังงานแบตเตอรี่โดยลดอัตราการรีเฟรชของจอแสดงผล ซึ่งจะส่งผลต่อการเลื่อนและภาพเคลื่อนไหว รวมถึงอัตราเฟรมของวิดีโอ
โดยทั่วไปแล้ว นักพัฒนาแอปไม่จำเป็นต้องดำเนินการใดๆ เพื่อรองรับโหมดประหยัดพลังงาน CSS และ JavaScript API สําหรับภาพเคลื่อนไหว การเปลี่ยน และ requestAnimationFrame()
จะปรับตามการเปลี่ยนแปลงของอัตราการรีเฟรชของจอแสดงผลโดยอัตโนมัติเมื่อเปิดใช้โหมดนี้
สถานการณ์หลักที่โหมดนี้อาจทำให้เกิดปัญหาคือเมื่อเว็บไซต์ใช้ภาพเคลื่อนไหวที่ใช้ JavaScript ซึ่งใช้อัตรารีเฟรชที่เจาะจงสำหรับผู้ใช้ทุกคน
เช่น หากเว็บไซต์ใช้ requestAnimationFrame()
ลูปและสมมติว่าเวลาผ่านไป 16.67 มิลลิวินาทีระหว่างการเรียกกลับ การแสดงภาพเคลื่อนไหวจะทำงานช้าลง 2 เท่าเมื่อเปิดใช้โหมดประหยัดพลังงาน
โปรดทราบว่าปัญหานี้เกิดขึ้นมาโดยตลอดสำหรับนักพัฒนาแอปที่ถือว่าอัตราการรีเฟรชเริ่มต้นคือ 60 Hz สำหรับผู้ใช้ทุกคน เนื่องจากอุปกรณ์ในปัจจุบันจำนวนมากไม่ได้เป็นแบบนั้น
การวัดอัตราการรีเฟรชจอแสดงผล
ไม่มี Web API โดยเฉพาะสำหรับวัดอัตราการรีเฟรชของจอแสดงผล และโดยทั่วไปแล้วเราไม่แนะนำให้พยายามวัดด้วย API ปัจจุบัน
สิ่งที่นักพัฒนาแอปทำได้ดีที่สุดกับ API ที่มีอยู่คือการเปรียบเทียบการประทับเวลาระหว่างการเรียกกลับ requestAnimationFrame()
ต่อเนื่อง แม้ว่าในกรณีส่วนใหญ่ ข้อมูลนี้จะแสดงอัตราการรีเฟรชโดยประมาณ ณ เวลาหนึ่งๆ แต่จะไม่แจ้งให้คุณทราบเมื่ออัตราการรีเฟรชมีการเปลี่ยนแปลง ซึ่งคุณจะต้องทำการสำรวจ requestAnimationFrame()
อย่างต่อเนื่อง ซึ่งขัดต่อเป้าหมายในการประหยัดพลังงานหรืออายุการใช้งานแบตเตอรี่ของผู้ใช้
การทดสอบเว็บไซต์ในโหมดประหยัดพลังงาน
วิธีหนึ่งในการทดสอบเว็บไซต์ในโหมดประหยัดพลังงานคือการเปิดใช้โหมดในการตั้งค่าของ Chrome และกำหนดค่าให้ทำงานเมื่อถอดปลั๊กอุปกรณ์
หากไม่มีอุปกรณ์ที่ถอดปลั๊กได้ คุณยังเปิดใช้โหมดด้วยตนเองได้โดยทำตามขั้นตอนต่อไปนี้
- เปิดใช้การติดธง
chrome://flags/#battery-saver-mode-available
- ไปที่
chrome://discards
แล้วคลิกลิงก์เปิด/ปิดโหมดประหยัดแบตเตอรี่ (สำคัญ: คุณต้องเปิดใช้ Flag#battery-saver-mode-available
เพื่อให้ลิงก์ใช้งานได้)
เมื่อเปิดใช้แล้ว คุณจะโต้ตอบกับเว็บไซต์และยืนยันว่าทุกอย่างดูดีตามที่ควรจะเป็น เช่น ภาพเคลื่อนไหวและทรานซิชันทำงานด้วยความเร็วที่ต้องการ
สรุป
แม้ว่าโหมดประหยัดหน่วยความจำและโหมดประหยัดพลังงานของ Chrome จะเป็นฟีเจอร์ที่แสดงต่อผู้ใช้เป็นหลัก แต่ก็มีผลกระทบต่อนักพัฒนาซอฟต์แวร์ด้วย เนื่องจากอาจส่งผลเสียต่อประสบการณ์การเข้าชมเว็บไซต์หากจัดการอย่างไม่เหมาะสม
โดยทั่วไปแล้ว โหมดใหม่เหล่านี้ได้รับการออกแบบโดยคำนึงถึงแนวทางปฏิบัติแนะนำที่มีอยู่สำหรับนักพัฒนาแอป หากนักพัฒนาแอปปฏิบัติตามแนวทางปฏิบัติแนะนำสำหรับเว็บมาอย่างยาวนาน เว็บไซต์ของนักพัฒนาแอปก็ควรทำงานได้อย่างราบรื่นกับโหมดใหม่เหล่านี้
อย่างไรก็ตาม หากเว็บไซต์ของคุณมีแนวทางปฏิบัติที่ระบุไว้ในโพสต์นี้ เป็นไปได้ว่าผู้ใช้จะพบปัญหามากขึ้นเมื่อเปิดใช้โหมดทั้ง 2 นี้
ดังเช่นเคย วิธีที่ดีที่สุดในการยืนยันว่าคุณมอบประสบการณ์การใช้งานที่ยอดเยี่ยมคือทดสอบเว็บไซต์ด้วยเงื่อนไขที่ตรงกับของผู้ใช้