Uzun Animasyon Çerçeveleri API'si

Long Animation Frames API (uzun animasyon kareleri API'si, LoAF olarak okunur), yavaş kullanıcı arayüzü (UI) güncellemelerini daha iyi anlamak için Long Tasks API'de yapılan bir güncellemedir. Bu, duyarlılığı ölçen Interaction to Next Paint (INP) Core Web Vital metriğini etkileme olasılığı olan yavaş animasyon karelerini veya akıcılığı etkileyen diğer kullanıcı arayüzü takılmalarını belirlemek için yararlı olabilir.

API'nin durumu

Tarayıcı desteği

  • Chrome: 123.
  • Edge: 123.
  • Firefox: Desteklenmez.
  • Safari: Desteklenmez.

Kaynak

Chrome 116'dan Chrome 122'ye kadar bir kaynak denemesinden sonra LoAF API, Chrome 123'ten itibaren kullanıma sunuldu.

Arka plan: Uzun Görevler API'si

Tarayıcı desteği

  • Chrome: 58.
  • Edge: 79.
  • Firefox: Desteklenmez.
  • Safari: Desteklenmez.

Kaynak

Uzun Animasyon Kareleri API'si, Chrome'da bir süredir (Chrome 58'den beri) kullanılabilen Uzun Görevler API'sine bir alternatiftir. Adından da anlaşılacağı gibi Uzun Görev API'si, ana iş parçacığını 50 milisaniye veya daha uzun süre boyunca işgal eden uzun görevleri izlemenize olanak tanır. Uzun görevler, PerformanceLongTaskTiming arayüzü kullanılarak PeformanceObserver ile izlenebilir:

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

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

Uzun görevler, duyarlılık sorunlarına neden olabilir. Bir kullanıcı bir sayfayla etkileşime geçmeye çalışırsa (ör. bir düğmeyi tıklar veya bir menüyü açar) ancak ana iş parçacığı zaten uzun bir görevle ilgileniyorsa bu görev tamamlanana kadar kullanıcı etkileşimi geciktirilir.

Yanıt hızını artırmak için genellikle uzun görevlerin bölünmesi önerilir. Bunun yerine her uzun görev, birden fazla küçük göreve bölünürse etkileşimlere yanıt vermede önemli gecikmeler yaşanmasını önlemek için bu görevler arasında daha önemli görevlerin yürütülmesine izin verilebilir.

Bu nedenle, yanıt vermeyi iyileştirmeye çalışırken genellikle ilk olarak bir performans izlemesi çalıştırıp uzun görevlere bakılır. Bu, Lighthouse gibi laboratuvar tabanlı bir denetim aracı (Uzun ana iş parçacığı görevlerinden kaçının denetimi içerir) veya Chrome Geliştirici Araçları'nda uzun görevleri inceleyerek yapılabilir.

Bu araçlar etkileşimleri içermeyebileceğinden laboratuvar tabanlı testler genellikle duyarlılığı tespit etmek için iyi bir başlangıç noktası değildir. Bu araçlar etkileşimleri içerdiğinde ise olası etkileşimlerin küçük bir alt kümesidir. İdeal olarak, alandaki yavaş etkileşimlerin nedenlerini ölçmeniz gerekir.

Uzun Görevler API'sinin eksiklikleri

Performans Gözlemcisi'ni kullanarak sahada uzun görevleri ölçmek yalnızca kısmen faydalıdır. Gerçekte, uzun bir görevin gerçekleştiği ve ne kadar sürdüğü dışında çok fazla bilgi sağlamaz.

Gerçek Kullanıcı İzleme (RUM) araçları genellikle uzun görevlerin sayısını veya süresini trend olarak belirlemek ya da hangi sayfalarda gerçekleştiğini belirlemek için bu metriği kullanır. Ancak uzun görevin nedenine dair temel ayrıntılar olmadan bu metriğin kullanımı sınırlıdır. Uzun Görevler API'sinde yalnızca bir temel ilişkilendirme modeli vardır. Bu model, en iyi ihtimalle uzun görevin gerçekleştiği kapsayıcıyı (üst düzey doküman veya <iframe>) gösterir ancak onu çağıran komut dosyasını veya işlevi göstermez. Bu durum, aşağıdaki tipik girişte gösterilmiştir:

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

Uzun Görevler API'si de bazı önemli görevleri hariç tutabileceğinden eksik bir görünümdür. Oluşturma gibi bazı güncellemeler ayrı görevlerde gerçekleşir. Bu güncellemelerin, ilgili etkileşimin "toplam çalışmasını" doğru şekilde ölçmesi için ideal olarak önceki yürütmeyle birlikte dahil edilmesi gerekir. Görevlere güvenmenin sınırlamaları hakkında daha fazla bilgi için açıklamanın "Uzun görevler ne zaman yetersiz kalır?" bölümüne bakın.

Son sorun, uzun görevlerin ölçülmesinin yalnızca 50 milisaniye sınırından daha uzun süren bireysel görevler hakkında rapor oluşturmasıdır. Bir animasyon karesi, bu 50 milisaniyelik sınırdan daha küçük birkaç görevden oluşabilir ancak toplu olarak yine de tarayıcının oluşturma özelliğini engelleyebilir.

Long Animation Frames API

Tarayıcı desteği

  • Chrome: 123.
  • Edge: 123.
  • Firefox: Desteklenmez.
  • Safari: Desteklenmez.

Kaynak

Long Animation Frames API (uzun animasyon kareleri API'si) (LoAF), geliştiricilerin duyarlılığı artırmaya ve INP'yi iyileştirmeye yardımcı olacak daha fazla uygulanabilir analiz elde etmesini sağlamak ve akıcılık sorunları hakkında analizler elde etmek için Long Tasks API'nin bazı eksikliklerini gidermeyi amaçlayan yeni bir API'dir.

Sayfanın duyarlılığı, sayfanın kendisiyle yapılan etkileşimlere hızlı yanıt vermesi anlamına gelir. Bu, kullanıcının ihtiyaç duyduğu tüm güncellemeleri zamanında boyayabilmeyi ve bu güncellemelerin yapılmasını engellemekten kaçınmayı içerir. INP için 200 milisaniye veya daha kısa sürede yanıt verilmesi önerilir ancak diğer güncellemeler (ör. animasyonlar) için 200 milisaniye bile çok uzun olabilir.

İşlenmesi uzun süren animasyon çerçeveleri API'si, engelleme çalışmalarını ölçmek için alternatif bir yaklaşımdır. İşlenmesi uzun süren animasyon çerçeveleri API'si, adından da anlaşılacağı gibi işlenmesi uzun süren animasyon çerçevelerini ölçer. Uzun animasyon karesi, oluşturma güncellemesinin 50 milisaniyeden (Long Tasks API'nin eşiğiyle aynı) fazla gecikmesidir.

Uzun animasyon kareleri, oluşturma işlemi gerektiren görevlerin başlangıcından itibaren ölçülür. Olası bir uzun animasyon çerçevesindeki ilk görev oluşturma gerektirmiyorsa oluşturma gerektirmeyen görev tamamlandıktan sonra uzun animasyon çerçevesi sonlandırılır ve sonraki görevle yeni bir olası uzun animasyon çerçevesi başlatılır. Oluşturma işlemi yapılmayan bu tür uzun animasyon kareleri, 50 milisaniyeden uzun olduğunda (renderStart süresi 0 olduğunda) potansiyel olarak engelleyen çalışmanın ölçülmesine izin vermek için Uzun Animasyon Kareleri API'ye dahil edilir.

Uzun animasyon kareleri, PerformanceObserver içeren uzun görevlere benzer şekilde gözlemlenebilir ancak bunun yerine long-animation-frame türüne bakılır:

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

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

Önceki uzun animasyon kareleri, Performans Zaman Çizelgesi'nden de şu şekilde sorgulanabilir:

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

Ancak performans girişleri için bir maxBufferSize vardır. Bu sürenin ardından daha yeni girişler bırakılır. Bu nedenle, PerformanceObserver yaklaşımı önerilir. long-animation-frame arabellek boyutu, long-tasks ile aynı şekilde 200 olarak ayarlanır.

Görevler yerine çerçevelere bakmanın avantajları

Bu konuya görevler açısından değil, kare açısından bakmanın en önemli avantajı, uzun bir animasyonun, toplu olarak uzun bir animasyon karesi oluşturan herhangi bir sayıda görevden oluşabilmesidir. Bu, daha önce bahsedilen son noktayı ele alır. Bu noktada, bir animasyon çerçevesinden önceki birçok küçük, oluşturmayı engelleyen görevin toplamı Long Tasks API tarafından gösterilmeyebilir.

Uzun görevlerde bu alternatif görünümün bir diğer avantajı, çerçevenin tamamının zaman çizelgesi dökümünü sunabilmesidir. Long Tasks API gibi yalnızca bir startTime ve bir duration içermek yerine LoAF, kare süresinin çeşitli bölümlerinin çok daha ayrıntılı bir dökümünü içerir.

Kare zaman damgaları ve süreleri

  • startTime: işlenmesi uzun süren animasyon çerçevesinin, gezinme başlangıç süresine göre başlangıç zamanı.
  • duration: uzun animasyon karesinin süresi (sunum süresi dahil değildir).
  • renderStart: requestAnimationFrame geri çağırma işlevleri, stil ve düzen hesaplaması, yeniden boyutlandır gözlemci ve kesişim gözlemci geri çağırma işlevlerini içeren oluşturma döngüsünün başlangıç zamanı.
  • styleAndLayoutStart: Stil ve düzen hesaplamalarında harcanan sürenin başlangıcı.
  • firstUIEventTimestamp: Bu kare sırasında işlenecek ilk kullanıcı arayüzü etkinliğinin (fare/klavye vb.) zamanı.
  • blockingDuration: Animasyon çerçevesinin girişin veya diğer yüksek öncelikli görevlerin işlenmesini engelleyeceği toplam süre (milisaniye cinsinden).

blockingDuration hakkında açıklama

Uzun bir animasyon karesi, çeşitli görevlerden oluşabilir. blockingDuration, 50 milisaniyeden uzun görev sürelerinin toplamıdır (en uzun görevdeki son oluşturma süresi dahil).

Örneğin, uzun bir animasyon karesi 55 milisaniye ve 65 milisaniyelik iki görevden ve ardından 20 milisaniyelik bir oluşturma işleminden oluşuyorsa duration yaklaşık 140 milisaniye olur ve blockingDuration değeri (55 - 50) + (65 + 20 - 50) = 40 milisaniye olur. 140 milisaniye uzunluğundaki bu animasyon karesi sırasında 40 milisaniye boyunca, karenin girişi engellediği kabul edilir.

duration veya blockingDuration'a bakılacak

Genel 60 hertz ekranlarda tarayıcılar, en az 16,66 milisaniyede bir (sürükleyici güncellemeler sağlamak için) veya giriş işleme gibi yüksek öncelikli bir görevden sonra (duyarlı güncellemeler sağlamak için) bir kare planlamaya çalışır. Ancak giriş yoksa veya başka yüksek öncelikli görev yoksa ancak başka görev kuyruğu varsa tarayıcı, görevler içinde ne kadar iyi dağıtılmış olursa olsun genellikle mevcut kareyi 16, 66 milisaniyeden çok daha uzun süre boyunca devam ettirir. Yani tarayıcı her zaman girişlere öncelik vermeye çalışır ancak oluşturma güncellemeleri yerine bir görev kuyruğuyla uğraşmayı seçebilir. Bunun nedeni, oluşturmanın pahalı bir işlem olmasıdır. Bu nedenle, birden fazla görev için birleştirilmiş bir oluşturma görevini işlemek genellikle genel iş yükünü azaltır.

Bu nedenle, blockingDuration değeri düşük veya sıfır olan uzun animasyon kareleri, girişe duyarlı olmaya devam etmelidir. Bu nedenle, uzun görevleri bölerek blockingDuration değerini azaltmak veya ortadan kaldırmak, INP tarafından ölçülen duyarlılığı iyileştirmenin anahtarıdır.

Ancak blockingDuration'ten bağımsız olarak çok sayıda uzun animasyon karesi, gecikmeli kullanıcı arayüzü güncellemelerini gösterir. Bu nedenle, INP tarafından ölçülen duyarlılıkla ilgili daha az sorun olsa bile, akıcılığı etkileyebilir ve kaydırma veya animasyonlar için gecikmeli bir kullanıcı arayüzü hissine yol açabilir. Bu alandaki sorunları anlamak için duration bölümüne bakın. Ancak bu sorunları, işleri bölerek değil, azaltarak çözmeniz gerektiğinden, bu sorunlar için optimizasyon yapmak daha zor olabilir.

Kare zamanlamaları

Daha önce bahsedilen zaman damgaları, uzun animasyon çerçevesinin zamanlamalara bölünmesine olanak tanır:

Zamanlama Hesaplama
Başlangıç Zamanı startTime
Bitiş Zamanı startTime + duration
Çalışma süresi renderStart ? renderStart - startTime : duration
Oluşturma süresi renderStart ? (startTime + duration) - renderStart: 0
Oluşturma: Düzen öncesi süre styleAndLayoutStart ? styleAndLayoutStart - renderStart : 0
Oluşturma: Stil ve düzen süresi styleAndLayoutStart ? (startTime + duration) - styleAndLayoutStart : 0

Daha iyi komut dosyası ilişkilendirmesi

long-animation-frame giriş türü, uzun bir animasyon çerçevesine katkıda bulunan her komut dosyasıyla ilgili daha iyi ilişkilendirme verileri içerir (5 milisaniyeden uzun komut dosyaları için).

Uzun Görevler API'sine benzer şekilde, bu bilgiler bir ilişkilendirme girişleri dizisi şeklinde sağlanır. Her girişte aşağıdakiler ayrıntılı olarak açıklanır:

  • Hem name hem de EntryType, script değerini döndürür.
  • Komut dosyasının nasıl çağrıldığını belirten anlamlı bir invoker (örneğin, 'IMG#id.onload', 'Window.requestAnimationFrame' veya 'Response.json.then').
  • Komut dosyası giriş noktasının invokerType değeri:
    • user-callback: Web platform API'sinden kaydedilen bilinen bir geri çağırma (ör. setTimeout, requestAnimationFrame).
    • event-listener: Platform etkinliğini dinleyen bir dinleyici (örneğin, click, load, keyup).
    • resolve-promise: Platform vaadinin işleyicisi (örneğin, fetch(). Söz konusu söz verme işlemleri olduğunda, aynı söz verme işlemlerinin tüm işleyicilerinin tek bir "komut dosyası" olarak bir araya getirildiğini unutmayın.).
    • reject-promise: resolve-promise ile aynıdır ancak reddetme içindir.
    • classic-script: Komut dosyası değerlendirmesi (örneğin, <script> veya import())
    • module-script: classic-script ile aynıdır ancak modül komut dosyaları için kullanılır.
  • Söz konusu komut dosyası için ayrı zamanlama verileri:
    • startTime: Giriş işlevinin çağrıldığı zaman.
    • duration: startTime ile sonraki mikro görev kuyruğunun işlenmesinin tamamlanması arasındaki süre.
    • executionStart: Derlemeden sonraki zaman.
    • forcedStyleAndLayoutDuration: Bu işlev içinde zorunlu düzen ve stilin işlenmesi için harcanan toplam süre (aşırı işleme bölümüne bakın).
    • pauseDuration: Eşzamanlı işlemleri "duraklatmada" (uyarı, eşzamanlı XHR) harcanan toplam süre.
  • Komut dosyası kaynak ayrıntıları:
    • sourceURL: Mevcut olduğunda komut dosyası kaynak adı (bulunmazsa boş).
    • sourceFunctionName: Mevcut olduğunda komut dosyası işlevi adı (bulunmazsa boş).
    • sourceCharPosition: Mevcut olduğunda komut dosyası karakter konumu (veya bulunamazsa -1).
  • windowAttribution: Uzun animasyon karesinin yer aldığı kapsayıcı (üst düzey belge veya <iframe>).
  • window: Aynı kaynaktaki pencereye referans.

Kaynak girişleri sağlandığında geliştiriciler, uzun animasyon karesindeki her komut dosyasının, çağıran komut dosyasındaki karakter konumuna kadar tam olarak nasıl çağrıldığını öğrenebilir. Bu, JavaScript kaynağındaki uzun animasyon çerçevesine neden olan tam konumu gösterir.

long-animation-frame performans girişi örneği

Tek bir komut dizisi içeren eksiksiz bir long-animation-frame performans girişi örneği:

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

Görüldüğü gibi bu, web sitelerinin gecikmeli oluşturma güncellemelerinin nedenini anlayabilmesi için benzeri görülmemiş miktarda veri sağlar.

Alanda Long Animation Frames API'yi kullanın

Chrome Geliştirici Araçları ve Lighthouse gibi araçlar, sorunları tespit etmek ve yeniden oluşturmak için yararlı olsa da kullanıcı deneyiminin yalnızca saha verilerinin sağlayabileceği önemli yönlerini gözden kaçırabilecek laboratuvar araçlarıdır.

Long Animation Frames API, Long Tasks API'nin toplayamadığı kullanıcı etkileşimleriyle ilgili önemli bağlamsal verileri toplamak için sahada kullanılmak üzere tasarlanmıştır. Bu sayede, etkileşimle ilgili başka türlü keşfedemeyeceğiniz sorunları tespit edip yeniden oluşturabilirsiniz.

Uzun Animasyon Kareleri API'si desteğini algılayan özellik

API'nin desteklenip desteklenmediğini test etmek için aşağıdaki kodu kullanabilirsiniz:

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

Uzun Animasyon Kareleri API'sinin en belirgin kullanım alanı, Sonraki Boyama İçin Etkileşim (INP) sorunlarını teşhis edip düzeltmeye yardımcı olmaktır. Chrome ekibinin bu API'yi geliştirmesinin başlıca nedenlerinden biri de budur. İyi bir INP, tüm etkileşimlere etkileşimden çerçevenin boyanmasına kadar 200 milisaniye veya daha kısa sürede yanıt verildiği durumdur. Uzun Animasyon Çerçeveleri API'si 50 ms veya daha uzun süren tüm kareleri ölçtüğünden, sorunlu INP'lerin çoğu bu etkileşimleri teşhis etmenize yardımcı olmak için LoAF verilerini içermelidir.

"INP LoAF", aşağıdaki şemada gösterildiği gibi INP etkileşimini içeren LoAF'tır:

Bir sayfadaki uzun animasyon karelerine örnek. INP LoAF vurgulanmıştır.
Bir sayfada, INP etkileşimiyle ilgili olanlardan biri olmak üzere birçok LoAF olabilir.

Bazı durumlarda bir INP etkinliğinin iki LoAF'ı kapsaması mümkündür. Bu durum genellikle, etkileşim çerçevenin önceki çerçevenin oluşturma bölümünü başlatmasından sonra gerçekleşirse ve dolayısıyla etkinlik işleyici sonraki çerçevede işlenirse ortaya çıkar:

Bir sayfadaki uzun animasyon karelerine örnek. INP LoAF vurgulanmıştır.
Bir sayfada, INP etkileşimiyle ilgili olanlardan biri olmak üzere birçok LoAF olabilir.

Bazı nadir durumlarda ikiden fazla LoAF'ı kapsayabilir.

INP etkileşimiyle ilişkili LoAF verilerini kaydetmek, teşhis etmenize yardımcı olmak için INP etkileşimi hakkında çok daha fazla bilgi edinmenizi sağlar. Bu, özellikle giriş gecikmesini anlamak için yararlıdır. Bu karede hangi komut dosyalarının çalıştığını görebilirsiniz.

Ayrıca, kullanıcılarınız için kendi testinize dahil edilmemiş olabilecek başka komut dosyaları çalışabileceğinden, etkinlik işleyicileriniz bu değerler için görülen değerleri yeniden üretmiyorsa açıklanamayan işleme süresi ve sunum gecikmesi hakkında bilgi edinmek de yararlı olabilir.

Bir INP girişini ilgili LoAF girişine veya girişlerine bağlamak için doğrudan API yoktur. Ancak her birinin başlangıç ve bitiş zamanlarını karşılaştırarak kodda bu işlemi yapmak mümkündür (WhyNp örnek komut dosyasına bakın). web-vitals kitaplığı, v4'ten itibaren INP ilişkilendirme arayüzünün longAnimationFramesEntries mülkünde kesişen tüm LoAF'leri içerir.

LoAF girişini veya girişlerini bağladıktan sonra INP ilişkilendirmesi içeren bilgiler ekleyebilirsiniz. scripts nesnesi, bu karelerde başka neler çalıştığını gösterebildiğinden en değerli bilgilerden bazılarını içerir. Bu nedenle, bu verileri analiz hizmetinize geri göndererek etkileşimlerin neden yavaş olduğu hakkında daha fazla bilgi edinebilirsiniz.

INP etkileşimi için LoAF'leri bildirmek, sayfanızdaki en acil etkileşim sorunlarını bulmanın iyi bir yoludur. Her kullanıcı sayfanızla farklı şekilde etkileşim kurabilir ve yeterli miktarda INP ilişkilendirme verisi varsa INP ilişkilendirme verilerine bir dizi olası sorun dahil edilir. Bu sayede, hangi komut dosyalarının yavaş INP ile ilişkili olduğunu görmek için komut dosyalarını hacme göre sıralayabilirsiniz.

Daha uzun animasyon verilerini bir analiz uç noktasına geri gönderme

Yalnızca INP LoAF'larına bakmanın bir dezavantajı, gelecekte INP sorunlarına neden olabilecek iyileştirmeler için diğer potansiyel alanları gözden kaçırmanızdır. Bu durum, büyük bir iyileşme göreceğinizi umarak bir INP sorununu düzelttiğiniz ancak en yavaş ikinci etkileşimin bundan yalnızca biraz daha iyi olduğunu gördüğünüzde kendinizi bir çıkmazda hissetmenize neden olabilir. Bu da INP'nizin çok fazla iyileşme göstermemesine yol açar.

Bu nedenle, yalnızca INP LoAF'ına bakmak yerine sayfanın kullanım ömrü boyunca tüm LoAF'ları dikkate alabilirsiniz:

Birçok LoAF içeren bir sayfa. Bazıları INP etkileşimi olmasa bile etkileşimler sırasında gerçekleşir.
Tüm LoAF'lara bakmak, gelecekteki INP sorunlarını belirlemenize yardımcı olabilir.

Ancak her LoAF girişi önemli miktarda veri içerir. Bu nedenle, analizinizi yalnızca bazı LoAF'larla sınırlamak isteyebilirsiniz. Ayrıca, uzun animasyon karesi girişleri oldukça büyük olabileceğinden geliştiriciler, girişteki hangi verilerin analizlere gönderileceğine karar vermelidir. Örneğin, girişin özet süreleri ve belki de komut dosyası adları veya gerekli olduğu düşünülebilecek diğer bağlamsal verilerin minimum bir kümesi.

Uzun animasyon karesi verilerinin miktarını azaltmak için önerilen bazı kalıplar şunlardır:

Sizin için en uygun kalıp, optimizasyon yolculuğunuzda ne kadar ilerlediğinize ve uzun animasyon karelerinin ne kadar yaygın olduğuna bağlıdır. Daha önce hiç duyarlılığa yönelik optimizasyon yapılmamış bir sitede çok sayıda LoAF olabilir. Bu nedenle, yalnızca etkileşim içeren LoAF'larla sınırlı kalmak, yüksek bir eşik belirlemek veya yalnızca en kötülerine bakmak isteyebilirsiniz.

Yaygın yanıt verme sorunlarını çözerken yalnızca etkileşimlerle veya yüksek engelleme süreleriyle sınırlı kalmayarak ya da eşikleri düşürerek bu kapsamı genişletebilirsiniz.

Etkileşimli uzun animasyon karelerini gözlemleme

Yalnızca INP uzun animasyon çerçevesinin ötesinde analizler elde etmek için etkileşim içeren (firstUIEventTimestamp değerinin varlığıyla algılanabilir) ve blockingDuration değeri yüksek olan tüm LoAF'lara bakabilirsiniz.

Bu, ikisini ilişkilendirmeye çalışmak yerine INP LoAF'lerini izlemenin daha kolay bir yöntemi de olabilir. Bu yöntem daha karmaşık olabilir. Çoğu durumda bu, belirli bir ziyaret için INP LoAF'ı içerir. Bu durumla nadiren karşılaşılırsa bile, diğer kullanıcılar için INP etkileşimi olabileceğinden düzeltilmesi önemli olan uzun etkileşimler yine de gösterilir.

Aşağıdaki kod, kare sırasında bir etkileşimin gerçekleştiği 100 milisaniyeden uzun bir blockingDuration içeren tüm LoAF girişlerini günlüğe kaydeder. 200 milisaniyelik "iyi" INP eşiğinden az olduğu için burada 100 değeri seçilmiştir. İhtiyaçlarınıza bağlı olarak daha yüksek veya daha düşük bir değer seçebilirsiniz.

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

Engelleme süresi yüksek olan uzun animasyon karelerini gözlemleyin

Etkileşimli tüm uzun animasyon karelerine bakmanın bir iyileştirmesi olarak, engelleme süresi yüksek olan tüm uzun animasyon karelerine bakabilirsiniz. Bu uzun animasyon kareleri sırasında kullanıcı etkileşimde bulunursa olası INP sorunlarını gösterir.

Aşağıdaki kod, kare sırasında bir etkileşimin gerçekleştiği ve engelleme süresinin 100 milisaniyeden uzun olduğu tüm LoAF girişlerini günlüğe kaydeder. Burada 100, olası sorunlu kareleri belirlemeye yardımcı olmak için 200 milisaniyelik "iyi" INP eşiğinden daha az olduğu ve bildirilen uzun animasyon karelerinin miktarını en aza indirdiği için seçilmiştir. İhtiyaçlarınıza bağlı olarak daha yüksek veya daha düşük bir değer seçebilirsiniz.

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

Sorunsuzluğu artırmak için kritik kullanıcı arayüzü güncellemeleri sırasında uzun animasyon kareleri gözlemleyin

Daha önce de belirtildiği gibi, uzun animasyon karelerinin yüksek engelleme süresine bakmak, giriş duyarlılığını ele almanıza yardımcı olabilir. Ancak pürüzsüzlük için tüm uzun animasyon karelerine uzun bir duration ile bakmanız gerekir.

Bu durum oldukça gürültülü olabileceğinden, bu ölçümleri aşağıdaki gibi bir kalıpla anahtar noktalarla sınırlamak isteyebilirsiniz:

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

En kötü uzun animasyon karelerini gözlemleme

Siteler, işaretlenmesi gereken veri hacmini azaltmak için belirli bir eşik yerine en uzun animasyon karesi (veya kareleri) hakkında veri toplamak isteyebilir. Dolayısıyla, bir sayfanın ne kadar uzun animasyon karesi yaşadığına bakılmaksızın yalnızca en kötü bir, beş, on veya kesinlikle gerekli olan uzun animasyon karelerinin verileri geri gönderilir.

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

Bu stratejiler birlikte de kullanılabilir. Yalnızca 100 milisaniyeden uzun etkileşimlere sahip en kötü 10 LoAF'a bakın.

Uygun zamanda (ideal olarak visibilitychange etkinliğinde) Analytics'e geri dönün. Yerel test için console.table'ü düzenli olarak kullanabilirsiniz:

console.table(longestBlockingLoAFs);

Uzun animasyon karelerindeki yaygın kalıpları belirleme

Alternatif bir strateji, uzun animasyon karesi girişlerinde en çok görünen ortak komut dosyalarına bakmaktır. Tekrarlanan ihlalleri tespit etmek için veriler komut dosyası ve karakter konumu düzeyinde geri raporlanabilir.

Bu yöntem, performans sorunlarına neden olan temaların veya eklentilerin çeşitli sitelerde tespit edilebildiği özelleştirilebilir platformlarda özellikle iyi sonuç verebilir.

Uzun animasyon karelerindeki yaygın komut dosyalarının (veya üçüncü taraf kaynaklarının) yürütme süresi toplanabilir ve bir site veya site koleksiyonu genelinde uzun animasyon karelerine ortak olarak katkıda bulunanları belirlemek için raporlanabilir. Örneğin, URL'lere bakmak için:

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

Bu çıkışa örnek olarak şunlar verilebilir:

(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

Araçlarda Long Animation Frames API'yi kullanma

API, yerel hata ayıklama için ek geliştirici araçları kullanmaya da olanak tanır. Lighthouse ve Chrome Geliştirici Araçları gibi bazı araçlar, daha düşük düzeydeki izleme ayrıntılarını kullanarak bu verilerin çoğunu toplayabilse de bu üst düzey API'nin kullanılması, diğer araçların bu verilere erişmesine olanak tanıyabilir.

DevTools'da işlenmesi uzun süren animasyon çerçevesi verilerini gösterme

performance.measure() API'sini kullanarak DevTools'da uzun animasyon kareleri gösterebilirsiniz. Bu kareler, performans iyileştirmeleri için çabalarınızı nereye odaklayacağınızı göstermek amacıyla performans izlemelerinde DevTools kullanıcı zamanlamaları kanalında gösterilir. DevTools Genişletilebilirlik API'si kullanılarak bunlar kendi kanallarında bile gösterilebilir:

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 });
Ana alev grafiğiyle karşılaştırılabilen uzun animasyon karesi verilerini gösteren özel bir kanal içeren DevTools Performans Paneli izlemesi.
DevTools'ta uzun animasyon karesi verilerini gösterme.

Uzun vadede, uzun animasyon kareleri büyük olasılıkla DevTools'a dahil edilecek ancak önceki kod snippet'i, bu süre zarfında burada gösterilmesine olanak tanır.

Önceki şekildeki ilk girişte, tarayıcının aralarında oluşturma işlemi yapmak yerine aynı uzun animasyon çerçevesinde birden fazla görevi birlikte işlediği de gösterilmektedir. Daha önce de belirtildiği gibi, yüksek öncelikli giriş görevi olmadığı ancak görev kuyruğu olduğunda bu durumla karşılaşılabilir. İlk uzun görevde tamamlanması gereken bazı oluşturma güncellemeleri vardır (aksi takdirde mevcut uzun animasyon karesi bu işlemden sonra sıfırlanır ve bir sonraki görevle yeni bir kare başlar). Ancak tarayıcı, bu oluşturma işlemini hemen yerine getirmek yerine bir dizi ek görevi işledikten sonra uzun oluşturma görevini yerine getirerek uzun animasyon karesini sonlandırdı. Bu, gecikmeli oluşturma işlemlerini belirlemek için yalnızca uzun görevler yerine DevTools'ta uzun animasyon karelerine bakmanın yararlılığını gösterir.

Uzun animasyon karesi verilerini diğer geliştirici araçlarında kullanma

Web Vitals uzantısı, performans sorunlarını teşhis etmek için günlük kaydı özeti hata ayıklama bilgilerindeki değeri göstermiştir.

Artık her INP geri çağırması ve her etkileşim için uzun animasyon karesi verileri de gösteriliyor:

Web Vitals uzantısı konsol günlük kaydı.
Web Vitals uzantısı konsol günlük kaydı, LoAF verilerini gösterir.

Otomatik test araçlarında uzun animasyon karesi verilerini kullanma

Benzer şekilde, CI/CD ardışık düzenlerindeki otomatik test araçları, çeşitli test paketlerini çalıştırırken uzun animasyon karelerini ölçerek olası performans sorunlarıyla ilgili ayrıntıları gösterebilir.

SSS

Bu API ile ilgili sık sorulan sorulardan bazıları şunlardır:

Neden Long Tasks API'yi genişletmiyor veya bu API üzerinde iterasyon yapmıyorsunuz?

Bu, potansiyel yanıt verme sorunlarının benzer ancak nihayetinde farklı bir ölçümünü raporlamaya yönelik alternatif bir yaklaşımdır. Mevcut Uzun Görevler API'sine dayanan sitelerin, mevcut kullanım alanlarını kesintiye uğratmamak için çalışmaya devam etmesini sağlamak önemlidir.

Uzun Görevler API'si, LoAF'ın bazı özelliklerinden (ör. daha iyi ilişkilendirme modeli) yararlanabilir. Ancak görevler yerine çerçevelere odaklanmanın, bu API'yi mevcut Uzun Görevler API'sinden temel olarak farklı kılan birçok avantaj sağladığına inanıyoruz.

Why do I not have script entries?

Bu durum, uzun animasyon çerçevesinin JavaScript nedeniyle değil, büyük oluşturma çalışması nedeniyle olduğunu gösterebilir.

Bu durum, uzun animasyon çerçevesi JavaScript nedeniyle olmasına rağmen komut dosyası ilişkilendirmesi daha önce belirtildiği gibi çeşitli gizlilik nedenlerinden (özellikle de JavaScript'in sayfaya ait olmaması) dolayı sağlanamadığında da ortaya çıkabilir.

Neden komut dosyası girişlerim var ancak kaynak bilgileri yok veya sınırlı?

Bu durum, yönlendirmek için iyi bir kaynak olmaması da dahil olmak üzere çeşitli nedenlerden kaynaklanabilir.

Komut dosyası bilgileri, no-cors cross-origin komut dosyaları için yalnızca sourceURL ile sınırlı olacak (yönlendirmeler hariç). sourceFunctionName için boş bir dize, sourceCharPosition için ise -1 kullanılacak. Bu sorun, <script> çağrısına crossOrigin = "anonymous" ekleyerek bu komut dosyalarını CORS kullanarak getirerek çözülebilir.

Örneğin, sayfaya eklenecek varsayılan Google Etiket Yöneticisi komut dosyası:

<!-- 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 -->

GTM için tam ilişkilendirme ayrıntılarının sağlanmasına izin vermek üzere j.crossOrigin = "anonymous" eklemek için geliştirilebilir.

Bu API, Long Tasks API'nin yerini alacak mı?

Uzun Animasyon Kareleri API'nin uzun görevleri ölçmek için daha iyi ve daha kapsamlı bir API olduğuna inanıyoruz ancak şu anda Uzun Görevler API'nin desteğini sonlandırmayı planlamıyoruz.

Geri bildirim istendi

Geri bildirimlerinizi GitHub Issues listesinde paylaşabilir veya Chrome'un API'yi uygulamasındaki hataları Chrome'un sorun izleyicisinde bildirebilirsiniz.

Sonuç

Uzun Animasyon Kareleri API'si, önceki Uzun Görevler API'sine kıyasla birçok potansiyel avantaja sahip heyecan verici yeni bir API'dir.

INP tarafından ölçülen yanıt verme sorunlarını ele almak için önemli bir araç olduğunu kanıtlamıştır. INP, optimize edilmesi zor bir metriktir ve bu API, Chrome Ekibi'nin geliştiricilerin sorunları tespit edip gidermesini kolaylaştırmaya çalıştığı yöntemlerden biridir.

Ancak Uzun Animasyon Kareleri API'sinin kapsamı yalnızca INP'nin ötesine geçer ve web sitesinin kullanıcı deneyiminin genel akıcılığı üzerinde etkisi olabilecek yavaş güncellemelerin diğer nedenlerini belirlemenize yardımcı olabilir.

Teşekkür ederiz

Unsplash'taki Henry Be tarafından oluşturulan küçük resim.