ดูวิธีค้นหาการโต้ตอบที่ช้าในข้อมูลภาคสนามของเว็บไซต์ เพื่อให้คุณเห็นโอกาสในการปรับปรุงการโต้ตอบกับ Next Paint
ข้อมูลภาคสนามคือข้อมูลที่บอกว่าผู้ใช้จริงได้รับประสบการณ์จากเว็บไซต์ของคุณอย่างไร ซึ่งจะช่วยให้คุณพบปัญหาที่ไม่พบในข้อมูลในห้องทดลองเพียงอย่างเดียว ในส่วนของ Interaction to Next Paint (INP) ข้อมูลภาคสนามมีความสําคัญอย่างยิ่งในการระบุการโต้ตอบที่ช้า และให้เบาะแสสําคัญที่จะช่วยคุณแก้ไข
ในคู่มือนี้ คุณจะได้เรียนรู้วิธีประเมิน INP ของเว็บไซต์อย่างรวดเร็วโดยใช้ข้อมูลภาคสนามจากรายงานประสบการณ์ของผู้ใช้ Chrome (CrUX) เพื่อดูว่าเว็บไซต์มีปัญหาเกี่ยวกับ INP หรือไม่ จากนั้นคุณจะได้เรียนรู้วิธีใช้การสร้างการระบุแหล่งที่มาของไลบรารี JavaScript ของ Web Vitals และข้อมูลเชิงลึกใหม่ที่ได้จาก Long Animation Frames API (LoAF) เพื่อรวบรวมและตีความข้อมูลภาคสนามสำหรับการโต้ตอบที่ช้าในเว็บไซต์
เริ่มต้นด้วย CrUX เพื่อประเมิน INP ของเว็บไซต์
หากคุณไม่ได้รวบรวมข้อมูลภาคสนามจากผู้ใช้เว็บไซต์ CrUX อาจเป็นจุดเริ่มต้นที่ดี CrUX จะรวบรวมข้อมูลภาคสนามจากผู้ใช้ Chrome จริงที่เลือกส่งข้อมูลการวัดและส่งข้อมูล
ข้อมูล CrUX จะปรากฏในส่วนต่างๆ และขึ้นอยู่กับขอบเขตของข้อมูลที่คุณกำลังมองหา CrUX สามารถให้ข้อมูลเกี่ยวกับ INP และ Core Web Vitals อื่นๆ สําหรับสิ่งต่อไปนี้
- หน้าเว็บแต่ละหน้าและทั้งต้นทางโดยใช้ PageSpeed Insights
- ประเภทของหน้าเว็บ ตัวอย่างเช่น เว็บไซต์อีคอมเมิร์ซจำนวนมากมีประเภทหน้าผลิตภัณฑ์โดยละเอียดและหน้าผลิตภัณฑ์ที่แสดง คุณดูข้อมูล CrUX สำหรับประเภทหน้าเว็บที่ไม่ซ้ำกันได้ใน Search Console
คุณสามารถป้อน URL ของเว็บไซต์ใน PageSpeed Insights เพื่อเริ่มต้นใช้งาน เมื่อป้อน URL แล้ว ระบบจะแสดงข้อมูลภาคสนามของ URL นั้น (หากมี) สำหรับเมตริกหลายรายการ รวมถึง INP นอกจากนี้ คุณยังใช้ปุ่มเปิด/ปิดเพื่อตรวจสอบค่า INP สำหรับมิติข้อมูลอุปกรณ์เคลื่อนที่และเดสก์ท็อปได้ด้วย

ข้อมูลนี้มีประโยชน์เนื่องจากจะบอกให้คุณทราบว่ามีปัญหาหรือไม่ แต่ CrUX ไม่สามารถบอกคุณได้ว่าอะไรเป็นสาเหตุของปัญหา มีโซลูชันการตรวจสอบผู้ใช้จริง (RUM) มากมายที่จะช่วยคุณรวบรวมข้อมูลภาคสนามของคุณเองจากผู้ใช้เว็บไซต์เพื่อช่วยตอบคำถามดังกล่าว และตัวเลือกหนึ่งคือการรวบรวมข้อมูลภาคสนามด้วยตนเองโดยใช้ไลบรารี JavaScript ของ Web Vitals
รวบรวมข้อมูลภาคสนามด้วยไลบรารี web-vitals
JavaScript
web-vitals
ไลบรารี JavaScript คือสคริปต์ที่คุณโหลดในเว็บไซต์เพื่อรวบรวมข้อมูลฟิลด์จากผู้ใช้เว็บไซต์ คุณสามารถใช้เพื่อบันทึกเมตริกต่างๆ ได้ รวมถึง INP ในเบราว์เซอร์ที่รองรับ
คุณใช้การสร้างไลบรารี web-vitals มาตรฐานเพื่อรับข้อมูล INP พื้นฐานจากผู้ใช้ในฟิลด์ได้โดยทำดังนี้
import {onINP} from 'web-vitals';
onINP(({name, value, rating}) => {
console.log(name); // 'INP'
console.log(value); // 512
console.log(rating); // 'poor'
});
หากต้องการวิเคราะห์ข้อมูลฟิลด์จากผู้ใช้ คุณจะต้องส่งข้อมูลนี้ไปยังที่ใดที่หนึ่ง โดยทำดังนี้
import {onINP} from 'web-vitals';
onINP(({name, value, rating}) => {
// Prepare JSON to be sent for collection. Note that
// you can add anything else you'd want to collect here:
const body = JSON.stringify({name, value, rating});
// Use `sendBeacon` to send data to an analytics endpoint.
// For Google Analytics, see https://github.com/GoogleChrome/web-vitals#send-the-results-to-google-analytics.
navigator.sendBeacon('/analytics', body);
});
อย่างไรก็ตาม ข้อมูลนี้เพียงอย่างเดียวไม่ได้บอกอะไรคุณมากไปกว่า CrUX ไลบรารี web-vitals เวอร์ชันการระบุแหล่งที่มาจึงเข้ามามีบทบาท
พัฒนาไปอีกขั้นด้วยการสร้างการระบุแหล่งที่มาของไลบรารี web-vitals
การสร้างการระบุแหล่งที่มาของไลบรารี web-vitals จะแสดงข้อมูลเพิ่มเติมที่คุณได้รับจากผู้ใช้ในภาคสนามเพื่อช่วยให้คุณแก้ปัญหาการโต้ตอบที่เป็นปัญหาซึ่งส่งผลต่อ INP ของเว็บไซต์ได้ดียิ่งขึ้น คุณเข้าถึงข้อมูลนี้ได้ผ่านออบเจ็กต์ attribution
ที่แสดงในเมธอด onINP()
ของไลบรารี
import {onINP} from 'web-vitals/attribution';
onINP(({name, value, rating, attribution}) => {
console.log(name); // 'INP'
console.log(value); // 56
console.log(rating); // 'good'
console.log(attribution); // Attribution data object
});

นอกเหนือจาก INP ของหน้าเว็บแล้ว การสร้างการระบุแหล่งที่มายังให้ข้อมูลมากมายที่คุณใช้เพื่อช่วยทําความเข้าใจสาเหตุของการโต้ตอบที่ช้าได้ รวมถึงส่วนของการโต้ตอบที่คุณควรให้ความสนใจ ซึ่งจะช่วยตอบคำถามสำคัญ เช่น
- "ผู้ใช้โต้ตอบกับหน้าเว็บขณะที่กำลังโหลดหรือไม่"
- "ตัวแฮนเดิลเหตุการณ์ของการโต้ตอบทํางานเป็นเวลานานหรือไม่"
- "โค้ดตัวแฮนเดิลเหตุการณ์การโต้ตอบเริ่มทำงานช้าหรือไม่ หากใช่ มีอะไรเกิดขึ้นอีกบ้างในเทรดหลักในเวลานั้น"
- "การโต้ตอบทำให้เกิดงานการแสดงผลจำนวนมากที่ทำให้เฟรมถัดไปแสดงผลช้าลงไหม"
ตารางต่อไปนี้แสดงข้อมูลการระบุแหล่งที่มาพื้นฐานบางส่วนที่คุณได้รับจากไลบรารี ซึ่งจะช่วยให้คุณทราบสาเหตุระดับสูงบางประการของการโต้ตอบที่ช้าในเว็บไซต์
attribution คีย์ออบเจ็กต์
|
ข้อมูล |
---|---|
interactionTarget
|
ตัวเลือก CSS ที่ชี้ไปยังองค์ประกอบที่สร้างค่า INP ของหน้าเว็บ เช่น button#save
|
interactionType
|
ประเภทของการโต้ตอบ ไม่ว่าจะเป็นจากการคลิก การแตะ หรือการป้อนข้อมูลด้วยแป้นพิมพ์ |
inputDelay *
|
ความล่าช้าของอินพุตของการโต้ตอบ |
processingDuration *
|
เวลาตั้งแต่ที่เครื่องมือฟังเหตุการณ์แรกเริ่มทํางานเพื่อตอบสนองต่อการโต้ตอบของผู้ใช้จนถึงเวลาที่การประมวลผลเครื่องมือฟังเหตุการณ์ทั้งหมดเสร็จสิ้น |
presentationDelay *
|
การหน่วงเวลาในการนำเสนอของการโต้ตอบ ซึ่งเกิดขึ้นตั้งแต่เวลาที่ตัวแฮนเดิลเหตุการณ์เสร็จสิ้นจนถึงเวลาที่วาดเฟรมถัดไป |
longAnimationFrameEntries *
|
รายการจาก LoAF ที่เชื่อมโยงกับการโต้ตอบ ดูข้อมูลเพิ่มเติมได้ที่ส่วนถัดไป |
ตั้งแต่เวอร์ชัน 4 ของไลบรารี web-vitals คุณจะได้รับข้อมูลเชิงลึกที่ละเอียดยิ่งขึ้นเกี่ยวกับการโต้ตอบที่มีปัญหาผ่านข้อมูลที่ได้จากการวิเคราะห์ระยะ INP (เวลาในการตอบสนองต่ออินพุต ระยะเวลาในการประมวลผล และเวลาในการนำเสนอ) และ Long Animation Frames API (LoAF)
Long Animation Frames API (LoAF)
การแก้ไขข้อบกพร่องของการโต้ตอบโดยใช้ข้อมูลฟิลด์เป็นงานที่ท้าทาย แต่ตอนนี้คุณสามารถรับข้อมูลเชิงลึกที่ดีขึ้นเกี่ยวกับสาเหตุที่อยู่เบื้องหลังการโต้ตอบที่ช้าได้แล้วด้วยข้อมูลจาก LoAF เนื่องจาก LoAF จะแสดงการจับเวลาแบบละเอียดและข้อมูลอื่นๆ จำนวนมากที่คุณใช้เพื่อระบุสาเหตุที่แน่ชัดได้ และที่สำคัญกว่านั้นคือระบุตำแหน่งที่มาของปัญหาในโค้ดของเว็บไซต์ได้
การสร้างการระบุแหล่งที่มาของไลบรารี web-vitals จะแสดงอาร์เรย์ของรายการ LoAF ภายใต้คีย์ longAnimationFrameEntries
ของออบเจ็กต์ attribution
ตารางต่อไปนี้แสดงข้อมูลสำคัญบางส่วนที่คุณจะเห็นในแต่ละรายการของ LoAF
คีย์ออบเจ็กต์ของรายการ LoAF | ข้อมูล |
---|---|
duration
|
ระยะเวลาของเฟรมของภาพเคลื่อนไหวที่ใช้เวลานานจนถึงเวลาที่เลย์เอาต์เสร็จสมบูรณ์ แต่ไม่รวมการวาดและการคอมโพสิต |
blockingDuration
|
ระยะเวลาทั้งหมดในเฟรมที่เบราว์เซอร์ตอบสนองได้อย่างรวดเร็วไม่ได้เนื่องจากมีงานที่ใช้เวลานาน เวลาที่ถูกบล็อกนี้อาจรวมถึงงานที่ใช้เวลานานซึ่งเรียกใช้ JavaScript รวมถึงงานการแสดงผลที่ใช้เวลานานในเฟรมต่อๆ ไป |
firstUIEventTimestamp
|
การประทับเวลาของเวลาที่จัดคิวเหตุการณ์ในระหว่างเฟรม มีประโยชน์ในการพิจารณาความล่าช้าของอินพุตของการโต้ตอบ |
startTime
|
การประทับเวลาเริ่มต้นของเฟรม |
renderStart
|
เมื่อเริ่มงานการแสดงผลสำหรับเฟรม ซึ่งรวมถึงการเรียกกลับ requestAnimationFrame (และ ResizeObserver หากมี) แต่ก่อนที่จะเริ่มงานด้านสไตล์/เลย์เอาต์
|
styleAndLayoutStart
|
เมื่อมีการทำงานด้านสไตล์/เลย์เอาต์ในเฟรม อาจมีประโยชน์ในการพิจารณาความยาวของงานจัดรูปแบบ/เลย์เอาต์เมื่อพิจารณาการประทับเวลาอื่นๆ ที่มี |
scripts
|
อาร์เรย์ของรายการที่มีข้อมูลการระบุแหล่งที่มาของสคริปต์ซึ่งส่งผลต่อ INP ของหน้าเว็บ |

blockingDuration
ออก)
ข้อมูลทั้งหมดนี้จะบอกคุณได้มากมายเกี่ยวกับสาเหตุที่ทำให้การโต้ตอบช้า แต่scripts
อาร์เรย์ที่รายการ LoAF แสดงควรเป็นสิ่งที่น่าสนใจเป็นพิเศษ
คีย์ออบเจ็กต์การระบุแหล่งที่มาของสคริปต์ | ข้อมูล |
---|---|
invoker
|
ผู้เรียกใช้ ซึ่งอาจแตกต่างกันไปตามประเภทผู้เรียกใช้ที่อธิบายไว้ในแถวถัดไป ตัวอย่างของ Invoker อาจเป็นค่า เช่น 'IMG#id.onload' , 'Window.requestAnimationFrame' หรือ 'Response.json.then' |
invokerType
|
ประเภทของ Invoker อาจเป็น 'user-callback' , 'event-listener' , 'resolve-promise' , 'reject-promise' , 'classic-script' หรือ 'module-script'
|
sourceURL
|
URL ของสคริปต์ที่เฟรมของภาพเคลื่อนไหวที่ใช้เวลานานมาจาก |
sourceCharPosition
|
ตำแหน่งอักขระในสคริปต์ที่ระบุโดย sourceURL
|
sourceFunctionName
|
ชื่อของฟังก์ชันในสคริปต์ที่ระบุ |
แต่ละรายการในอาร์เรย์นี้มีข้อมูลที่แสดงในตารางนี้ ซึ่งจะให้ข้อมูลเกี่ยวกับสคริปต์ที่ทำให้เกิดการโต้ตอบที่ช้า และวิธีที่สคริปต์ทำให้เกิดการโต้ตอบที่ช้า
วัดและระบุสาเหตุที่พบบ่อยที่อยู่เบื้องหลังการโต้ตอบที่ช้า
เพื่อให้คุณเห็นภาพว่าอาจใช้ข้อมูลนี้อย่างไร คู่มือนี้จะอธิบายวิธีใช้ข้อมูล LoAF ที่แสดงในweb-vitals
ไลบรารีเพื่อระบุสาเหตุบางอย่างที่อยู่เบื้องหลังการโต้ตอบที่ช้า
ระยะเวลาในการประมวลผลนาน
ระยะเวลาการประมวลผลของการโต้ตอบคือระยะเวลาที่ใช้ในการเรียกกลับของตัวแฮนเดิลเหตุการณ์ที่ลงทะเบียนของการโต้ตอบให้ทำงานจนเสร็จสมบูรณ์ และสิ่งอื่นๆ ที่อาจเกิดขึ้นระหว่างนั้น ไลบรารี Web Vitals จะแสดงระยะเวลาการประมวลผลที่นาน
import {onINP} from 'web-vitals/attribution';
onINP(({name, value, attribution}) => {
const {processingDuration} = attribution; // 512.5
});
คุณอาจคิดว่าสาเหตุหลักที่ทำให้การโต้ตอบช้าคือโค้ดตัวแฮนเดิลเหตุการณ์ใช้เวลานานเกินไปในการเรียกใช้ แต่ก็อาจไม่เป็นเช่นนั้นเสมอไป เมื่อยืนยันแล้วว่านี่คือปัญหา คุณสามารถเจาะลึกข้อมูล LoAF ได้โดยทำดังนี้
import {onINP} from 'web-vitals/attribution';
onINP(({name, value, attribution}) => {
const {processingDuration} = attribution; // 512.5
// Get the longest script from LoAF covering `processingDuration`:
const loaf = attribution.longAnimationFrameEntries.at(-1);
const script = loaf?.scripts.toSorted((a, b) => b.duration - a.duration)[0];
if (script) {
// Get attribution for the long-running event handler:
const {invokerType} = script; // 'event-listener'
const {invoker} = script; // 'BUTTON#update.onclick'
const {sourceURL} = script; // 'https://example.com/app.js'
const {sourceCharPosition} = script; // 83
const {sourceFunctionName} = script; // 'update'
}
});
ดังที่เห็นในโค้ดตัวอย่างก่อนหน้า คุณสามารถใช้ข้อมูล LoAF เพื่อติดตามหาสาเหตุที่แท้จริงของการโต้ตอบที่มีค่าระยะเวลาการประมวลผลสูง ซึ่งรวมถึง
- องค์ประกอบและ Listener เหตุการณ์ที่ลงทะเบียน
- ไฟล์สคริปต์และตำแหน่งอักขระภายในไฟล์ที่มีโค้ดตัวแฮนเดิลเหตุการณ์ที่ทำงานเป็นเวลานาน
- ชื่อฟังก์ชัน
ข้อมูลประเภทนี้มีคุณค่าอย่างยิ่ง คุณไม่ต้องเสียเวลาค้นหาว่าการโต้ตอบใดหรือตัวแฮนเดิลเหตุการณ์ใดที่ทำให้ค่าระยะเวลาการประมวลผลสูงอีกต่อไป นอกจากนี้ เนื่องจากสคริปต์ของบุคคลที่สามมักจะลงทะเบียนตัวแฮนเดิลเหตุการณ์ของตนเอง คุณจึงสามารถพิจารณาได้ว่าโค้ดของคุณเป็นสาเหตุหรือไม่ สำหรับโค้ดที่คุณควบคุมได้ คุณจะต้องพิจารณาการเพิ่มประสิทธิภาพงานที่ใช้เวลานาน
ความล่าช้าในการป้อนข้อมูลนาน
แม้ว่าตัวแฮนเดิลเหตุการณ์ที่ทำงานเป็นเวลานานจะเป็นเรื่องปกติ แต่ก็มีส่วนอื่นๆ ของการโต้ตอบที่ต้องพิจารณาด้วย ส่วนหนึ่งเกิดขึ้นก่อนระยะเวลาการประมวลผล ซึ่งเรียกว่าความล่าช้าของอินพุต นี่คือเวลาตั้งแต่ตอนที่ผู้ใช้เริ่มการโต้ตอบจนถึงตอนที่การเรียกกลับของตัวแฮนเดิลเหตุการณ์เริ่มทํางาน และเกิดขึ้นเมื่อเธรดหลักกําลังประมวลผลงานอื่นอยู่ การสร้างการระบุแหล่งที่มาของไลบรารี web-vitals จะบอกระยะเวลาการตอบสนองแรกสำหรับอินเทอร์แอกชันได้
import {onINP} from 'web-vitals/attribution';
onINP(({name, value, attribution}) => {
const {inputDelay} = attribution; // 125.59439536
});
หากสังเกตเห็นว่าการโต้ตอบบางอย่างมีเวลาในการตอบสนองสูง คุณจะต้องพิจารณาว่าเกิดอะไรขึ้นในหน้าเว็บ ณ เวลาที่มีการโต้ตอบซึ่งทำให้เกิดเวลาในการตอบสนองนาน และมักจะสรุปได้ว่าการโต้ตอบเกิดขึ้นขณะที่หน้าเว็บกำลังโหลดหรือหลังจากนั้น
เกิดขึ้นระหว่างการโหลดหน้าเว็บใช่ไหม
เทรดหลักมักจะทำงานหนักที่สุดเมื่อหน้าเว็บกำลังโหลด ในระหว่างนี้ ระบบจะจัดคิวและประมวลผลงานทุกประเภท และหากผู้ใช้พยายามโต้ตอบกับหน้าเว็บขณะที่ระบบกำลังทำงานทั้งหมดนี้ การโต้ตอบอาจล่าช้า หน้าเว็บที่โหลด JavaScript จำนวนมากจะเริ่มทำงานเพื่อคอมไพล์และประเมินสคริปต์ รวมถึงเรียกใช้ฟังก์ชันที่ทำให้หน้าเว็บพร้อมสำหรับการโต้ตอบของผู้ใช้ การทำงานนี้อาจขัดขวางการโต้ตอบของผู้ใช้หากเกิดขึ้นพร้อมกัน และคุณสามารถตรวจสอบได้ว่าผู้ใช้เว็บไซต์ของคุณเป็นเช่นนั้นหรือไม่โดยทำดังนี้
import {onINP} from 'web-vitals/attribution';
onINP(({name, value, attribution}) => {
const {inputDelay} = attribution; // 125.59439536
// Get the longest script from the first LoAF entry:
const loaf = attribution.longAnimationFrameEntries[0];
const script = loaf?.scripts.toSorted((a, b) => b.duration - a.duration)[0];
if (script) {
// Invoker types can describe if script eval blocked the main thread:
const {invokerType} = script; // 'classic-script' | 'module-script'
const {sourceLocation} = script; // 'https://example.com/app.js'
}
});
หากคุณบันทึกข้อมูลนี้ในฟิลด์และเห็นความล่าช้าในการป้อนข้อมูลสูงและประเภท Invoker เป็น 'classic-script'
หรือ 'module-script'
ก็สามารถพูดได้ว่าสคริปต์ในเว็บไซต์ใช้เวลานานในการประเมิน และบล็อกเทรดหลักนานพอที่จะทำให้การโต้ตอบล่าช้า คุณลดเวลาการบล็อกนี้ได้โดยแบ่งสคริปต์ออกเป็นแพ็กเกจขนาดเล็ก เลื่อนการโหลดโค้ดที่ไม่ได้ใช้ในตอนแรกไปเป็นเวลาอื่น และตรวจสอบโค้ดที่ไม่ได้ใช้ในเว็บไซต์เพื่อนำออกทั้งหมด
เป็นหลังจากโหลดหน้าเว็บใช่ไหม
แม้ว่าความล่าช้าในการป้อนข้อมูลมักจะเกิดขึ้นขณะที่หน้าเว็บกำลังโหลด แต่ก็เป็นไปได้เช่นกันที่จะเกิดขึ้นหลังจากที่หน้าเว็บโหลดเสร็จแล้ว ซึ่งเกิดจากสาเหตุที่แตกต่างกันโดยสิ้นเชิง สาเหตุที่พบบ่อยของความล่าช้าในการป้อนข้อมูลหลังจากโหลดหน้าเว็บอาจเป็นโค้ดที่ทำงานเป็นระยะๆ เนื่องจากการเรียก setInterval
ก่อนหน้านี้ หรือแม้แต่การเรียกกลับของเหตุการณ์ที่จัดคิวไว้ให้ทำงานก่อนหน้านี้และยังคงประมวลผลอยู่
import {onINP} from 'web-vitals/attribution';
onINP(({name, value, attribution}) => {
const {inputDelay} = attribution; // 125.59439536
// Get the longest script from the first LoAF entry:
const loaf = attribution.longAnimationFrameEntries[0];
const script = loaf?.scripts.toSorted((a, b) => b.duration - a.duration)[0];
if (script) {
const {invokerType} = script; // 'user-callback'
const {sourceURL} = script; // 'https://example.com/app.js'
const {sourceCharPosition} = script; // 83
const {sourceFunctionName} = script; // 'update'
}
});
เช่นเดียวกับการแก้ปัญหาค่าระยะเวลาการประมวลผลสูง ความล่าช้าในการป้อนข้อมูลสูงเนื่องจากสาเหตุที่กล่าวถึงก่อนหน้านี้จะให้ข้อมูลการระบุแหล่งที่มาของสคริปต์โดยละเอียด อย่างไรก็ตาม สิ่งที่แตกต่างออกไปคือประเภทผู้เรียกใช้จะเปลี่ยนไปตามลักษณะของงานที่ทำให้การโต้ตอบล่าช้า
'user-callback'
ระบุว่างานบล็อกมาจากsetInterval
,setTimeout
หรือแม้แต่requestAnimationFrame
'event-listener'
แสดงว่างานการบล็อกมาจากอินพุตก่อนหน้านี้ที่อยู่ในคิวและยังคงประมวลผลอยู่'resolve-promise'
และ'reject-promise'
หมายความว่างานที่บล็อกมาจากงานแบบอะซิงโครนัสบางอย่างที่เริ่มก่อนหน้านี้ และได้รับการแก้ไขหรือปฏิเสธในเวลาที่ผู้ใช้พยายามโต้ตอบกับหน้าเว็บ ซึ่งทำให้การโต้ตอบล่าช้า
ไม่ว่าในกรณีใดก็ตาม ข้อมูลการระบุแหล่งที่มาของสคริปต์จะช่วยให้คุณทราบว่าควรเริ่มดูที่ใด และความล่าช้าในการป้อนข้อมูลเกิดจากโค้ดของคุณเองหรือสคริปต์ของบุคคลที่สาม
ความล่าช้าของงานนำเสนอที่นาน
ความล่าช้าในการนำเสนอคือขั้นตอนสุดท้ายของการโต้ตอบ และจะเริ่มเมื่อตัวแฮนเดิลเหตุการณ์ของการโต้ตอบเสร็จสิ้น จนถึงจุดที่วาดเฟรมถัดไป ซึ่งจะเกิดขึ้นเมื่อการทำงานในตัวแฮนเดิลเหตุการณ์เนื่องจากการโต้ตอบเปลี่ยนสถานะภาพของอินเทอร์เฟซผู้ใช้ เช่นเดียวกับระยะเวลาการประมวลผลและความล่าช้าของอินพุต ไลบรารี web-vitals จะบอกระยะเวลาความล่าช้าในการนำเสนอสำหรับการโต้ตอบได้ ดังนี้
import {onINP} from 'web-vitals/attribution';
onINP(({name, value, attribution}) => {
const {presentationDelay} = attribution; // 113.32307691
});
หากคุณบันทึกข้อมูลนี้และเห็นว่าการนำเสนอมีความล่าช้าสูงสำหรับการโต้ตอบที่ส่งผลต่อ INP ของเว็บไซต์ สาเหตุอาจแตกต่างกันไป แต่สาเหตุที่ควรระวังมีดังนี้
การจัดรูปแบบและเลย์เอาต์ที่ซับซ้อน
ความล่าช้าในการนำเสนอที่นานอาจเกิดจากการคำนวณสไตล์ใหม่และเลย์เอาต์ที่มีค่าใช้จ่ายสูง ซึ่งเกิดจากสาเหตุหลายประการ รวมถึงเครื่องมือเลือก CSS ที่ซับซ้อนและขนาด DOM ที่ใหญ่ คุณสามารถวัดระยะเวลาของงานนี้ได้โดยใช้เวลา LoAF ที่แสดงในไลบรารี web-vitals
import {onINP} from 'web-vitals/attribution';
onINP(({name, value, attribution}) => {
const {presentationDelay} = attribution; // 113.32307691
// Get the longest script from the last LoAF entry:
const loaf = attribution.longAnimationFrameEntries.at(-1);
const script = loaf?.scripts.toSorted((a, b) => b.duration - a.duration)[0];
// Get necessary timings:
const {startTime} = loaf; // 2120.5
const {duration} = loaf; // 1002
// Figure out the ending timestamp of the frame (approximate):
const endTime = startTime + duration; // 3122.5
// Get the start timestamp of the frame's style/layout work:
const {styleAndLayoutStart} = loaf; // 3011.17692309
// Calculate the total style/layout duration:
const styleLayoutDuration = endTime - styleAndLayoutStart; // 111.32307691
if (script) {
// Get attribution for the event handler that triggered
// the long-running style and layout operation:
const {invokerType} = script; // 'event-listener'
const {invoker} = script; // 'BUTTON#update.onclick'
const {sourceURL} = script; // 'https://example.com/app.js'
const {sourceCharPosition} = script; // 83
const {sourceFunctionName} = script; // 'update'
}
});
LoAF จะไม่บอกระยะเวลาการทำงานของสไตล์และเลย์เอาต์สำหรับเฟรม แต่จะบอกเวลาที่เริ่มทำงาน การประทับเวลาเริ่มต้นนี้ช่วยให้คุณใช้ข้อมูลอื่นๆ จาก LoAF เพื่อคำนวณระยะเวลาที่ถูกต้องของงานนั้นได้โดยการกำหนดเวลาสิ้นสุดของเฟรม แล้วลบการประทับเวลาเริ่มต้นของงานสไตล์และเลย์เอาต์ออกจากเวลาสิ้นสุดนั้น
requestAnimationFrame
การเรียกกลับที่ใช้เวลานาน
สาเหตุหนึ่งที่อาจทำให้เกิดความล่าช้าในการนำเสนอเป็นเวลานานคือการทำงานมากเกินไปในแฮนเดิลการเรียกกลับ requestAnimationFrame
เนื้อหาของฟังก์ชันเรียกกลับนี้จะดำเนินการหลังจากตัวแฮนเดิลเหตุการณ์ทำงานเสร็จแล้ว แต่จะดำเนินการก่อนการคำนวณรูปแบบใหม่และงานเลย์เอาต์
การเรียกกลับเหล่านี้อาจใช้เวลานานพอสมควรจึงจะเสร็จสมบูรณ์หากงานที่ทำภายในมีความซับซ้อน หากสงสัยว่าค่าความล่าช้าในการนำเสนอสูงเกิดจากการทำงานร่วมกับ requestAnimationFrame
คุณสามารถใช้ข้อมูล LoAF ที่ไลบรารี web-vitals แสดงเพื่อระบุสถานการณ์ต่อไปนี้
onINP(({name, value, attribution}) => {
const {presentationDelay} = attribution; // 543.1999999880791
// Get the longest script from the last LoAF entry:
const loaf = attribution.longAnimationFrameEntries.at(-1);
const script = loaf?.scripts.toSorted((a, b) => b.duration - a.duration)[0];
// Get the render start time and when style and layout began:
const {renderStart} = loaf; // 2489
const {styleAndLayoutStart} = loaf; // 2989.5999999940395
// Calculate the `requestAnimationFrame` callback's duration:
const rafDuration = styleAndLayoutStart - renderStart; // 500.59999999403954
if (script) {
// Get attribution for the event handler that triggered
// the long-running requestAnimationFrame callback:
const {invokerType} = script; // 'user-callback'
const {invoker} = script; // 'FrameRequestCallback'
const {sourceURL} = script; // 'https://example.com/app.js'
const {sourceCharPosition} = script; // 83
const {sourceFunctionName} = script; // 'update'
}
});
หากเห็นว่าเวลาในการนำเสนอที่ล่าช้าส่วนใหญ่ใช้ไปกับrequestAnimationFrame
การเรียกกลับ ให้ตรวจสอบว่างานที่คุณทำในการเรียกกลับเหล่านี้จำกัดอยู่เพียงการทำงานที่ส่งผลให้เกิดการอัปเดตจริงในอินเทอร์เฟซผู้ใช้ งานอื่นๆ ที่ไม่ได้แตะ DOM หรืออัปเดตสไตล์จะทำให้การวาดเฟรมถัดไปล่าช้าโดยไม่จำเป็น ดังนั้นโปรดระมัดระวัง
บทสรุป
ข้อมูลภาคสนามเป็นแหล่งข้อมูลที่ดีที่สุดที่คุณสามารถใช้ได้เมื่อต้องการทำความเข้าใจว่าการโต้ตอบใดที่ทำให้เกิดปัญหาสำหรับผู้ใช้จริงในภาคสนาม การใช้เครื่องมือรวบรวมข้อมูลภาคสนาม เช่น ไลบรารี JavaScript ของ Web Vitals (หรือผู้ให้บริการ RUM) จะช่วยให้คุณมั่นใจมากขึ้นว่าการโต้ตอบใดที่มีปัญหามากที่สุด จากนั้นจึงจำลองการโต้ตอบที่มีปัญหาในห้องทดลอง แล้วดำเนินการแก้ไข
รูปภาพหลักจาก Unsplash โดย Federico Respini