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

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

สถานะของ API

การสนับสนุนเบราว์เซอร์

  • 123
  • x
  • x
  • x

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

Long Tasks API

การสนับสนุนเบราว์เซอร์

  • 58
  • 79
  • x
  • x

แหล่งที่มา

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

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

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

{
  "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

การสนับสนุนเบราว์เซอร์

  • 123
  • x
  • x
  • x

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

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

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

คุณดูเฟรมของภาพเคลื่อนไหวที่ใช้เวลานานได้ในลักษณะเดียวกันกับงานที่ใช้เวลานานด้วย 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 อาจไม่แสดงการรวมงานบล็อกการแสดงผลขนาดเล็กจำนวนมากก่อนเฟรมภาพเคลื่อนไหว

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

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

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

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

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

การระบุแหล่งที่มาที่ดียิ่งขึ้น

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

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

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

Long Animation Frames API จะเปิดใช้โดยค่าเริ่มต้นจาก Chrome 123

การใช้ Long Animation Frames API ในช่อง

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

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

ฟีเจอร์ตรวจพบการรองรับ Long Animation Frames API

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

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

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

if ('PerformanceLongAnimationFrameTiming' in window) {
  // Monitor LoAFs
}

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

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

const REPORTING_THRESHOLD_MS = 150;

const observer = new PerformanceObserver(list => {
  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 });

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

สังเกตเฟรมแอนิเมชันแบบยาวที่แย่ที่สุด

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

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 });

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

console.table(longestBlockingLoAFs);

การลิงก์ไปยังการโต้ตอบ INP ที่ยาวที่สุด

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

ปัจจุบันไม่มี API โดยตรงที่จะลิงก์รายการ INP กับรายการ LoAF ที่เกี่ยวข้อง แต่คุณสามารถดำเนินการได้ในโค้ดโดยการเปรียบเทียบเวลาเริ่มต้นและเวลาสิ้นสุดของแต่ละรายการ (ดูสคริปต์ตัวอย่างนี้)

การรายงานเฟรมของภาพเคลื่อนไหวที่ยาวและมีการโต้ตอบ

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

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

const REPORTING_THRESHOLD_MS = 150;

const observer = new PerformanceObserver(list => {
    for (const entry of list.getEntries()) {
      if (entry.duration > 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 });

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

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

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

เวลาประมวลผลของสคริปต์ทั่วไปหรือต้นทางของบุคคลที่สามในเฟรมภาพเคลื่อนไหวขนาดยาวอาจสรุปและรายงานกลับเพื่อระบุผู้มีส่วนร่วมในเฟรมภาพเคลื่อนไหวขนาดยาวในเว็บไซต์หรือกลุ่มเว็บไซต์ได้ ตัวอย่างเช่น หากคุณต้องการดู 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 ซึ่งจากนั้นจะแสดงในการติดตามระยะเวลาของผู้ใช้ในเครื่องมือสำหรับนักพัฒนาเว็บในการติดตามประสิทธิภาพเพื่อแสดงให้เห็นว่าควรปรับปรุงประสิทธิภาพในส่วนใด

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    performance.measure('LoAF', {
      start: entry.startTime,
      end: entry.startTime + entry.duration,
    });
  }
});

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

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

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

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

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

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

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

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

ทำไมไม่ลองขยายหรือทำซ้ำการใช้ Long Tasks API

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

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

ฟีเจอร์นี้จะมาแทนที่ 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