Eine neue JavaScript API, mit der Sie einen Kompromiss zwischen Ladeleistung und Reaktionsfähigkeit bei der Eingabe vermeiden können.
Ein schnelles Laden ist schwierig. Websites, die ihre Inhalte derzeit mithilfe von JavaScript rendern zwischen Lastleistung und Eingabequalität Reaktionsfähigkeit: entweder alle Arbeiten ausführen, die für die Displaywerbung erforderlich sind auf einmal (bessere Ladeleistung, schlechtere Reaktionsfähigkeit bei der Eingabe) oder die Arbeit in kleinere Aufgaben aufteilen, um reaktionsschnell Eingabe und Darstellung (schlechte Ladeleistung, bessere Eingabe Sensibilität).
Um diesen Kompromiss zu vermeiden, schlug Facebook vor und implementierte
isInputPending()
-API in Chromium verwenden, um die Reaktionsfähigkeit zu verbessern, ohne
nachtragend sein. Aufgrund von Feedback zum Ursprungstest haben wir einige Aktualisierungen am
API verfügbar. Wir freuen uns, Ihnen mitteilen zu können, dass die API jetzt standardmäßig in Chromium ausgeliefert wird.
87!
Browserkompatibilität
Unterstützte Browser
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
isInputPending()
wird in Chromium-basierten Browsern ab Version 87 ausgeliefert.
Kein anderer Browser hat die Absicht signalisiert, die API zu versenden.
Hintergrund
Die meiste Arbeit im heutigen JS-System wird in einem einzigen Thread erledigt: dem Hauptthread. Dies bietet Entwicklern ein robustes Ausführungsmodell, (insbesondere die Reaktionsfähigkeit) kann drastisch beeinträchtigt werden, wenn das Skript für einen längeren Zeitraum . Wenn die Seite viel Arbeit macht, während ein Eingabeereignis ausgelöst wird, Beispiel: Die Seite verarbeitet das Klickeingabeereignis erst nach der abgeschlossen wird.
Die aktuelle Best Practice besteht darin, dieses Problem anzugehen, indem Sie die um JavaScript in kleinere Blöcke aufzuteilen. Während die Seite geladen wird, und dann die Kontrolle an den Browser übergeben. Die kann er die Eingangsereigniswarteschlange überprüfen und feststellen, ob dort was sie der Seite mitteilen muss. Anschließend führt der Browser wieder die werden JavaScript blockiert. Das hilft, kann aber andere Probleme verursachen.
Jedes Mal, wenn die Seite dem Browser die Kontrolle übergibt, dauert es einige Zeit, um die Eingabeereigniswarteschlange zu überprüfen, Ereignisse zu verarbeiten und die nächsten JavaScript-Block. Während der Browser schneller auf Ereignisse reagiert, verlangsamt. Und wenn wir zu oft nachgeben, lädt zu langsam. Wenn wir seltener nachgeben, dauert es länger, bis der Browser auf Nutzerereignisse reagieren und die Nutzer frustriert sind. Kein Spaß.
Bei Facebook wollten wir sehen, wie die Dinge aussehen würden, wenn wir eine
neuen Ansatz zum Laden, der diesen frustrierenden Kompromiss eliminieren würde. Mi.
unsere Freunde bei Chrome darüber gesprochen und einen Vorschlag
für isInputPending()
. Die isInputPending()
API verwendet als Erstes das Konzept der
Nutzereingaben im Web unterbrochen werden und JavaScript kann
Eingaben prüfen, ohne dass der Browser dies nachlässt.
Aufgrund des Interesses an der API arbeiteten wir mit unseren Chrome-Kollegen zusammen. um die Funktion in Chromium zu implementieren und zu veröffentlichen. Mit Chrome die Patches wurden einem Ursprungstest unterzogen Mit dieser Funktion kann Chrome Änderungen testen und Feedback von Entwicklern einholen. bevor eine API vollständig veröffentlicht wird).
Wir haben jetzt Feedback vom Ursprungstest und von den anderen Mitgliedern der W3C Web Performance Working Group und hat Änderungen an der API implementiert.
Beispiel: Yieldier-Planer
Angenommen, ihr müsst eine Menge Arbeit erledigen, um das Display zu blockieren.
zum Beispiel das Generieren von Markup aus Komponenten, das Ausschließen von Primzahlen
einfach ein cooles Ladesymbol zeichnen. Jedes davon wird in eine eigene
Arbeitselement. Lassen Sie uns mithilfe des Planermusters skizzieren, wie wir
eine hypothetische processWorkQueue()
-Funktion:
const DEADLINE = performance.now() + QUANTUM;
while (workQueue.length > 0) {
if (performance.now() >= DEADLINE) {
// Yield the event loop if we're out of time.
setTimeout(processWorkQueue);
return;
}
let job = workQueue.shift();
job.execute();
}
Wenn processWorkQueue()
später in einer neuen Makroaufgabe über setTimeout()
aufgerufen wird,
um dem Browser die Möglichkeit zu geben, auf Eingaben zu reagieren,
Event-Handler ausführen, bevor die Arbeit fortgesetzt wird)
ohne Unterbrechung. Allerdings kann es sein, dass der Termin durch andere Aufgaben
die Steuerung der Ereignisschleife wünscht, oder zusätzliche QUANTUM
Millisekunden erreichen
der Ereignislatenz.
Das ist in Ordnung, aber können wir das besser machen? Auf jeden Fall!
const DEADLINE = performance.now() + QUANTUM;
while (workQueue.length > 0) {
if (navigator.scheduling.isInputPending() || performance.now() >= DEADLINE) {
// Yield if we have to handle an input event, or we're out of time.
setTimeout(processWorkQueue);
return;
}
let job = workQueue.shift();
job.execute();
}
Mit einem Anruf bei navigator.scheduling.isInputPending()
können wir
schneller auf Eingaben reagieren und gleichzeitig dafür sorgen,
ohne Unterbrechung ausgeführt wird. Wenn wir mit irgendetwas nichts
bis die Arbeit abgeschlossen ist, können wir die Zahl
auch die Länge von QUANTUM
.
Standardmäßig ist „Kontinuierlich“ Ereignisse werden von isInputPending()
nicht zurückgegeben. Diese
sind mousemove
, pointermove
und weitere. Wenn Sie mit Ihrem Budget
auch diese verwenden, kein Problem. Durch Bereitstellen eines Objekts für isInputPending()
mit
includeContinuous
ist auf true
festgelegt. Jetzt kann es losgehen:
const DEADLINE = performance.now() + QUANTUM;
const options = { includeContinuous: true };
while (workQueue.length > 0) {
if (navigator.scheduling.isInputPending(options) || performance.now() >= DEADLINE) {
// Yield if we have to handle an input event (any of them!), or we're out of time.
setTimeout(processWorkQueue);
return;
}
let job = workQueue.shift();
job.execute();
}
Fertig! Frameworks wie React unterstützen isInputPending()
in der
mit ähnlicher Logik. Hoffentlich führt dies
Entwickler, die diese Frameworks nutzen, um von isInputPending()
zu profitieren
ohne aufwendige Umformulierungen hinter die Kulissen.
Ertrag ist nicht immer schlecht
Zu beachten ist, dass weniger Einnahme nicht für jeden Verwendungszweck die richtige Lösung ist. Fall. Es gibt viele weitere Gründe, die Kontrolle an den Browser zurückzugeben, Eingabeereignisse verarbeiten, etwa zum Ausführen von Renderings und Ausführen anderer Skripte auf auf der Seite.
Es gibt Fälle, in denen der Browser den Status "Ausstehend" nicht richtig zuordnen kann.
Eingabeereignissen. Vor allem das Einrichten komplexer Clips und Masken für ursprungsübergreifende
iFrames melden möglicherweise falsch negative Ergebnisse (d.h., isInputPending()
könnte eine unerwartete Ausgabe zurückgeben)
false festlegen. Achten Sie darauf, dass Sie oft genug ertragen, wenn
Ihre Website erfordert Interaktionen mit stilisierten Subframes.
Achten Sie auch auf andere Seiten mit einer gemeinsamen Ereignisschleife. Auf Plattformen wie
wie Chrome für Android, kommt es häufig vor, dass
mehrere Ursprünge ein Ereignis teilen,
Schleife isInputPending()
gibt niemals true
zurück, wenn die Eingabe an eine
ursprungsübergreifenden Frame zu verstehen. Daher können Seiten im Hintergrund den
die Reaktionszeit der Seiten im Vordergrund. Möglicherweise möchten Sie Ihre Kampagnen
häufiger, wenn Sie im Hintergrund mit der Page Visibility API arbeiten.
Wir empfehlen dir, isInputPending()
mit Bedacht zu verwenden. Wenn es keine
zu verhindern, und seien Sie freundlich zu anderen in der Ereignisschleife, indem Sie
häufiger erbringt. Lange Aufgaben können schädlich sein.
Feedback
- Feedback zu den Spezifikationen in der is-input-pending-Repository.
- Wenden Sie sich an @acomminos, einen der Spezifikationsautoren. auf Twitter.
Fazit
Wir freuen uns über die Einführung von isInputPending()
.
um sie noch heute zu nutzen. Mit dieser API erstellt Facebook zum ersten Mal eine
Web-API entwickelt und sie von der Ideenfindung über den Standardvorschlag bis hin zur
der Versand in einem Browser. Wir möchten uns bei allen bedanken, die uns geholfen haben,
und ein besonderes Dankeschön an alle bei Chrome, die uns geholfen haben,
diese Idee umzusetzen und zu versenden.
Hero-Foto von Will H McMahan auf Unsplash (Unsplash).