Die Long Animation Frames API (LoAF-ausgesprochen Lo-Af) ist ein Update für die Long Tasks API, um langsame Aktualisierungen der Benutzeroberfläche (UI) besser zu verstehen. Dies kann nützlich sein, um langsame Animationsframes zu identifizieren, die wahrscheinlich den Core Web Vital-Messwert Interaction to Next Paint (INP) beeinflussen, der die Reaktionsfähigkeit misst, oder um andere UI-Verzögerungen zu identifizieren, die sich auf die Glättigkeit auswirken.
Status der API
Unterstützte Browser
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
Nach einem Ursprungstest von Chrome 116 zu Chrome 122 wurde die LoAF API von Chrome 123 ausgeliefert.
Hintergrund: Die Long Tasks API
Unterstützte Browser
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
Das Long Animation Frames API ist eine Alternative zur Long Tasks API, die seit einiger Zeit (seit Chrome 58) in Chrome verfügbar ist. Wie der Name schon sagt, können Sie mit der Long Task API lange Aufgaben überwachen, d. h. Aufgaben, die den Hauptthread mindestens 50 Millisekunden lang in Anspruch nehmen. Lange Aufgaben können über die PerformanceLongTaskTiming
-Oberfläche mit einem PeformanceObserver
überwacht werden:
const observer = new PerformanceObserver((list) => {
console.log(list.getEntries());
});
observer.observe({ type: 'longtask', buffered: true });
Bei langen Aufgaben kommt es wahrscheinlich zu Reaktionsproblemen. Wenn ein Nutzer versucht, mit einer Seite zu interagieren – z. B. durch Klicken auf eine Schaltfläche oder Öffnen eines Menüs –, aber der Hauptthread bereits eine lange Aufgabe verarbeitet, verzögert sich die Interaktion des Nutzers auf den Abschluss dieser Aufgabe.
Um die Reaktionsfähigkeit zu verbessern, wird oft empfohlen, lange Aufgaben in Abschnitte zu unterteilen. Wenn jede lange Aufgabe stattdessen in eine Reihe mehrerer, kleinerer Aufgaben aufgeteilt wird, können wichtigere Aufgaben zwischen ihnen ausgeführt werden, um erhebliche Verzögerungen bei der Reaktion auf Interaktionen zu vermeiden.
Wenn Sie also die Reaktionsfähigkeit verbessern möchten, besteht der erste Anhaltspunkt oft darin, eine Leistungs-Trace auszuführen und sich lange Aufgaben anzusehen. Dies kann über ein Lab-basiertes Auditing-Tool wie Lighthouse (mit der Prüfung Lange Hauptthreadaufgaben vermeiden) oder durch Ansehen langer Aufgaben in den Chrome-Entwicklertools erfolgen.
Labbasierte Tests sind häufig ein schlechter Ausgangspunkt, um Probleme mit der Reaktionsfähigkeit zu erkennen, da diese Tools möglicherweise keine Interaktionen enthalten. Wenn sie dies tun, stellen sie einen kleinen Teil der wahrscheinlichen Interaktionen dar. Idealerweise sollten Sie die Ursachen für langsame Interaktionen in der Praxis messen.
Schwachstellen der Long Tasks API
Das Messen langer Aufgaben vor Ort mit einem Leistungsbeobachter ist nur wenig hilfreich. Tatsächlich liefert sie nicht so viele Informationen, abgesehen von der Tatsache, dass eine lange Aufgabe stattgefunden hat und wie lange sie gedauert hat.
RUM-Tools (Real User Monitoring) verwenden diese Funktion häufig, um die Anzahl oder Dauer langer Aufgaben zu bestimmen oder um zu ermitteln, auf welchen Seiten sie auftreten. Ohne die zugrunde liegenden Details zur Ursache der langen Aufgabe ist dies jedoch nur begrenzt nützlich. Die Long Tasks API hat nur ein grundlegendes Attributionsmodell, das Ihnen bestenfalls nur den Container angibt, in dem die lange Aufgabe ausgeführt wurde (das Dokument der obersten Ebene oder ein <iframe>
), nicht jedoch das Skript oder die Funktion, von der sie aufgerufen wurde, wie ein typischer Eintrag zeigt:
{
"name": "unknown",
"entryType": "longtask",
"startTime": 31.799999997019768,
"duration": 136,
"attribution": [
{
"name": "unknown",
"entryType": "taskattribution",
"startTime": 0,
"duration": 0,
"containerType": "window",
"containerSrc": "",
"containerId": "",
"containerName": ""
}
]
}
Die Long Tasks API ist ebenfalls unvollständig, da sie möglicherweise auch einige wichtige Aufgaben ausschließt. Einige Aktualisierungen, wie das Rendering, finden in separaten Aufgaben statt, die idealerweise zusammen mit der vorherigen Ausführung enthalten sein sollten, wodurch diese Aktualisierung zur genauen Messung der „Gesamtarbeit“ geführt hat für diese Interaktion. Weitere Einzelheiten zu den Einschränkungen, die sich aus der Verwendung von Aufgaben ergeben, finden Sie im Abschnitt Wofür lange Aufgaben unerreichbar sind? der Erklärung.
Das letzte Problem ist, dass beim Messen langer Aufgaben nur einzelne Aufgaben erfasst werden, die länger als 50 Millisekunden dauern. Ein Animations-Frame könnte aus mehreren Aufgaben bestehen, die kleiner als diese 50 Millisekunden sind, aber trotzdem die Rendering-Funktion des Browsers blockieren.
Long Animation Frames API
Unterstützte Browser
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
Die Long Animation Frames API (LoAF) ist eine neue API, die darauf abzielt, einige der Mängel der Long Tasks API zu beheben, damit Entwickler mehr umsetzbare Informationen erhalten, um Reaktionsprobleme zu beheben und INP zu verbessern.
Gute Reaktionsfähigkeit bedeutet, dass eine Seite schnell auf Interaktionen mit ihr reagiert. Dazu gehört, dass Sie alle vom Nutzer benötigten Updates rechtzeitig darstellen und vermeiden können, dass diese Updates blockiert werden. Für INP wird empfohlen, innerhalb von 200 Millisekunden oder weniger zu antworten. Bei anderen Aktualisierungen (z. B. Animationen) kann es sogar zu lang sein.
Das Long Animation Frames API ist ein alternativer Ansatz zur Messung der Blockierarbeit. Anstatt die einzelnen Aufgaben zu messen, misst die Long Animation Frames API – wie der Name schon sagt – lange Animationsframes. Bei einem langen Animationsframe wird eine Renderingaktualisierung mehr als 50 Millisekunden verzögert (dies entspricht dem Grenzwert für die Long Tasks API).
Frames für lange Animationen können auf ähnliche Weise wie lange Aufgaben mit einem PerformanceObserver
beobachtet werden, aber in diesem Fall wird stattdessen der Typ long-animation-frame
betrachtet:
const observer = new PerformanceObserver((list) => {
console.log(list.getEntries());
});
observer.observe({ type: 'long-animation-frame', buffered: true });
So können Sie auch vorherige lange Animationsframes aus der Leistungszeitachse abfragen:
const loafs = performance.getEntriesByType('long-animation-frame');
Es gibt jedoch einen maxBufferSize
für Leistungseinträge, nach dem neuere Einträge gelöscht werden. Daher ist der Ansatz "PerformanceObserver" die empfohlene Methode. Die Puffergröße long-animation-frame
ist auf 200 festgelegt, genau wie für long-tasks
.
Vorteile von Frames anstelle von Aufgaben
Der Hauptvorteil dieser Betrachtung aus der Frame-Perspektive statt aus der Aufgabenperspektive besteht darin, dass eine lange Animation aus einer beliebigen Anzahl von Aufgaben bestehen kann, die insgesamt zu einem langen Animationsframe geführt haben. Damit wird der letzte Punkt, der zuvor erwähnt wurde, von der Long Tasks API nicht mehr angezeigt.
Ein weiterer Vorteil dieser alternativen Ansicht für lange Aufgaben ist die Möglichkeit, zeitliche Aufschlüsselungen des gesamten Frames bereitzustellen. Anstelle von startTime
und duration
wie bei der Long Tasks API enthält LoAF eine viel detailliertere Aufschlüsselung der verschiedenen Teile der Framedauer, darunter:
startTime
: die Startzeit des langen Animationsframes relativ zur Startzeit der Navigation.duration
: die Dauer des langen Animationsframes (ohne die Präsentationszeit).renderStart
: die Startzeit des Renderingzyklus, dierequestAnimationFrame
-Callbacks, Stil- und Layoutberechnung sowie die Größe der Beobachter- und Intersektions-Beobachter-Callbacks umfasst.styleAndLayoutStart
: der Beginn des Zeitraums für Stil- und Layoutberechnungen.firstUIEventTimestamp
: die Zeit des ersten UI-Ereignisses (Maus/Tastatur usw.), das im Verlauf dieses Frames verarbeitet werden soll.blockingDuration
: die Dauer in Millisekunden, für die der Animationsframe blockiert wurde.
Durch diese Zeitstempel kann der lange Animationsframe in Timings unterteilt werden:
Timing | Berechnung |
---|---|
Beginn | startTime |
Ende | startTime + duration |
Arbeitsdauer | renderStart ? renderStart - startTime : duration |
Renderingdauer | renderStart ? (startTime + duration) - renderStart: 0 |
Rendering: Dauer vor dem Layout | styleAndLayoutStart ? styleAndLayoutStart - renderStart : 0 |
Rendering: Stil und Layoutdauer | styleAndLayoutStart ? (startTime + duration) - styleAndLayoutStart : 0 |
Weitere Informationen zu diesen einzelnen Zeitabständen finden Sie in der Erläuterung. Dort finden Sie detaillierte Angaben dazu, welche Aktivität zu einem langen Animationsframe beigetragen hat.
Bessere Attribution
Der Eintragstyp long-animation-frame
enthält bessere Attributionsdaten für jedes Skript, das zu einem langen Animationsframe beigetragen hat.
Ähnlich wie bei der Long Tasks API wird diese in einem Array von Attributionseinträgen bereitgestellt, die jeweils folgende Details enthalten:
- Sowohl
name
als auchEntryType
gebenscript
zurück. - Eine aussagekräftige
invoker
, die angibt, wie das Script aufgerufen wurde, z. B.'IMG#id.onload'
,'Window.requestAnimationFrame'
oder'Response.json.then'
. - Der
invokerType
des Skripteinstiegspunkts: <ph type="x-smartling-placeholder">- </ph>
user-callback
: Ein bekannter Callback, der von einer Webplattform-API registriert wurde (z. B.setTimeout
,requestAnimationFrame
).event-listener
: Listener für ein Plattformereignis (z. B.click
,load
,keyup
).resolve-promise
: Handler eines Plattformversprechens (z. B.fetch()
). Im Fall von Promise-Objekten werden alle Handler derselben Promise als ein „Script“ kombiniert..
reject-promise
: Gemäßresolve-promise
, aber für die Ablehnung.classic-script
: Skriptauswertung (z. B.<script>
oderimport()
)module-script
: Entsprichtclassic-script
, aber für Modulskripts.
- Separate Zeitdaten für dieses Skript:
<ph type="x-smartling-placeholder">
- </ph>
startTime
: Zeitpunkt, zu dem die Eintragsfunktion aufgerufen wurde.duration
: Der Zeitraum zwischen demstartTime
und dem Zeitpunkt, zu dem die Verarbeitung der nachfolgenden Mikroaufgabenwarteschlange abgeschlossen ist.executionStart
: Die Zeit nach der Kompilierung.forcedStyleAndLayoutDuration
: Die Gesamtzeit, die für die Verarbeitung des erzwungenen Layouts und Stils in dieser Funktion aufgewendet wurde (siehe Thrashing).pauseDuration
: Gesamtzeit im „Pausieren“ synchrone Vorgänge (Benachrichtigung, synchrone XHR)
- Details zur Skriptquelle:
<ph type="x-smartling-placeholder">
- </ph>
sourceURL
: Der Name der Skriptressource, falls verfügbar (oder leer, wenn er nicht gefunden wird).sourceFunctionName
: Der Name der Skriptfunktion, falls verfügbar (oder leer, wenn er nicht gefunden wird).sourceCharPosition
: Die Zeichenposition des Skripts, falls verfügbar (oder -1, wenn sie nicht gefunden wurde).
windowAttribution
: Der Container (das Dokument der obersten Ebene oder ein<iframe>
), in dem der lange Animationsframe aufgetreten ist.window
: Ein Verweis auf dasselbe Ursprungsfenster.
Sofern angegeben, können Entwickler mithilfe der Quelleinträge genau nachvollziehen, wie jedes Skript im langen Animationsframe bis zur Zeichenposition im aufrufenden Skript aufgerufen wurde. Dadurch wird die genaue Position in einer JavaScript-Ressource angegeben, die zum langen Animationsframe geführt hat.
<ph type="x-smartling-placeholder">Beispiel für einen long-animation-frame
-Leistungseintrag
Hier ein vollständiges Beispiel für einen long-animation-frame
-Leistungseintrag mit einem einzelnen Skript:
{
"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
}
Dadurch ergibt sich für Websites eine noch nie dagewesene Menge an Daten, um die Ursache für verzögerte Rendering-Aktualisierungen zu ermitteln.
Verwenden Sie die Long Animation Frames API im Außendienst
Tools wie die Chrome-Entwicklertools und Lighthouse sind zwar nützlich, um Probleme zu erkennen und zu reproduzieren. Sie sind Labortools, die wichtige Aspekte der Nutzererfahrung übersehen, die nur mit Felddaten möglich sind.
Das Long Animation Frames API wurde für den Einsatz vor Ort entwickelt, um wichtige Kontextdaten für Nutzerinteraktionen zu sammeln, die die Long Tasks API nicht konnte. So können Sie Probleme bei der Interaktivität identifizieren und reproduzieren, die Ihnen sonst möglicherweise nicht aufgefallen wären.
Unterstützung für die Erkennung von Long Animation Frames API
Mit dem folgenden Code können Sie testen, ob die API unterstützt wird:
if (PerformanceObserver.supportedEntryTypes.includes('long-animation-frame')) {
// Monitor LoAFs
}
Link zur längsten INP-Interaktion
Der offensichtlichste Anwendungsfall für die Long Animation Frames API ist die Diagnose und Behebung von Problemen mit Interaction to Next Paint (INP). Dies war einer der Hauptgründe, warum das Chrome-Team diese API entwickelt hat. Bei einem guten INP werden alle Interaktionen in maximal 200 Millisekunden von der Interaktion bis zum Zeichnen des Frames beantwortet. Da die Long Animation Frames API alle Frames misst, die 50 ms oder mehr dauern, sollten die meisten problematischen INP-Daten LoAF-Daten zur Diagnose dieser Interaktionen enthalten.
Das „INP LoAF“ ist das LoAF, das die INP-Interaktion enthält, wie im folgenden Diagramm dargestellt:
<ph type="x-smartling-placeholder">In einigen Fällen ist es möglich, dass ein INP-Ereignis zwei LoAFs umfasst. Dies geschieht in der Regel dann, wenn die Interaktion erfolgt, nachdem der Frame das Rendering des vorherigen Frames gestartet hat und der Ereignis-Handler sie daher im nächsten Frame verarbeitet hat:
<ph type="x-smartling-placeholder">In seltenen Fällen ist es sogar möglich, dass es sich über mehr als zwei LoAFs erstreckt.
Wenn Sie die LoAF-Daten im Zusammenhang mit der INP-Interaktion aufzeichnen, erhalten Sie viel mehr Informationen über die INP-Interaktion, die Ihnen bei der Diagnose helfen kann. Dies ist besonders hilfreich, um die Eingabeverzögerung zu verstehen, da Sie sehen können, welche anderen Skripts in diesem Frame ausgeführt wurden.
Es kann auch hilfreich sein, die unerklärlichen Verarbeitungsdauer und Verzögerungen bei der Präsentation zu verstehen, wenn Ihre Event-Handler die für diese erfassten Werte nicht reproduzieren, da möglicherweise andere Skripts für Ihre Nutzer ausgeführt werden, die möglicherweise nicht in Ihren eigenen Tests enthalten sind.
Es gibt keine direkte API, um einen INP-Eintrag mit dem zugehörigen LoAF-Eintrag oder den zugehörigen LoAF-Einträgen zu verknüpfen. Dies ist jedoch im Code möglich, indem die Start- und Endzeiten der einzelnen Einträge verglichen werden (siehe WhyNp).
Die web-vitals
-Bibliothek enthält alle sich überschneidenden LoAFs in der longAnimationFramesEntries
-Property der INP-Attributionsoberfläche aus Version 4.
Nachdem Sie den oder die LoAF-Einträge verknüpft haben, können Sie Informationen mit der INP-Zuordnung hinzufügen. Das scripts
-Objekt enthält einige der wertvollsten Informationen, da es zeigen kann, was sonst in diesen Frames lief. Durch das Beaconing dieser Daten an Ihren Analysedienst können Sie also besser nachvollziehen, warum Interaktionen langsam waren.
Wenn Sie LoAFs für die INP-Interaktion melden, können Sie die wichtigsten Interaktivitätsprobleme auf Ihrer Seite ermitteln. Da jeder Nutzer anders mit Ihrer Seite interagiert, können bei einer ausreichenden Menge an INP-Attributionsdaten verschiedene potenzielle Probleme in die INP-Attributionsdaten einfließen. So können Sie Skripts nach Volumen sortieren, um zu sehen, welche Skripts mit langsamem INP korrelieren.
Mehr lange Animationsdaten an einen Analyseendpunkt senden
Ein Nachteil, wenn Sie sich nur die INP-LoAF(s) ansehen, ist, dass Ihnen möglicherweise andere Verbesserungsmöglichkeiten entgehen, die zukünftige INP-Probleme verursachen könnten. Wenn Sie ein INP-Problem beheben, erwarten Sie eine enorme Verbesserung, aber die nächste langsamste Interaktion ist nur geringfügig besser, sodass sich Ihr INP-Problem nicht stark verbessert.
Anstatt also nur die INP-LoAF in den Mittelpunkt zu stellen, sollten Sie alle LoAFs für die gesamte Lebensdauer der Seite berücksichtigen:
<ph type="x-smartling-placeholder">Jeder LoAF-Eintrag enthält jedoch erhebliche Daten, sodass Sie wahrscheinlich nicht alle Daten mit einem Beacon zurücksenden möchten. Stattdessen sollten Sie Ihre Analyse auf einige LoAFs oder Daten beschränken.
Hier einige Vorschläge für Muster:
- Lange Animationsframes mit Interaktionen beobachten
- Animationsframes beobachten, die einen bestimmten Grenzwert überschreiten
- Die schlechtesten langen Animationsframes beobachten
- Häufige Muster in langen Animationsframes identifizieren
Welches dieser Muster für Sie am besten funktioniert, hängt davon ab, wie weit Sie bereits bei der Optimierung sind und wie lange Animationsframes häufig vorkommen. Bei einer Website, die noch nie im Hinblick auf die Reaktionsfähigkeit optimiert wurde, kann es viele LoAFs geben, die Sie auf LoAFs mit Interaktionen beschränken, einen hohen Schwellenwert festlegen oder sich nur die schlechtesten ansehen möchten. Wenn Sie häufig auftretende Probleme mit der Reaktionsfähigkeit beheben, können Sie diese erweitern, indem Sie sich nicht nur auf Interaktionen beschränken und Grenzwerte senken oder nach bestimmten Mustern suchen.
Lange Animationsframes mit Interaktionen beobachten
Um Informationen über den langen INP-Animationsframe hinaus zu erhalten, können Sie sich alle LoAFs mit Interaktionen ansehen (die durch das Vorhandensein eines firstUIEventTimestamp
-Werts erkannt werden).
Dies kann auch eine einfachere Methode zur Überwachung der INP-LoAFs sein, als zu versuchen, die beiden zu korrelieren, was komplexer sein kann. In den meisten Fällen umfasst dies die INP-LoAF für einen bestimmten Besuch. Falls dies nicht der Fall ist, werden in seltenen Fällen trotzdem lange Interaktionen angezeigt, die behoben werden müssen, da diese die INP-Interaktion für andere Nutzer sein können.
Mit dem folgenden Code werden alle LoAF-Einträge protokolliert, die größer als 150 Millisekunden sind und bei denen während des Frames eine Interaktion stattfand. Hier wird die 150 ausgewählt, weil sie etwas kleiner ist als die „gute“ 200-Millisekunde INP-Grenzwert Sie können je nach Ihren Anforderungen einen höheren oder niedrigeren Wert wählen.
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 });
Animationsframes beobachten, die einen bestimmten Grenzwert überschreiten
Eine andere Strategie wäre, alle LoAFs zu überwachen und diejenigen, die über einem bestimmten Schwellenwert liegen, zur späteren Analyse zurück an einen Analyseendpunkt zu senden:
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 });
Da die langen Animationsframe-Einträge sehr groß sein können, sollten Entwickler entscheiden, welche Daten des Eintrags an Analytics gesendet werden sollen. Zum Beispiel die Zusammenfassungszeiten des Eintrags und möglicherweise die Skriptnamen oder eine andere Mindestmenge an Kontextdaten, die als erforderlich erachtet werden.
Die schlechtesten langen Animationsframes beobachten
Anstatt einen festgelegten Grenzwert festzulegen, sollten Websites Daten für den längsten Animationsframe (oder die längsten Frames) erfassen, um das Datenvolumen für das Beaconing zu reduzieren. Unabhängig von der Anzahl der langen Animationsframes auf einer Seite werden also nur die Daten für die schlechtesten, fünf oder die unbedingt notwendige lange Animationsframes zurückgegeben.
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 });
Diese Strategien können auch kombiniert werden. Betrachten Sie nur die zehn schlechtesten LoAFs mit Interaktionen, die länger als 150 Millisekunden sind.
Zum passenden Zeitpunkt (idealerweise beim Ereignis visibilitychange
) wird das Beacon in Analytics zurückgegeben. Für lokale Tests kannst du console.table
regelmäßig verwenden:
console.table(longestBlockingLoAFs);
Häufige Muster in langen Animationsframes identifizieren
Eine alternative Strategie wäre, gängige Skripts zu betrachten, die am häufigsten in Frameeinträgen für lange Animations-Frames vorkommen. Daten können auf Skript- und Zeichenpositionsebene gemeldet werden, um Wiederholungstäter zu identifizieren.
Dies eignet sich besonders für anpassbare Plattformen, auf denen Themes oder Plug-ins, die Leistungsprobleme verursachen, auf einer Reihe von Websites identifiziert werden können.
Die Ausführungszeit gängiger Skripte oder der Herkunft Dritter in langen Animationsframes kann zusammengefasst und zurückgemeldet werden, um zu ermitteln, welche Personen häufig zu langen Animationsframes auf einer Website oder einer Reihe von Websites beigetragen haben. So können Sie sich z. B. URLs ansehen:
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});
Und ein Beispiel für diese Ausgabe ist:
(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 in Tools verwenden
Die API bietet auch zusätzliche Entwicklertools für die lokale Fehlerbehebung. Mit einigen Tools wie Lighthouse und den Chrome-Entwicklertools konnten zwar viele dieser Daten mit Low-Level-Tracing-Details erhoben werden, aber mit dieser übergeordneten API könnten andere Tools auf diese Daten zugreifen.
Daten zu langen Animationsframes in den Entwicklertools ansehen
Du kannst in den Entwicklertools mit der performance.measure()
API lange Animationsframes anzeigen, die dann im Entwicklertools-Track für das Nutzertiming in Leistungs-Traces angezeigt werden. So siehst du, worauf du dich bei der Leistungssteigerung konzentrieren solltest:
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 });
Auf lange Sicht wird es wahrscheinlich in die Entwicklertools selbst integriert werden, aber mit dem vorherigen Code-Snippet kann es dort in der Zwischenzeit angezeigt werden.
Daten zu langen Animationsframes in anderen Entwicklertools verwenden
Die Web Vitals-Erweiterung hat den Wert in den Debug-Informationen der Zusammenfassungszusammenfassung angezeigt, um Leistungsprobleme zu diagnostizieren.
Für jeden INP-Callback und jede Interaktion werden jetzt auch Frame-Daten für lange Animationen angezeigt:
<ph type="x-smartling-placeholder">Daten zu langen Animationsframes in automatisierten Testtools verwenden
Ähnlich können automatisierte Testtools in CI/CD-Pipelines Details zu potenziellen Leistungsproblemen liefern, indem lange Animationsframes während der Ausführung verschiedener Testsuiten gemessen werden.
FAQ
Zu dieser API gehören unter anderem:
Warum nicht einfach die Long Tasks API erweitern oder iterieren?
Dies ist eine alternative Möglichkeit, eine ähnliche – aber letztendlich andere – Messung möglicher Probleme bei der Reaktionszeit zu melden. Es ist wichtig, dafür zu sorgen, dass Websites, die auf der bestehenden Long Tasks API basieren, weiterhin funktionieren, um bestehende Anwendungsfälle nicht zu beeinträchtigen.
Obwohl die Long Tasks API von einigen der LoAF-Funktionen (z. B. einem besseren Attributionsmodell) profitieren kann, sind wir der Meinung, dass die Fokussierung auf Frames statt Aufgaben viele Vorteile bietet, die diese API grundlegend von der bestehenden Long Tasks API unterscheiden.
Warum habe ich keine Skripteinträge?
Dies kann darauf hindeuten, dass der lange Animations-Frame nicht auf JavaScript, sondern vielmehr auf eine umfangreiche Rendering-Aufwand zurückzuführen ist.
Das kann auch der Fall sein, wenn der lange Animationsframe auf JavaScript zurückzuführen ist, aber die Skriptzuordnung aus verschiedenen Datenschutzgründen (siehe oben) nicht angegeben werden kann (hauptsächlich, weil die Seite nicht der Inhaber von JavaScript ist).
Warum habe ich Skripteinträge, aber keine oder nur begrenzte Quelleninformationen?
Dafür kann es verschiedene Gründe geben, z. B. kein guter Verweis.
Skriptinformationen sind auch für no-cors cross-origin
-Skripts eingeschränkt. Dieses Problem lässt sich jedoch beheben, indem Sie diese Skripts mithilfe von CORS abrufen, indem Sie crossOrigin = "anonymous"
zum <script>
-Aufruf hinzufügen.
Hier sehen Sie beispielsweise das standardmäßige Google Tag Manager-Skript, das Sie der Seite hinzufügen möchten:
<!-- 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 -->
Kann erweitert werden, um j.crossOrigin = "anonymous"
hinzuzufügen, damit vollständige Attributionsdetails für GTM angegeben werden können
Wird die Long Tasks API dadurch ersetzt?
Wir sind der Meinung, dass das Long Animation Frames API eine bessere und umfassendere API für die Messung langer Aufgaben ist. Derzeit gibt es jedoch keine Pläne, die Long Tasks API einzustellen.
Feedback erwünscht
Feedback können Sie über die GitHub-Problemliste geben. Fehler bei der Implementierung der API in Chrome können Sie über die Problemverfolgung von Chrome melden.
Fazit
Das Long Animation Frames API ist eine spannende neue API mit vielen potenziellen Vorteilen gegenüber der vorherigen Long Tasks API.
Es hat sich laut INP als ein wichtiges Instrument bei der Behebung von Reaktionsproblemen erwiesen. Der Messwert „INP“ lässt sich nur schwer optimieren. Mit dieser API möchte das Chrome-Team Entwicklern die Identifizierung und Behebung von Problemen erleichtern.
Der Umfang der Long Animation Frames API geht jedoch über INP hinaus und kann dabei helfen, andere Ursachen für langsame Updates zu identifizieren, die sich auf die allgemeine reibungslose Nutzererfahrung einer Website auswirken können.