กรณีศึกษานี้อธิบายเวิร์กโฟลว์แบบทีละขั้นตอนในการแก้ไขข้อบกพร่องและปรับปรุง INP ใน React ที่ Trendyol ใช้โดยใช้ประโยชน์จากเครื่องมือของ Google เช่น PageSpeed Insights (PSI), Chrome DevTools และ scheduler.yield
API
องค์ประกอบสำคัญ 2 อย่างของเว็บไซต์อีคอมเมิร์ซคือหน้าข้อมูลผลิตภัณฑ์ที่แสดง (PLP) และหน้ารายละเอียดผลิตภัณฑ์ (PDP) การเข้าชมอีคอมเมิร์ซมักมาจากหน้ารายการผลิตภัณฑ์ ไม่ว่าจะผ่านแคมเปญอีเมล โซเชียลมีเดีย หรือโฆษณา ด้วยเหตุนี้ คุณจึงควรออกแบบประสบการณ์การใช้งาน PLP อย่างรอบคอบเพื่อลดเวลาที่ใช้ในการซื้อ การให้ความสำคัญกับคุณภาพประสบการณ์ของผู้ใช้เป็นสิ่งสำคัญในการประสบความสำเร็จ สิ่งพิมพ์งานวิจัย เช่น Milliseconds Make Millions ได้เผยให้เห็นถึงผลกระทบที่สำคัญของประสิทธิภาพเว็บที่มีต่อความเต็มใจในการใช้จ่ายเงินและการมีส่วนร่วมกับแบรนด์ทางออนไลน์ของผู้บริโภค
Trendyol เป็นแพลตฟอร์มอีคอมเมิร์ซที่มีลูกค้าประมาณ 30 ล้านคนและผู้ขาย 240,000 ราย ซึ่งทำให้เรากลายเป็นธุรกิจแรกในตุรกีด้วยมูลค่ากว่า 1 หมื่นล้านดอลลาร์ และเป็นหนึ่งในแพลตฟอร์มอีคอมเมิร์ซชั้นนำของโลก
เพื่อบรรลุเป้าหมายในการมอบประสบการณ์การใช้งานที่ดีที่สุดแก่ผู้ใช้ในวงกว้าง โดยยังคงความยืดหยุ่นของเนื้อหาและทำงานร่วมกับ React เวอร์ชันเก่า Trendsol ได้ให้ความสำคัญกับ Interaction to Next Paint (INP) เป็นเมตริกหลักในการปรับปรุง กรณีศึกษานี้อธิบายเส้นทางการปรับปรุง INP ของ Trendsol บน PLP ทำให้ INP ลดลง 50% และ เมตริกธุรกิจในผลการค้นหาเพิ่มขึ้น 1%
กระบวนการตรวจสอบ INP ของ Trendsol
INP วัดการตอบสนองของเว็บไซต์ต่อข้อมูลจากผู้ใช้ INP ที่ดีบ่งชี้ว่าเบราว์เซอร์สามารถตอบสนองต่อข้อมูลจากผู้ใช้ทั้งหมดได้อย่างรวดเร็วและมีความเสถียร และเป็นตัวแทนของหน้าเว็บใหม่ ซึ่งเป็นองค์ประกอบสำคัญที่ช่วยให้ผู้ใช้ได้รับประสบการณ์ที่ดี
เส้นทางการพัฒนา INP ของ Trendsol ใน PLP เริ่มด้วยการวิเคราะห์ประสบการณ์ของผู้ใช้อย่างละเอียดก่อนที่จะมีการปรับปรุงใดๆ จากรายงานของ PSI ประสบการณ์ของผู้ใช้จริงของ PLP มี INP อยู่ที่ 963 มิลลิวินาทีในอุปกรณ์เคลื่อนที่ ดังที่แสดงในรูปถัดไป
เจ้าของเว็บไซต์ควรตั้งเป้าหมาย INP ที่ต่ำกว่าหรือ 200 มิลลิวินาที ซึ่งหมายความว่าในขณะนั้น INP ของ Trendsol อยู่ในช่วง "ต่ำ" เพื่อให้มีการตอบสนองที่ดี
โชคดีที่ PSI ให้ข้อมูลทั้ง 2 แบบสำหรับหน้าที่รวมอยู่ในรายงานประสบการณ์ของผู้ใช้ Chrome (CrUX) และข้อมูลการวินิจฉัยในห้องทดลองโดยละเอียด เมื่อดูข้อมูลห้องทดลอง การตรวจสอบเวลาดำเนินการ JavaScript ของ Lighthouse แนะนำว่าสคริปต์ search-result-v2
ใช้เวลาอยู่ในเทรดหลักนานกว่าสคริปต์อื่นๆ ในหน้าเว็บ
ในการระบุปัญหาคอขวดในชีวิตจริง เราใช้แผงประสิทธิภาพในเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome เพื่อแก้ปัญหาเกี่ยวกับ PLP และระบุแหล่งที่มาของปัญหา การจำลองประสิทธิภาพของอุปกรณ์เคลื่อนที่โดยชะลอการทำงานของ CPU ลง 4 เท่าใน Chrome DevTools เผยให้เห็นงานที่มีความยาว 700-900 มิลลิวินาทีในเทรดหลัก หากเทรดหลักมีภาระงานอื่นๆ เป็นเวลานานกว่า 50 มิลลิวินาที ระบบอาจตอบกลับข้อมูลจากผู้ใช้ได้ทันเวลา ซึ่งส่งผลให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ไม่ดี
งานที่ใช้เวลานานที่สุดเกิดจากการเรียกกลับของ Intersection Observer API ในสคริปต์ผลการค้นหาภายในคอมโพเนนต์ React ในจุดนี้ เราเริ่มแยกงานที่ยาวๆ ออกเป็นส่วนเล็กๆ เพื่อให้เบราว์เซอร์มีโอกาสมากขึ้นในการตอบสนองต่องานที่มีความสำคัญสูงกว่า ซึ่งรวมถึงการโต้ตอบของผู้ใช้ด้วย
เราพบว่าการใช้การดำเนินการ setState
ซึ่งทริกเกอร์การแสดงผล React ภายในโค้ดเรียกกลับ Intersection Observer จะมีค่าใช้จ่ายสูง ซึ่งอาจก่อให้เกิดปัญหาสําหรับอุปกรณ์ระดับล่างเนื่องจากการใช้งานเทรดหลักนานเกินไป
วิธีหนึ่งที่นักพัฒนาซอฟต์แวร์ใช้แบ่งงานออกเป็นงานย่อยๆ จะต้องเกี่ยวข้องกับ setTimeout
เราใช้เทคนิคนี้เพื่อเลื่อนการดำเนินการการเรียกใช้ setState
เป็นงานที่แยกต่างหาก แม้ว่า setTimeout
จะอนุญาตการเลื่อนการดำเนินการ JavaScript แต่ไม่ได้ให้การควบคุมลำดับความสำคัญใดๆ วิธีนี้ช่วยให้เราเข้าร่วมช่วงทดลองใช้จากต้นทาง scheduler.yield
เพื่อรับประกันว่าการดำเนินการของสคริปต์จะดำเนินไปอย่างต่อเนื่องหลังจากกลับมาที่เทรดหลัก
/*
* Yielding method using scheduler.yield, falling back to setTimeout:
*/
async function yieldToMain() {
if('scheduler' in window && 'yield' in scheduler) {
return await scheduler.yield();
}
return new Promise(resolve => {
setTimeout(resolve, 0);
});
}
/*
* Yielding to the main thread before changing the state of the component:
*/
const observer = new IntersectionObserver((entries) => {
entries.forEach(handleIntersection);
const maxNumberOfEntries = Math.max(...this.intersectingEntries);
if (Number.isFinite(maxNumberOfEntries)) {
await this.yieldToMain();
this.setState({ count: maxNumberOfEntries });
}
}, { threshold: 0.5 });
การเพิ่มวิธีการให้ผลตอบแทนนี้ลงในโค้ด PLP ส่งผลให้มี INP ที่ดีขึ้นได้ เนื่องจากงานหลักที่ยาวนี้ได้แบ่งออกเป็นชุดย่อยๆ ซึ่งทำให้มีงานที่มีลำดับความสำคัญสูงกว่า เช่น การโต้ตอบของผู้ใช้และงานการแสดงผลในลำดับต่อๆ ไป ให้เกิดขึ้นเร็วกว่าที่ควรจะเป็น
โปรดทราบว่า Trendsol ใช้เฟรมเวิร์กของ PuzzleJs ในการใช้งานสถาปัตยกรรมแบบไมโครฟรอนท์เอนด์โดยใช้ React v16.9.0 เมื่อใช้ React 18 ประสิทธิภาพจะมีประสิทธิภาพเท่าๆ เดิม แต่ได้จากหลายสาเหตุทำให้ Insightsol อัปเกรดไม่ได้ในขณะนี้
ผลการค้นหาธุรกิจ
ในการวัดผลกระทบของการปรับปรุง INP ที่นำไปใช้ เราได้ทำการทดสอบ A/B เพื่อดูว่าเมตริกธุรกิจได้รับผลกระทบอย่างไร โดยรวมแล้ว การเปลี่ยนแปลง PLP ของเรามีการปรับปรุงอย่างมาก โดยทำให้ INP ลดลง 50% และอัตราการคลิกผ่านเพิ่มขึ้น 1% จากหน้ารายละเอียดผลิตภัณฑ์ต่อเซสชันผู้ใช้ ในรูปต่อไปนี้ คุณจะเห็นได้ว่า INP มีประสิทธิภาพดีขึ้นใน PLP อย่างไรบ้างเมื่อเวลาผ่านไป
บทสรุป
การเพิ่มประสิทธิภาพ INP เป็นกระบวนการที่ซับซ้อนและมีการทำซ้ำ แต่สามารถทำให้ง่ายขึ้นด้วยเวิร์กโฟลว์ที่ชัดเจน วิธีง่ายๆ ในการแก้ไขข้อบกพร่องและปรับปรุง INP ของเว็บไซต์จะขึ้นอยู่กับว่าคุณกำลังรวบรวมข้อมูลภาคสนามของคุณเองหรือไม่ หากไม่เป็นเช่นนั้น PSI และ Lighthouse ก็เป็นจุดเริ่มต้นที่ดี เมื่อระบุหน้าที่มีปัญหาได้แล้ว คุณสามารถใช้เครื่องมือสำหรับนักพัฒนาเว็บเพื่อเจาะลึกขึ้นและจำลองปัญหา
การตอบสนองต่อเทรดหลักเป็นครั้งคราวเพื่อให้เบราว์เซอร์มีโอกาสในการทำงานที่เร่งด่วนมากขึ้นจะทำให้เว็บไซต์ของคุณตอบสนองได้ดีขึ้น ซึ่งทำให้ลูกค้าได้รับประสบการณ์ของผู้ใช้ที่ดีขึ้น API การตั้งเวลาใหม่อย่าง scheduler.yield()
ช่วยให้งานนี้ง่ายขึ้น
ขอขอบคุณเป็นพิเศษสำหรับ Jeremy Wagner, Barry Pollard และ Houssein Djirdeh จาก Google และทีมวิศวกรของTrendol ที่มีส่วนร่วมในงานนี้