API เฟรมภาพเคลื่อนไหวแบบยาว

Long Animation Frames API (LoAF - ออกเสียงว่า Lo-Af) เป็นการอัปเดต Long Tasks API เพื่อให้เข้าใจการอัปเดตอินเทอร์เฟซผู้ใช้ (UI) ที่ช้าได้ดียิ่งขึ้น ซึ่งอาจมีประโยชน์ในการระบุเฟรมภาพเคลื่อนไหวที่ช้าซึ่งมีแนวโน้มที่จะส่งผลต่อเมตริก Interaction to Next Paint (INP) ของ Core Web Vitals ซึ่งวัดการตอบสนอง หรือเพื่อระบุ UI อื่นๆ ที่กระตุกซึ่งส่งผลต่อความลื่นไหล

สถานะของ API

การรองรับเบราว์เซอร์

  • Chrome: 123
  • Edge: 123
  • Firefox: ไม่รองรับ
  • Safari: ไม่รองรับ

แหล่งที่มา

หลังจากช่วงทดลองใช้จากต้นทางของ Chrome 116 ถึง Chrome 122 ทางเราได้เปิดตัว LoAF API จาก Chrome 123

เบื้องหลัง: Long Tasks API

การรองรับเบราว์เซอร์

  • Chrome: 58
  • Edge: 79
  • Firefox: ไม่รองรับ
  • Safari: ไม่รองรับ

แหล่งที่มา

Long Animation Frames API เป็นทางเลือกแทน Long Tasks API ที่มีให้บริการใน Chrome มาระยะหนึ่งแล้ว (ตั้งแต่ Chrome 58) Long Task API ช่วยให้คุณตรวจสอบงานที่ใช้เวลานานได้ ซึ่งก็คืองานที่ครอบครองชุดข้อความหลักเป็นเวลา 50 มิลลิวินาทีขึ้นไป คุณสามารถตรวจสอบงานที่ใช้เวลานานได้โดยใช้อินเทอร์เฟซ PerformanceLongTaskTiming ที่มี PeformanceObserver ดังนี้

const observer = new PerformanceObserver((list) => {
  console.log(list.getEntries());
});

observer.observe({ type: 'longtask', buffered: true });

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

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

ดังนั้นเมื่อพยายามปรับปรุงการตอบสนอง สิ่งแรกที่ควรทำคือเรียกใช้การติดตามประสิทธิภาพและดูงานที่ใช้เวลานาน ซึ่งอาจเป็นการตรวจสอบผ่านเครื่องมือตรวจสอบแบบห้องทดลอง เช่น Lighthouse (ซึ่งมีการตรวจสอบหลีกเลี่ยงงานในเทรดหลักที่ใช้เวลานาน) หรือดูงานที่ใช้เวลานานในเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome

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

ข้อบกพร่องของ Long Tasks API

การวัดงานที่ใช้เวลานานในสนามโดยใช้เครื่องมือสังเกตประสิทธิภาพมีประโยชน์เพียงเล็กน้อยเท่านั้น แต่จริงๆ แล้ว ข้อมูลนี้ไม่ได้ให้ข้อมูลมากไปกว่าข้อเท็จจริงที่ว่าเกิดงานที่ใช้เวลานานขึ้นและใช้เวลานานเท่าใด

เครื่องมือ Real User Monitoring (RUM) มักใช้เมตริกนี้เพื่อติดตามแนวโน้มของจํานวนหรือระยะเวลาของงานที่ใช้เวลานาน หรือระบุหน้าเว็บที่เกิดการดําเนินการดังกล่าว แต่หากไม่มีรายละเอียดที่เจาะลึกเกี่ยวกับสาเหตุที่ทําให้งานใช้เวลานาน ข้อมูลนี้ก็จะมีประโยชน์เพียงเล็กน้อย Long Tasks API มีเพียงรูปแบบการระบุแหล่งที่มาพื้นฐาน ซึ่งจะบอกได้แค่คอนเทนเนอร์ที่ Long Task เกิดขึ้น (เอกสารระดับบนสุดหรือ <iframe>) แต่จะไม่บอกสคริปต์หรือฟังก์ชันที่เรียกใช้ Long Task ดังที่แสดงโดยรายการทั่วไปต่อไปนี้

{
  "name": "unknown",
  "entryType": "longtask",
  "startTime": 31.799999997019768,
  "duration": 136,
  "attribution": [
    {
      "name": "unknown",
      "entryType": "taskattribution",
      "startTime": 0,
      "duration": 0,
      "containerType": "window",
      "containerSrc": "",
      "containerId": "",
      "containerName": ""
    }
  ]
}

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

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

Long Animation Frames API

การรองรับเบราว์เซอร์

  • Chrome: 123
  • Edge: 123
  • Firefox: ไม่รองรับ
  • Safari: ไม่รองรับ

แหล่งที่มา

Long Animation Frames API (LoAF) คือ API ใหม่ที่พยายามแก้ไขข้อบกพร่องบางอย่างของ Long Tasks API เพื่อให้นักพัฒนาแอปได้รับข้อมูลเชิงลึกที่นําไปใช้ได้จริงมากขึ้นเพื่อช่วยแก้ไขปัญหาการตอบสนองและปรับปรุง INP รวมถึงรับข้อมูลเชิงลึกเกี่ยวกับปัญหาความลื่นไหล

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

Long Animation Frames API เป็นแนวทางทางเลือกในการวัดการบล็อก Long Animation Frames API จะวัดเฟรมภาพเคลื่อนไหวที่ใช้เวลานาน ตามที่ชื่อบอกไว้ แทนที่จะวัดงานแต่ละรายการ เฟรมภาพเคลื่อนไหวที่ยาวคือเมื่อการอัปเดตการแสดงผลล่าช้าเกิน 50 มิลลิวินาที (เท่ากับเกณฑ์สำหรับ Long Tasks API)

ระบบจะวัดเฟรมภาพเคลื่อนไหวแบบยาวนับจากจุดเริ่มต้นของงานที่ต้องมีการเรนเดอร์ ในกรณีที่งานแรกในเฟรมภาพเคลื่อนไหวที่ใช้เวลานานไม่จำเป็นต้องใช้การแสดงผล เฟรมภาพเคลื่อนไหวที่ใช้เวลานานจะสิ้นสุดลงเมื่องานที่ไม่ต้องใช้การแสดงผลเสร็จสมบูรณ์ และเฟรมภาพเคลื่อนไหวที่ใช้เวลานานที่เป็นไปได้ใหม่จะเริ่มขึ้นพร้อมกับงานถัดไป เฟรมภาพเคลื่อนไหวแบบยาวที่ไม่ได้แสดงผลดังกล่าวจะยังคงรวมอยู่ใน Long Animation Frames API เมื่อนานกว่า 50 มิลลิวินาที (โดยมีเวลา renderStart เป็น 0) เพื่อให้วัดงานที่อาจมีการบล็อกได้

เฟรมภาพเคลื่อนไหวที่ยาวจะสังเกตได้คล้ายกับงานที่ยาวที่มี PerformanceObserver แต่ดูที่ประเภท long-animation-frame แทน

const observer = new PerformanceObserver((list) => {
  console.log(list.getEntries());
});

observer.observe({ type: 'long-animation-frame', buffered: true });

นอกจากนี้ คุณยังค้นหาเฟรมภาพเคลื่อนไหวแบบยาวก่อนหน้าจากไทม์ไลน์ประสิทธิภาพได้ด้วย โดยทำดังนี้

const loafs = performance.getEntriesByType('long-animation-frame');

อย่างไรก็ตาม มี maxBufferSize สำหรับรายการประสิทธิภาพ ซึ่งระบบจะทิ้งรายการที่ใหม่กว่า ดังนั้นเราจึงแนะนําให้ใช้แนวทาง PerformanceObserver ขนาดบัฟเฟอร์ของ long-animation-frame ตั้งค่าเป็น 200 เช่นเดียวกับ long-tasks

ข้อดีของการดูเฟรมแทนงาน

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

ข้อดีอีกอย่างหนึ่งของมุมมองทางเลือกนี้สำหรับงานที่ใช้เวลานานคือความสามารถในการแสดงรายละเอียดเวลาของทั้งเฟรม LoAF มีการแจกแจงรายละเอียดที่ละเอียดกว่ามากในส่วนต่างๆ ของระยะเวลาเฟรม แทนที่จะใส่เพียง startTime และ duration เหมือนกับ Long Tasks API

การประทับเวลาและระยะเวลาของเฟรม

  • startTime: เวลาเริ่มต้นของเฟรมภาพเคลื่อนไหวที่ใช้เวลานานซึ่งสัมพันธ์กับเวลาเริ่มต้นของการนําทาง
  • duration: ระยะเวลาของเฟรมภาพเคลื่อนไหวแบบยาว (ไม่รวมเวลานำเสนอ)
  • renderStart: เวลาเริ่มต้นของรอบการแสดงผล ซึ่งรวมถึงการเรียกกลับ requestAnimationFrame, การคำนวณสไตล์และเลย์เอาต์, การเรียกกลับของ ResizeObserver และ IntersectionObserver
  • styleAndLayoutStart: ช่วงเวลาเริ่มต้นที่ใช้ในการคำนวณสไตล์และเลย์เอาต์
  • firstUIEventTimestamp: เวลาของเหตุการณ์ UI แรก (เมาส์/แป้นพิมพ์ และอื่นๆ) ที่จะจัดการในระหว่างกรอบเวลานี้
  • blockingDuration: ระยะเวลาทั้งหมดเป็นมิลลิวินาทีที่เฟรมภาพเคลื่อนไหวจะบล็อกการประมวลผลอินพุตหรืองานอื่นๆ ที่มีลำดับความสำคัญสูง

คําอธิบายของ blockingDuration

เฟรมภาพเคลื่อนไหวที่ยาวอาจประกอบด้วยงานหลายรายการ blockingDuration คือผลรวมของระยะเวลาของงานที่นานกว่า 50 มิลลิวินาที (รวมถึงระยะเวลาการแสดงผลสุดท้ายภายในงานที่ยาวที่สุด)

ตัวอย่างเช่น หากเฟรมภาพเคลื่อนไหวแบบยาวประกอบด้วยงาน 2 รายการที่ใช้เวลา 55 มิลลิวินาทีและ 65 มิลลิวินาที ตามด้วยการเรนเดอร์ 20 มิลลิวินาที duration จะเท่ากับประมาณ 140 มิลลิวินาที โดยมี blockingDuration เท่ากับ (55 - 50) + (65 + 20 - 50) = 40 มิลลิวินาที เป็นเวลา 40 มิลลิวินาทีในเฟรมภาพเคลื่อนไหวยาว 140 มิลลิวินาทีนี้ ระบบถือว่าเฟรมถูกบล็อกไม่ให้จัดการอินพุต

พิจารณา duration หรือ blockingDuration

สำหรับจอแสดงผล 60 เฮิร์ตซ์ทั่วไป เบราว์เซอร์จะพยายามกำหนดเวลาเฟรมอย่างน้อยทุก 16.66 มิลลิวินาที (เพื่อให้การอัปเดตราบรื่น) หรือหลังจากงานที่มีลำดับความสำคัญสูง เช่น การจัดการอินพุต (เพื่อให้การอัปเดตตอบสนองได้อย่างรวดเร็ว) อย่างไรก็ตาม หากไม่มีอินพุตหรืองานอื่นๆ ที่มีลำดับความสำคัญสูง แต่มีคิวงานอื่นๆ อยู่ โดยทั่วไปเบราว์เซอร์จะแสดงเฟรมปัจจุบันต่อไปเกิน 16.66 มิลลิวินาที ไม่ว่างานจะแบ่งออกเป็นส่วนๆ ได้ดีเพียงใดก็ตาม กล่าวคือ เบราว์เซอร์จะพยายามจัดลําดับความสําคัญของอินพุตเสมอ แต่อาจเลือกจัดการคิวของงานแทนการอัปเดตการแสดงผล เนื่องจากการแสดงผลเป็นกระบวนการที่มีค่าใช้จ่ายสูง การประมวลผลงานการแสดงผลแบบรวมสำหรับงานหลายรายการจึงมักจะทำให้งานโดยรวมลดลง

ดังนั้น เฟรมภาพเคลื่อนไหวที่ยาวซึ่งมี blockingDuration ต่ำหรือเป็น 0 ควรยังคงตอบสนองต่ออินพุต ดังนั้น การลดหรือกำจัด blockingDuration โดยแบ่งงานที่ใช้เวลานานออกเป็นหลายงานจึงเป็นกุญแจสำคัญในการปรับปรุงการตอบสนองตามที่วัดโดย INP

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

ช่วงเวลาของเฟรม

การประทับเวลาที่กล่าวถึงก่อนหน้านี้ช่วยให้คุณแบ่งเฟรมภาพเคลื่อนไหวแบบยาวออกเป็นช่วงเวลาต่างๆ ได้ ดังนี้

ช่วงเวลา การคำนวณ
เวลาเริ่มต้น startTime
เวลาสิ้นสุด startTime + duration
ระยะเวลาทำงาน renderStart ? renderStart - startTime : duration
ระยะเวลาการแสดงผล renderStart ? (startTime + duration) - renderStart: 0
การแสดงผล: ระยะเวลาก่อนเลย์เอาต์ styleAndLayoutStart ? styleAndLayoutStart - renderStart : 0
การแสดงผล: ระยะเวลาของสไตล์และเลย์เอาต์ styleAndLayoutStart ? (startTime + duration) - styleAndLayoutStart : 0

การระบุแหล่งที่มาของสคริปต์ที่ดียิ่งขึ้น

ประเภทรายการ long-animation-frame มีข้อมูลการระบุแหล่งที่มาที่ดีขึ้นของสคริปต์แต่ละรายการที่ทําให้เกิดเฟรมภาพเคลื่อนไหวที่ยาว (สําหรับสคริปต์ที่ยาวกว่า 5 มิลลิวินาที)

ข้อมูลนี้จะแสดงในอาร์เรย์ของรายการการระบุแหล่งที่มา ซึ่งแต่ละรายการจะมีรายละเอียดดังนี้ ซึ่งคล้ายกับ Long Tasks API

  • ทั้ง name และ EntryType จะแสดงผล script
  • invoker ที่มีความหมาย ซึ่งระบุวิธีเรียกใช้สคริปต์ (เช่น 'IMG#id.onload', 'Window.requestAnimationFrame' หรือ 'Response.json.then')
  • invokerType ของจุดแรกเข้าของสคริปต์
    • user-callback: แคล็กแบ็กที่รู้จักซึ่งลงทะเบียนจาก API ของแพลตฟอร์มเว็บ (เช่น setTimeout, requestAnimationFrame)
    • event-listener: รายการที่รับฟังเหตุการณ์ของแพลตฟอร์ม (เช่น click, load, keyup)
    • resolve-promise: แฮนเดิลของสัญญาแพลตฟอร์ม (เช่น fetch() โปรดทราบว่าในกรณีของ Promise ระบบจะรวมตัวแฮนเดิลทั้งหมดของ Promise เดียวกันไว้ด้วยกันเป็น "สคริปต์" รายการเดียว).
    • reject-promise: ตาม resolve-promise แต่เป็นการปฏิเสธ
    • classic-script: การประเมินสคริปต์ (เช่น <script> หรือ import())
    • module-script: เหมือนกับ classic-script แต่สำหรับสคริปต์ของข้อบังคับ
  • แยกข้อมูลเวลาของสคริปต์นั้นๆ ดังนี้
    • startTime: เวลาที่มีการเรียกใช้ฟังก์ชันรายการ
    • duration: ระยะเวลาระหว่าง startTime กับเวลาที่คิวงานย่อยรายการถัดไปประมวลผลเสร็จสิ้น
    • executionStart: เวลาหลังจากการคอมไพล์
    • forcedStyleAndLayoutDuration: เวลาทั้งหมดที่ใช้ประมวลผลเลย์เอาต์และสไตล์ที่บังคับภายในฟังก์ชันนี้ (ดูการทํางานหนักเกินไป)
    • pauseDuration: เวลาทั้งหมดที่ใช้ใน "การหยุดชั่วคราว" การดำเนินการแบบซิงค์ (การแจ้งเตือน, XHR แบบซิงค์)
  • รายละเอียดแหล่งที่มาของสคริปต์
    • sourceURL: ชื่อทรัพยากรสคริปต์ (หากมี) (หรือว่างเปล่าหากไม่พบ)
    • sourceFunctionName: ชื่อฟังก์ชันสคริปต์ (หากมี) (หรือว่างเปล่าหากไม่พบ)
    • sourceCharPosition: ตําแหน่งอักขระสคริปต์ (หรือ -1 หากไม่พบ)
  • windowAttribution: คอนเทนเนอร์ (เอกสารระดับบนสุดหรือ <iframe>) ที่เฟรมภาพเคลื่อนไหวยาวเกิดขึ้น
  • window: การอ้างอิงถึงหน้าต่างต้นทางเดียวกัน

รายการแหล่งที่มา (หากมี) ช่วยให้นักพัฒนาซอฟต์แวร์ทราบวิธีที่เรียกใช้สคริปต์แต่ละรายการในเฟรมภาพเคลื่อนไหวแบบยาวได้อย่างชัดเจน ไปจนถึงตำแหน่งของตัวละครในสคริปต์ที่เรียก ซึ่งจะให้ตําแหน่งที่แน่นอนในทรัพยากร JavaScript ที่ทําให้เกิดเฟรมภาพเคลื่อนไหวที่ยาว

ตัวอย่างรายการประสิทธิภาพ long-animation-frame

ตัวอย่างรายการประสิทธิภาพ long-animation-frame ที่สมบูรณ์ซึ่งมีสคริปต์เดียวมีดังนี้

{
  "blockingDuration": 0,
  "duration": 60,
  "entryType": "long-animation-frame",
  "firstUIEventTimestamp": 11801.099999999627,
  "name": "long-animation-frame",
  "renderStart": 11858.800000000745,
  "scripts": [
    {
      "duration": 45,
      "entryType": "script",
      "executionStart": 11803.199999999255,
      "forcedStyleAndLayoutDuration": 0,
      "invoker": "DOMWindow.onclick",
      "invokerType": "event-listener",
      "name": "script",
      "pauseDuration": 0,
      "sourceURL": "https://web.dev/js/index-ffde4443.js",
      "sourceFunctionName": "myClickHandler",
      "sourceCharPosition": 17796,
      "startTime": 11803.199999999255,
      "window": [Window object],
      "windowAttribution": "self"
    }
  ],
  "startTime": 11802.400000000373,
  "styleAndLayoutStart": 11858.800000000745
}

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

ใช้ Long Animation Frames API ในพื้นที่ทำงาน

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

Long Animation Frames API ออกแบบมาเพื่อใช้ในสนามเพื่อรวบรวมข้อมูลตามบริบทที่สําคัญสําหรับการโต้ตอบของผู้ใช้ ซึ่ง Long Tasks API ทําไม่ได้ ซึ่งจะช่วยให้คุณระบุและจำลองปัญหาเกี่ยวกับการโต้ตอบที่อาจไม่พบได้

ฟีเจอร์ที่รองรับการระบุเฟรมภาพเคลื่อนไหวแบบยาวของ API

คุณสามารถใช้โค้ดต่อไปนี้เพื่อทดสอบว่าระบบรองรับ API หรือไม่

if (PerformanceObserver.supportedEntryTypes.includes('long-animation-frame')) {
  // Monitor LoAFs
}

กรณีการใช้งานที่ชัดเจนที่สุดของ Long Animation Frames API คือเพื่อช่วยวินิจฉัยและแก้ไขปัญหา Interaction to Next Paint (INP) และนี่เป็นหนึ่งในเหตุผลหลักที่ทีม Chrome พัฒนา API นี้ INP ที่ดีคือการโต้ตอบทั้งหมดได้รับการตอบกลับภายใน 200 มิลลิวินาทีหรือน้อยกว่านับจากการโต้ตอบจนกว่าเฟรมจะแสดง และเนื่องจาก Long Animation Frames API จะวัดเฟรมทั้งหมดที่ใช้เวลา 50 มิลลิวินาทีขึ้นไป INP ที่มีปัญหาส่วนใหญ่จึงควรมีข้อมูล LoAF เพื่อช่วยคุณวิเคราะห์การโต้ตอบเหล่านั้น

"LoAF ของ INP" คือ LoAF ที่มี INP Interaction ตามที่แสดงในแผนภาพต่อไปนี้

ตัวอย่างเฟรมภาพเคลื่อนไหวแบบยาวในหน้าเว็บ โดยไฮไลต์ INP LoAF
หน้าเว็บอาจมี LoAF หลายรายการ โดยที่ 1 ในนั้นเกี่ยวข้องกับการโต้ตอบ INP

ในบางกรณี เหตุการณ์ INP อาจครอบคลุม LoAF 2 รายการ ซึ่งมักเกิดขึ้นเมื่อการโต้ตอบเกิดขึ้นหลังจากที่เฟรมเริ่มแสดงผลบางส่วนของเฟรมก่อนหน้าแล้ว ระบบจึงประมวลผลตัวแฮนเดิลเหตุการณ์ในเฟรมถัดไป

ตัวอย่างเฟรมภาพเคลื่อนไหวแบบยาวในหน้าเว็บ โดยไฮไลต์ INP LoAF
หน้าเว็บอาจมี LoAF หลายรายการ โดยที่ 1 ในนั้นเกี่ยวข้องกับการโต้ตอบ INP

และอาจครอบคลุม LoAF มากกว่า 2 รายการในบางกรณีที่ไม่ค่อยเกิดขึ้น

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

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

ไม่มี API โดยตรงที่จะลิงก์รายการ INP กับรายการ LoAF ที่เกี่ยวข้อง แต่คุณลิงก์รายการเหล่านั้นในโค้ดได้โดยการเปรียบเทียบเวลาเริ่มต้นและเวลาสิ้นสุดของแต่ละรายการ (ดูสคริปต์ตัวอย่าง WhyNp) ไลบรารี web-vitals จะรวม LoAF ที่ตัดกันทั้งหมดในพร็อพเพอร์ตี้ longAnimationFramesEntries ของอินเทอร์เฟซการระบุแหล่งที่มา INP จาก v4

เมื่อลิงก์รายการ LoAF แล้ว คุณจะใส่ข้อมูลที่มีการระบุแหล่งที่มาของ INP ได้ ออบเจ็กต์ scripts มีข้อมูลที่มีประโยชน์มากที่สุดเนื่องจากสามารถแสดงสิ่งที่ทํางานอยู่ในเฟรมเหล่านั้นได้ การส่งบีคอนกลับไปยังบริการวิเคราะห์จะช่วยให้คุณเข้าใจสาเหตุที่การโต้ตอบช้าลง

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

รายงานข้อมูลภาพเคลื่อนไหวแบบยาวเพิ่มเติมไปยังปลายทางข้อมูลวิเคราะห์

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

คุณจึงควรพิจารณา LoAF ทั้งหมดตลอดอายุการใช้งานของหน้าเว็บแทนที่จะดูเฉพาะ LoAF ของ INP

หน้าเว็บที่มี LoAF จำนวนมาก ซึ่งบางส่วนเกิดขึ้นระหว่างการโต้ตอบ แม้ว่าจะไม่ใช่การโต้ตอบ INP ก็ตาม
การตรวจสอบ LoAF ทั้งหมดจะช่วยระบุปัญหา INP ในอนาคตได้

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

รูปแบบที่แนะนำในการลดปริมาณข้อมูลเฟรมภาพเคลื่อนไหวแบบยาวมีดังนี้

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

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

สังเกตเฟรมภาพเคลื่อนไหวที่ใช้เวลานานที่มีการโต้ตอบ

หากต้องการข้อมูลเชิงลึกนอกเหนือจากเฟรมภาพเคลื่อนไหวแบบยาวของ INP ให้ดู LoAF ทั้งหมดที่มีการโต้ตอบ (ซึ่งตรวจพบได้จากค่า firstUIEventTimestamp) ที่มี blockingDuration สูง

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

โค้ดต่อไปนี้จะบันทึกรายการ LoAF ทั้งหมดที่มี blockingDuration มากกว่า 100 มิลลิวินาทีซึ่งมีการโต้ตอบเกิดขึ้นระหว่างเฟรม ตัวเลข 100 นี้เลือกมาเนื่องจากน้อยกว่าเกณฑ์ INP "ดี" ที่ 200 มิลลิวินาที คุณเลือกค่าที่สูงกว่าหรือต่ำกว่าก็ได้ตามต้องการ

const REPORTING_THRESHOLD_MS = 100;

const observer = new PerformanceObserver(list => {
  for (const entry of list.getEntries()) {
    if (entry.blockingDuration > REPORTING_THRESHOLD_MS &&
      entry.firstUIEventTimestamp > 0
    ) {
      // Example here logs to console, but could also report back to analytics
      console.log(entry);
    }
  }
});
observer.observe({ type: 'long-animation-frame', buffered: true });

ดูเฟรมภาพเคลื่อนไหวที่ใช้เวลานานซึ่งมีระยะเวลาการบล็อกสูง

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

โค้ดต่อไปนี้จะบันทึกรายการ LoAF ทั้งหมดที่มีระยะเวลาการบล็อกนานกว่า 100 มิลลิวินาทีซึ่งเกิดการโต้ตอบระหว่างเฟรม ตัวเลข 100 นี้เลือกมาเนื่องจากน้อยกว่าเกณฑ์ INP "ดี" ที่ 200 มิลลิวินาที เพื่อช่วยระบุเฟรมที่อาจมีปัญหา ขณะเดียวกันก็ลดจำนวนเฟรมภาพเคลื่อนไหวที่ยาวซึ่งมีการรายงานให้เหลือน้อยที่สุด คุณเลือกค่าที่สูงกว่าหรือต่ำกว่าก็ได้ตามต้องการ

const REPORTING_THRESHOLD_MS = 100;

const observer = new PerformanceObserver(list => {
  for (const entry of list.getEntries()) {
    if (entry.blockingDuration > REPORTING_THRESHOLD_MS) {
      // Example here logs to console, but could also report back to analytics
      console.log(entry);
    }
  }
});
observer.observe({ type: 'long-animation-frame', buffered: true });

สังเกตเฟรมภาพเคลื่อนไหวที่ยาวระหว่างการอัปเดต UI ที่สำคัญเพื่อปรับปรุงความลื่นไหล

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

เนื่องจากข้อมูลนี้อาจมีความผันผวนสูง คุณจึงอาจต้องจํากัดการวัดเหล่านี้ไว้ที่จุดสําคัญโดยใช้รูปแบบดังนี้

const REPORTING_THRESHOLD_MS = 100;

const observer = new PerformanceObserver(list => {
  if (measureImportantUIupdate) {
    for (const entry of list.getEntries()) {
      if (entry.duration > REPORTING_THRESHOLD_MS) {
        // Example here logs to console, but could also report back to analytics
        console.log(entry);
      }
    }
  }
});
observer.observe({ type: 'long-animation-frame', buffered: true });

async function doUIUpdatesWithMeasurements() {
  measureImportantUIupdate = true;
  await doUIUpdates();
  measureImportantUIupdate = false;
}

ดูเฟรมภาพเคลื่อนไหวที่ใช้เวลานานที่สุด

เว็บไซต์อาจต้องการรวบรวมข้อมูลในเฟรมภาพเคลื่อนไหว (หรือเฟรม) ที่ยาวที่สุดเพื่อลดปริมาณข้อมูลที่ต้องใช้บีคอนแทนการกำหนดเกณฑ์ ดังนั้น ไม่ว่าหน้าเว็บจะมีเฟรมภาพเคลื่อนไหวแบบยาวกี่เฟรม ระบบจะส่งกลับเฉพาะข้อมูลของเฟรมภาพเคลื่อนไหวแบบยาว 5, 10 หรือกี่เฟรมที่จำเป็นที่สุด

MAX_LOAFS_TO_CONSIDER = 10;
let longestBlockingLoAFs = [];

const observer = new PerformanceObserver(list => {
  longestBlockingLoAFs = longestBlockingLoAFs.concat(list.getEntries()).sort(
    (a, b) => b.blockingDuration - a.blockingDuration
  ).slice(0, MAX_LOAFS_TO_CONSIDER);
});
observer.observe({ type: 'long-animation-frame', buffered: true });

นอกจากนี้ คุณยังใช้กลยุทธ์เหล่านี้ร่วมกันได้ด้วย โดยดูเฉพาะ LoAF ที่แย่ที่สุด 10 รายการที่มีการโต้ตอบนานกว่า 100 มิลลิวินาที

เมื่อถึงเวลาที่เหมาะสม (ควรเป็นเหตุการณ์ visibilitychange) ให้บีคอนส่งกลับไปยัง Analytics สำหรับการทดสอบในเครื่อง คุณสามารถใช้ console.table เป็นระยะๆ ดังนี้

console.table(longestBlockingLoAFs);

ระบุรูปแบบที่พบบ่อยในเฟรมภาพเคลื่อนไหวแบบยาว

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

วิธีนี้อาจได้ผลดีกับแพลตฟอร์มที่ปรับแต่งได้ ซึ่งสามารถระบุธีมหรือปลั๊กอินที่ทำให้เกิดปัญหาด้านประสิทธิภาพในเว็บไซต์ต่างๆ

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

const observer = new PerformanceObserver(list => {
  const allScripts = list.getEntries().flatMap(entry => entry.scripts);
  const scriptSource = [...new Set(allScripts.map(script => script.sourceURL))];
  const scriptsBySource= scriptSource.map(sourceURL => ([sourceURL,
      allScripts.filter(script => script.sourceURL === sourceURL)
  ]));
  const processedScripts = scriptsBySource.map(([sourceURL, scripts]) => ({
    sourceURL,
    count: scripts.length,
    totalDuration: scripts.reduce((subtotal, script) => subtotal + script.duration, 0)
  }));
  processedScripts.sort((a, b) => b.totalDuration - a.totalDuration);
  // Example here logs to console, but could also report back to analytics
  console.table(processedScripts);
});

observer.observe({type: 'long-animation-frame', buffered: true});

ตัวอย่างเอาต์พุตนี้คือ

(index) sourceURL count totalDuration
0 'https://example.consent.com/consent.js' 1 840
1 'https://example.com/js/analytics.js' 7 628
2 'https://example.chatapp.com/web-chat.js' 1 5

ใช้ Long Animation Frames API ในเครื่องมือ

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

แสดงข้อมูลเฟรมภาพเคลื่อนไหวที่ใช้เวลานานในเครื่องมือสำหรับนักพัฒนาเว็บ

คุณสามารถแสดงเฟรมภาพเคลื่อนไหวที่ยาวในเครื่องมือสำหรับนักพัฒนาเว็บได้โดยใช้ performance.measure() API ซึ่งจะแสดงในแทร็กเวลาของผู้ใช้ในเครื่องมือสำหรับนักพัฒนาเว็บในการติดตามประสิทธิภาพเพื่อแสดงจุดที่ควรมุ่งเน้นการปรับปรุงประสิทธิภาพ โดยใช้ DevTools Extensibility API คุณสามารถแสดงข้อมูลเหล่านี้ในแทร็กของตัวเองได้

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    performance.measure('LoAF', {
      start: entry.startTime,
      end: entry.startTime + entry.duration,
      detail: {
        devtools: {
          dataType: "track-entry",
          track: "Long animation frames",
          trackGroup: "Performance Timeline",
          color: "tertiary-dark",
          tooltipText: 'LoAF'
        }
      }
    });
  }
});

observer.observe({ type: 'long-animation-frame', buffered: true });
การติดตามแผงประสิทธิภาพของ DevTools ด้วยแทร็กที่กำหนดเองซึ่งแสดงข้อมูลเฟรมภาพเคลื่อนไหวแบบยาวที่เปรียบเทียบกับแผนภูมิเปลวไฟหลักได้
การแสดงข้อมูลเฟรมภาพเคลื่อนไหวแบบยาวในเครื่องมือสำหรับนักพัฒนาเว็บ

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

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

ใช้ข้อมูลเฟรมภาพเคลื่อนไหวแบบยาวในเครื่องมืออื่นๆ สำหรับนักพัฒนาซอฟต์แวร์

ส่วนขยาย Web Vitals แสดงค่าในการบันทึกข้อมูลการแก้ไขข้อบกพร่องของข้อมูลสรุปเพื่อวิเคราะห์ปัญหาด้านประสิทธิภาพ

ตอนนี้ยังแสดงข้อมูลเฟรมภาพเคลื่อนไหวแบบยาวสําหรับการเรียกกลับ INP แต่ละครั้งและการโต้ตอบแต่ละครั้งด้วย

การบันทึกคอนโซลส่วนขยาย Web Vitals
การบันทึกคอนโซลของส่วนขยาย Web Vitals จะแสดงข้อมูล LoAF

ใช้ข้อมูลเฟรมภาพเคลื่อนไหวแบบยาวในเครื่องมือทดสอบอัตโนมัติ

ในทํานองเดียวกัน เครื่องมือทดสอบอัตโนมัติในไปป์ไลน์ CI/CD สามารถแสดงรายละเอียดเกี่ยวกับปัญหาด้านประสิทธิภาพที่อาจเกิดขึ้นได้โดยการวัดเฟรมภาพเคลื่อนไหวที่ยาวขณะเรียกใช้ชุดทดสอบต่างๆ

คำถามที่พบบ่อย

คำถามที่พบบ่อยเกี่ยวกับ API นี้ ได้แก่

ทำไมไม่ขยายหรือปรับปรุง Long Tasks API ไปเลย

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

แม้ว่า Long Tasks API อาจได้รับประโยชน์จากฟีเจอร์บางอย่างของ LoAF (เช่น รูปแบบการระบุแหล่งที่มาที่ดีขึ้น) แต่เราเชื่อว่าการมุ่งเน้นที่เฟรมแทนที่จะเป็นงานจะให้ประโยชน์หลายประการ ซึ่งทำให้ API นี้เป็น API ที่แตกต่างจาก Long Tasks API ที่มีอยู่โดยพื้นฐาน

Why do I not have script entries?

ซึ่งอาจบ่งชี้ว่าเฟรมภาพเคลื่อนไหวที่ยาวไม่ได้เกิดจาก JavaScript แต่เกิดจากงานเรนเดอร์ขนาดใหญ่

กรณีนี้ยังอาจเกิดขึ้นเมื่อเฟรมภาพเคลื่อนไหวยาวเกิดจาก JavaScript แต่ไม่สามารถระบุแหล่งที่มาของสคริปต์ได้เนื่องจากเหตุผลด้านความเป็นส่วนตัวหลายประการตามที่ระบุไว้ก่อนหน้านี้ (โดยหลักแล้ว JavaScript นั้นไม่ได้เป็นของหน้าเว็บ)

เหตุใดฉันจึงมีรายการสคริปต์แต่ไม่มีหรือมีข้อมูลแหล่งที่มาแบบจำกัด

ปัญหานี้อาจเกิดขึ้นได้จากหลายสาเหตุ ซึ่งรวมถึงการไม่มีแหล่งที่มาที่ดีที่จะชี้ไปยัง

ข้อมูลสคริปต์จะจํากัดไว้ที่ sourceURL เท่านั้น (ยกเว้นการเปลี่ยนเส้นทาง) สําหรับสคริปต์ no-cors cross-origin โดยมีสตริงว่างสําหรับ sourceFunctionName และ -1 สําหรับ sourceCharPosition ปัญหานี้แก้ไขได้โดยดึงข้อมูลสคริปต์เหล่านั้นโดยใช้ CORS โดยเพิ่ม crossOrigin = "anonymous" ลงในคําเรียก <script>

ตัวอย่างเช่น สคริปต์ Google Tag Manager เริ่มต้นที่จะเพิ่มลงในหน้าเว็บ

<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXXX');</script>
<!-- End Google Tag Manager -->

สามารถปรับปรุงเพื่อเพิ่ม j.crossOrigin = "anonymous" เพื่ออนุญาตให้ระบุรายละเอียดการระบุแหล่งที่มาแบบสมบูรณ์สําหรับ GTM

การดำเนินการนี้จะแทนที่ Long Tasks API ไหม

แม้ว่าเราจะเชื่อว่า Long Animation Frames API เป็น API ที่ดีกว่าและสมบูรณ์กว่าสำหรับการวัดงานที่ใช้เวลานาน แต่ขณะนี้ยังไม่มีแผนที่จะเลิกใช้งาน Long Tasks API

ต้องการความคิดเห็น

คุณสามารถแสดงความคิดเห็นได้ที่รายการปัญหาใน GitHub หรือรายงานข้อบกพร่องในการใช้งาน API ของ Chrome ได้ในเครื่องมือติดตามปัญหาของ Chrome

บทสรุป

Long Animation Frames API เป็น API ใหม่ที่ยอดเยี่ยมซึ่งมีศักยภาพในหลายๆ ด้านเหนือกว่า Long Tasks API ก่อนหน้านี้

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

ขอบเขตของ Long Animation Frames API นั้นครอบคลุมมากกว่า INP และช่วยระบุสาเหตุอื่นๆ ของการอัปเดตที่ช้า ซึ่งอาจส่งผลต่อประสบการณ์การใช้งานเว็บไซต์โดยรวม

ขอขอบคุณ

รูปภาพขนาดย่อโดย Henry Be ใน Unsplash