Long Animation Frames API

Long Animation Frames API (با تلفظ LoAF Lo-Af) به‌روزرسانی Long Tasks API است تا درک بهتری از به‌روزرسانی‌های رابط کاربر آهسته (UI) ارائه دهد. این می‌تواند برای شناسایی فریم‌های پویانمایی آهسته که احتمالاً بر معیار Interaction to Next Paint (INP) Core Web Vital که میزان پاسخ‌دهی را اندازه‌گیری می‌کند، تأثیر می‌گذارد، یا برای شناسایی سایر جابه‌جایی‌های رابط کاربری که بر صافی تأثیر می‌گذارند، مفید باشد.

وضعیت API

پشتیبانی مرورگر

  • کروم: 123.
  • لبه: 123.
  • فایرفاکس: پشتیبانی نمی شود.
  • سافاری: پشتیبانی نمی شود.

منبع

پس از آزمایش اولیه از Chrome 116 به Chrome 122 ، LoAF API از Chrome 123 ارسال شد.

پس زمینه: Long Tasks API

پشتیبانی مرورگر

  • کروم: 58.
  • لبه: 79.
  • فایرفاکس: پشتیبانی نمی شود.
  • سافاری: پشتیبانی نمی شود.

منبع

Long Animation Frames API جایگزینی برای Long Tasks API است که مدتی است (از Chrome 58) در Chrome موجود است. همانطور که از نامش پیداست، Long Task API به شما امکان می دهد کارهای طولانی را نظارت کنید، کارهایی که رشته اصلی را برای 50 میلی ثانیه یا بیشتر اشغال می کنند. کارهای طولانی را می توان با استفاده از رابط PerformanceLongTaskTiming ، با PeformanceObserver مانیتور کرد:

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

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

کارهای طولانی احتمالا باعث مشکلات پاسخگویی می شوند. اگر کاربر سعی کند با یک صفحه تعامل داشته باشد - به عنوان مثال، روی یک دکمه کلیک کند یا یک منو باز کند - اما موضوع اصلی در حال حاضر با یک کار طولانی سروکار دارد، در این صورت تعامل کاربر در انتظار تکمیل آن کار به تاخیر می افتد .

برای بهبود پاسخگویی، اغلب توصیه می شود کارهای طولانی را از بین ببرید . اگر هر کار طولانی به جای آن به مجموعه ای از وظایف متعدد و کوچکتر تقسیم شود، ممکن است اجازه دهد تا وظایف مهم تری در بین آنها اجرا شود تا از تأخیر قابل توجه در پاسخگویی به تعاملات جلوگیری شود.

بنابراین هنگام تلاش برای بهبود پاسخگویی، اولین تلاش اغلب اجرای یک ردیابی عملکرد و بررسی وظایف طولانی است. این می‌تواند از طریق یک ابزار ممیزی مبتنی بر آزمایشگاه مانند Lighthouse (که دارای ممیزی از کارهای طولانی رشته اصلی اجتناب شود )، یا با مشاهده کارهای طولانی در ابزار توسعه کروم باشد.

آزمایش مبتنی بر آزمایشگاه اغلب محل شروع ضعیفی برای شناسایی مسائل مربوط به پاسخگویی است، زیرا این ابزارها ممکن است شامل تعاملات نباشند—در صورت وجود، زیرمجموعه کوچکی از تعاملات احتمالی هستند. در حالت ایده‌آل، می‌توانید دلایل کندی تعاملات را در این زمینه اندازه‌گیری کنید.

کاستی های Long Tasks API

اندازه‌گیری کارهای طولانی در میدان با استفاده از مشاهده‌گر عملکرد فقط تا حدودی مفید است. در واقع، اطلاعات زیادی فراتر از این که یک کار طولانی اتفاق افتاده است، و اینکه چقدر طول کشیده است، نمی دهد.

ابزارهای نظارت بر کاربر واقعی (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.
  • لبه: 123.
  • فایرفاکس: پشتیبانی نمی شود.
  • سافاری: پشتیبانی نمی شود.

منبع

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 ، محاسبه سبک و طرح‌بندی، تغییر اندازه ناظر و تماس‌های ناظر تقاطع است.
  • styleAndLayoutStart : آغاز دوره زمانی صرف شده در محاسبات سبک و چیدمان.
  • firstUIEventTimestamp : زمان اولین رویداد UI (ماوس/صفحه کلید و غیره) که در طول این فریم مدیریت می شود.
  • blockingDuration : کل مدت زمان بر حسب میلی ثانیه که فریم انیمیشن پردازش ورودی یا سایر وظایف با اولویت بالا را مسدود می کند.

توضیحی در مورد blockingDuration

یک فریم انیمیشن طولانی ممکن است از تعدادی کار تشکیل شده باشد. blockingDuration مجموع مدت زمان کار بیشتر از 50 میلی ثانیه است (شامل مدت زمان رندر نهایی در طولانی ترین کار).

برای مثال، اگر یک فریم انیمیشن طولانی از دو کار 55 میلی‌ثانیه و 65 میلی‌ثانیه و به دنبال آن یک رندر 20 میلی‌ثانیه‌ای تشکیل شده باشد، آن‌گاه duration تقریباً 140 میلی‌ثانیه با مدت blockingDuration (55 - 50) + (65 + 20) خواهد بود. - 50) = 40 میلی ثانیه. برای 40 میلی ثانیه در طول این فریم انیمیشن طولانی 140 میلی ثانیه، فریم از مدیریت ورودی مسدود شده در نظر گرفته شد.

چه به duration نگاه کنیم یا blockingDuration

برای نمایشگر معمولی 60 هرتز، یک مرورگر سعی می‌کند حداقل هر 16.66 میلی‌ثانیه یک فریم را برنامه‌ریزی کند (برای اطمینان از به‌روزرسانی‌های روان)، یا بعد از یک کار با اولویت بالا مانند مدیریت ورودی (برای اطمینان از به‌روزرسانی‌های پاسخگو). با این حال، اگر هیچ ورودی وجود نداشته باشد - و یا سایر وظایف با اولویت بالا - اما یک صف از وظایف دیگر وجود داشته باشد، مرورگر معمولاً فریم فعلی را به خوبی از 16.66 میلی‌ثانیه گذشته است، مهم نیست که وظایف در آن چقدر به خوبی تقسیم شده باشند. یعنی مرورگر همیشه سعی می‌کند ورودی‌ها را اولویت‌بندی کند، اما ممکن است صفی از وظایف را نسبت به به‌روزرسانی‌های رندر انتخاب کند. این به دلیل گران بودن رندر است، بنابراین پردازش یک کار رندر ترکیبی برای چندین کار معمولاً منجر به کاهش کلی کار می شود.

بنابراین، فریم‌های انیمیشن طولانی با blockingDuration کم یا صفر باید همچنان به ورودی پاسخ دهند. بنابراین، کاهش یا حذف blockingDuration با شکستن وظایف طولانی، کلیدی برای بهبود پاسخگویی است که توسط INP اندازه‌گیری می‌شود.

با این حال، بسیاری از فریم‌های انیمیشن طولانی، بدون در نظر گرفتن blockingDuration مدت زمان به‌روزرسانی‌های رابط کاربری را نشان می‌دهد که با تأخیر مواجه می‌شوند و بنابراین همچنان می‌توانند بر روان بودن تأثیر بگذارند و منجر به احساس تأخیر در رابط کاربری برای پیمایش یا انیمیشن‌ها شوند، حتی اگر این موارد برای پاسخ‌دهی کمتر مشکلی ایجاد کنند. اندازه گیری شده توسط 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 : Handler یک وعده پلتفرم (مثلا fetch() . توجه داشته باشید که در مورد وعده‌ها، همه کنترل‌کننده‌های همان وعده‌ها به عنوان یک «اسکریپت» با هم ترکیب می‌شوند) .
    • reject-promise : طبق resolve-promise ، اما برای رد.
    • classic-script : ارزیابی اسکریپت (به عنوان مثال، <script> یا import() )
    • module-script : همانند classic-script ، اما برای اسکریپت های ماژول.
  • داده های زمان بندی را برای آن اسکریپت جدا کنید:
    • startTime : زمانی که تابع ورودی فراخوانی شد.
    • duration : مدت زمان بین startTime و زمانی که پردازش صف ریز وظیفه بعدی به پایان رسید.
    • executionStart : زمان پس از کامپایل.
    • forcedStyleAndLayoutDuration : کل زمان صرف شده برای پردازش طرح و استایل اجباری در داخل این تابع (به thrashing مراجعه کنید).
    • pauseDuration : کل زمان صرف شده در "مکث" عملیات همزمان (هشدار، XHR همزمان).
  • جزئیات منبع اسکریپت:
    • sourceURL : نام منبع اسکریپت در صورت وجود (یا خالی در صورت یافت نشدن).
    • sourceFunctionName : نام تابع اسکریپت که در دسترس است (یا خالی اگر یافت نشد).
    • sourceCharPosition : موقعیت کاراکتر اسکریپت در صورت موجود بودن (یا -1 در صورت یافت نشدن).
  • windowAttribution : محفظه (سند سطح بالا، یا یک <iframe> ) که قاب انیمیشن طولانی در آن قرار دارد.
  • window : ارجاع به پنجره همان منبع.

در صورت ارائه، ورودی‌های منبع به توسعه‌دهندگان اجازه می‌دهد تا دقیقاً بدانند که هر اسکریپت در قاب طولانی انیمیشن چگونه فراخوانی شده است، تا موقعیت کاراکتر در اسکریپت فراخوان. این مکان دقیق را در یک منبع جاوا اسکریپت نشان می دهد که منجر به قاب طولانی انیمیشن می شود.

نمونه‌ای از ورودی اجرای 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 DevTools و Lighthouse - اگرچه برای کشف و بازتولید مسائل مفید هستند - ابزارهای آزمایشگاهی هستند که ممکن است جنبه‌های مهم تجربه کاربر را که فقط داده‌های میدانی می‌توانند ارائه کنند، از دست بدهند.

Long Animation Frames API طراحی شده است تا در میدان مورد استفاده قرار گیرد تا داده‌های زمینه‌ای مهم برای تعاملات کاربر را جمع‌آوری کند که Long Tasks API قادر به انجام آن نبود. این می تواند به شما در شناسایی و بازتولید مسائلی با تعامل که ممکن است در غیر این صورت کشف نکرده باشید، کمک کند.

قابلیت شناسایی Long Animation Frames 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 باشند تا به شما در تشخیص کمک کنند. آن فعل و انفعالات

"INP LoAF" LoAF است که شامل تعامل INP است، همانطور که در نمودار زیر نشان داده شده است:

نمونه‌هایی از فریم‌های انیمیشن بلند در یک صفحه، با برجسته‌سازی INP LoAF.
یک صفحه ممکن است LoAF های زیادی داشته باشد که یکی از آنها به تعامل INP مربوط می شود.

در برخی موارد ممکن است که یک رویداد INP دو LoAF را در بر بگیرد—معمولاً اگر تعامل پس از شروع بخش رندر فریم قبلی توسط فریم اتفاق بیفتد و بنابراین کنترل کننده رویداد در فریم بعدی پردازش می‌شود:

نمونه‌هایی از فریم‌های انیمیشن بلند در یک صفحه، با برجسته‌سازی INP LoAF.
یک صفحه ممکن است LoAF های زیادی داشته باشد که یکی از آنها به تعامل INP مربوط می شود.

حتی ممکن است در برخی شرایط نادر، بیش از دو LoAF را در بر گیرد.

ثبت داده‌های LoAF(های) مرتبط با تعامل INP به شما امکان می‌دهد اطلاعات بیشتری در مورد تعامل INP برای کمک به تشخیص آن به دست آورید. این به ویژه برای درک تاخیر ورودی مفید است: همانطور که می بینید چه اسکریپت های دیگری در آن فریم اجرا می شدند.

همچنین درک مدت زمان پردازش غیرقابل توضیح و تأخیر ارائه می‌تواند مفید باشد اگر کنترل‌کننده‌های رویداد شما مقادیری را که برای آن‌ها مشاهده می‌شود بازتولید نمی‌کنند، زیرا ممکن است اسکریپت‌های دیگری برای کاربران شما در حال اجرا باشند که ممکن است در آزمایش خود شما لحاظ نشده باشند.

هیچ API مستقیمی برای پیوند دادن یک ورودی INP با ورودی یا ورودی های LoAF مربوط به آن وجود ندارد، اگرچه می توان این کار را به صورت کد با مقایسه زمان شروع و پایان هر کدام انجام داد (به اسکریپت مثال WhyNp مراجعه کنید). کتابخانه web-vitals شامل تمام LoAF های متقاطع در ویژگی longAnimationFramesEntries رابط انتساب INP از نسخه 4 است.

هنگامی که ورودی یا ورودی های LoAF را پیوند دادید، می توانید اطلاعاتی را با انتساب INP اضافه کنید. شی scripts حاوی برخی از ارزشمندترین اطلاعات است، زیرا می تواند نشان دهد که چه چیز دیگری در آن فریم ها در حال اجرا است، بنابراین بازگرداندن آن داده ها به سرویس تجزیه و تحلیل شما به شما این امکان را می دهد که بیشتر در مورد چرایی کندی تعاملات درک کنید.

گزارش LoAF ها برای تعامل INP راه خوبی برای یافتن مهم ترین مسائل تعاملی در صفحه شما است. هر کاربر ممکن است با صفحه شما تعامل متفاوتی داشته باشد و با حجم کافی از داده های انتساب INP، تعدادی از مشکلات احتمالی در داده های انتساب INP گنجانده می شود. این به شما امکان می دهد اسکریپت ها را بر اساس حجم مرتب کنید تا ببینید کدام اسکریپت با INP کند مرتبط است.

داده‌های طولانی‌تر انیمیشن را به نقطه پایانی تجزیه و تحلیل گزارش دهید

یکی از نکات منفی نگاه کردن به LoAF(های) INP این است که ممکن است سایر زمینه‌های بالقوه برای بهبودهایی را که ممکن است باعث مشکلات INP در آینده شود از دست بدهید. این می‌تواند منجر به احساس تعقیب دنبال خود شود، جایی که مشکل INP را برطرف می‌کنید و انتظار دارید پیشرفت بزرگی را مشاهده کنید، فقط برای یافتن اینکه کندترین تعامل بعدی فقط مقدار کمی بهتر از آن است، بنابراین INP شما بهبود چندانی نمی‌یابد.

بنابراین به جای اینکه فقط به INP LoAF نگاه کنید، ممکن است بخواهید همه LoAF ها را در طول عمر صفحه در نظر بگیرید:

صفحه ای با تعداد زیادی LoAF، که برخی از آنها در طول تعاملات اتفاق می افتد، حتی اگر تعامل INP نباشد.
نگاهی به همه LoAF ها می تواند به شناسایی مشکلات آینده INP کمک کند.

با این حال، هر ورودی LoAF حاوی داده های قابل توجهی است، بنابراین احتمالاً می خواهید تجزیه و تحلیل خود را فقط به برخی از LoAF ها محدود کنید. علاوه بر این، از آنجایی که ورودی های فریم انیمیشن طولانی می تواند بسیار بزرگ باشد، توسعه دهندگان باید تصمیم بگیرند که چه داده هایی از ورودی باید به تجزیه و تحلیل ارسال شود. به عنوان مثال، زمان‌های خلاصه ورودی و شاید نام‌های اسکریپت، یا حداقل مجموعه دیگری از داده‌های زمینه‌ای دیگر که ممکن است ضروری تلقی شوند.

برخی از الگوهای پیشنهادی برای کاهش حجم داده‌های فریم انیمیشن طولانی عبارتند از:

اینکه کدام یک از این الگوها برای شما بهتر عمل می‌کند، بستگی به این دارد که چقدر در مسیر بهینه‌سازی شما قرار گرفته‌اید و فریم‌های انیمیشن طولانی چقدر رایج هستند. برای سایتی که قبلاً هرگز برای پاسخگویی بهینه سازی نشده است، ممکن است LoAF های زیادی وجود داشته باشد که بخواهید فقط به LoAF ها با تعامل محدود کنید، یا آستانه بالایی را تعیین کنید، یا فقط به بدترین آنها نگاه کنید.

همانطور که مشکلات رایج پاسخگویی خود را حل می کنید، می توانید این را با محدود نکردن فقط به تعاملات یا مدت زمان مسدود کردن بالا یا با کاهش آستانه گسترش دهید.

فریم های طولانی انیمیشن را با تعامل مشاهده کنید

برای به دست آوردن اطلاعاتی فراتر از قاب انیمیشن طولانی INP، می‌توانید همه LoAFها را با فعل و انفعالات (که می‌توان با حضور یک مقدار firstUIEventTimestamp تشخیص داد) با مدت blockingDuration بالا مشاهده کرد.

این همچنین می‌تواند روش ساده‌تری برای نظارت بر INP LoAFها به جای تلاش برای مرتبط کردن این دو باشد، که می‌تواند پیچیده‌تر باشد. در بیشتر موارد، این شامل INP LoAF برای یک بازدید معین می‌شود، و در موارد نادری که باز هم نشان داده نمی‌شود، باز هم فعل و انفعالات طولانی را نشان می‌دهد که رفع آنها مهم است، زیرا ممکن است تعامل 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 });

برای بهبود نرمی، فریم‌های طولانی انیمیشن را در طول به‌روزرسانی‌های مهم رابط کاربری مشاهده کنید

همانطور که قبلا ذکر شد، نگاه کردن به فریم‌های انیمیشن طولانی مدت مسدود شدن بالا می‌تواند به پاسخگویی ورودی کمک کند. اما برای صاف بودن باید به تمام فریم های انیمیشن طولانی با 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;
}

بدترین فریم های طولانی انیمیشن را مشاهده کنید

به جای داشتن آستانه تعیین شده، سایت‌ها ممکن است بخواهند داده‌ها را در طولانی‌ترین قاب انیمیشن (یا فریم‌ها) جمع‌آوری کنند، تا حجم داده‌هایی را که باید نشان داده شود، کاهش دهند. بنابراین مهم نیست که یک صفحه چند فریم انیمیشن طولانی را تجربه می کند، تنها اطلاعات مربوط به بدترین فریم های متحرک، پنج، ده، یا هر تعداد فریم های طولانی انیمیشنی که کاملا ضروری است، نشان داده می شود.

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

این استراتژی‌ها را نیز می‌توان با هم ترکیب کرد - فقط به 10 بدترین LoAF با فعل و انفعالات طولانی‌تر از 100 میلی‌ثانیه نگاه کنید.

در زمان مناسب ( به طور ایده آل در رویداد visibilitychange ) چراغ راهنما به تجزیه و تحلیل باز می گردد. برای آزمایش محلی می‌توانید به‌طور دوره‌ای از 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 سطح بالاتر می‌تواند به ابزارهای دیگر اجازه دسترسی به این داده‌ها را بدهد.

داده های فریم های انیمیشن بلند سطحی را در DevTools مشاهده کنید

می‌توانید با استفاده از API performance.measure() فریم‌های انیمیشن طولانی را در DevTools نشان دهید، که سپس در مسیر زمان‌بندی کاربر DevTools در ردیابی عملکرد نمایش داده می‌شوند تا نشان دهند که تلاش‌های خود را برای بهبود عملکرد کجا متمرکز کنید. با استفاده از 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 با یک مسیر سفارشی که داده‌های قاب انیمیشن طولانی را نشان می‌دهد که می‌تواند با نمودار شعله اصلی مقایسه شود.
نمایش داده های قاب انیمیشن طولانی در DevTools.

فریم‌های طولانی‌مدت انیمیشن احتمالاً در خود DevTools گنجانده می‌شوند، اما قطعه کد قبلی به آن اجازه می‌دهد تا در این مدت در آنجا ظاهر شود.

اولین ورودی در شکل قبلی همچنین نشان می‌دهد که مرورگر به جای رندر کردن بین آنها، چندین کار را با هم در یک قاب انیمیشن طولانی پردازش کرده است. همانطور که قبلاً ذکر شد این می تواند زمانی اتفاق بیفتد که وظایف ورودی با اولویت بالا وجود ندارد، اما یک صف از وظایف وجود دارد. اولین کار طولانی دارای برخی به‌روزرسانی‌های رندر برای تکمیل است (در غیر این صورت، فریم انیمیشن طولانی فعلی پس از آن بازنشانی می‌شود و یک کار جدید با کار بعدی شروع می‌شود)، اما مرورگر به‌جای انجام فوری آن رندر، تعدادی از موارد را پردازش کرده است. وظایف اضافی را انجام داد و تنها پس از آن وظیفه رندر طولانی را انجام داد و فریم طولانی انیمیشن را پایان داد. این کار سودمندی نگاه کردن به فریم های طولانی انیمیشن در DevTools را به جای کارهای طولانی برای کمک به شناسایی رندرهای تاخیری نشان می دهد.

از داده‌های فریم‌های انیمیشن طولانی در سایر ابزارهای توسعه‌دهنده استفاده کنید

برنامه افزودنی Web Vitals ارزش ثبت اطلاعات اشکال زدایی خلاصه را برای تشخیص مشکلات عملکرد نشان داده است .

اکنون همچنین داده‌های فریم انیمیشن طولانی را برای هر تماس INP و هر تعامل نشان می‌دهد:

ورود به سیستم کنسول برنامه افزودنی Web Vitals.
Web Vitals Extension کنسول ثبت اطلاعات LoAF را سطح می کند.

از داده های فریم های انیمیشن بلند در ابزارهای تست خودکار استفاده کنید

به طور مشابه، ابزارهای تست خودکار در خطوط لوله CI/CD می‌توانند با اندازه‌گیری فریم‌های طولانی انیمیشن در حین اجرای مجموعه‌های آزمایشی مختلف، جزئیات مربوط به مشکلات عملکرد بالقوه را نشان دهند.

سوالات متداول

برخی از سوالات متداول در مورد این API عبارتند از:

چرا روی Long Tasks API فقط تمدید یا تکرار نمی شود؟

این یک نگاه جایگزین به گزارش یک اندازه گیری مشابه – اما در نهایت متفاوت – از مسائل احتمالی پاسخگویی است. مهم است که اطمینان حاصل شود که سایت‌های متکی به Long Tasks API به کار خود ادامه می‌دهند تا از ایجاد اختلال در موارد استفاده موجود جلوگیری شود.

در حالی که Long Tasks API ممکن است از برخی از ویژگی‌های LoAF (مانند یک مدل انتساب بهتر) بهره مند شود، ما معتقدیم که تمرکز بر فریم‌ها به جای وظایف، مزایای زیادی را ارائه می‌کند که این API را اساساً متفاوت از Long Tasks API موجود می‌سازد.

چرا ورودی های اسکریپت ندارم؟

این ممکن است نشان دهد که فریم طولانی انیمیشن به دلیل جاوا اسکپت نیست، بلکه به دلیل کار رندر بزرگ است.

این همچنین می تواند زمانی اتفاق بیفتد که فریم طولانی انیمیشن به دلیل جاوا اسکریپت باشد ، اما به دلایل مختلف حفظ حریم خصوصی همانطور که قبلا ذکر شد (در درجه اول اینکه جاوا اسکریپت متعلق به صفحه نیست) نمی توان انتساب اسکریپت را ارائه کرد.

چرا ورودی های اسکریپت را دارم اما اطلاعات منبع ندارد یا محدود است؟

این ممکن است به دلایل مختلفی اتفاق بیفتد، از جمله اینکه منبع خوبی برای اشاره وجود ندارد .

اطلاعات اسکریپت نیز برای اسکریپت‌های no-cors cross-origin ، با یک رشته خالی برای sourceFunctionName و یک -1 برای sourceCharPosition ، فقط به sourceURL (به استثنای هرگونه تغییر مسیر) محدود می‌شود. این مشکل را می توان با واکشی آن اسکریپت ها با استفاده از 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 ارائه کرد، یا اشکالات در اجرای Chrome از API را می توان در ردیاب مشکل کروم ثبت کرد.

نتیجه گیری

Long Animation Frames API یک API جدید و هیجان انگیز با مزایای بالقوه زیادی نسبت به Long Tasks API قبلی است.

ثابت شده است که این یک ابزار کلیدی برای رسیدگی به مسائل مربوط به پاسخگویی است که توسط INP اندازه گیری می شود. INP معیاری چالش برانگیز برای بهینه سازی است و این API راهی است که تیم Chrome به دنبال تسهیل شناسایی و رسیدگی به مشکلات برای توسعه دهندگان است.

دامنه Long Animation Frames API فراتر از فقط INP است، و می تواند به شناسایی دلایل دیگر به روز رسانی کند کمک کند که می تواند بر روان بودن کلی تجربه کاربری یک وب سایت تأثیر بگذارد.

قدردانی ها

تصویر کوچک توسط هنری بی در Unsplash .