Eingabe kommt an den Compositor
Dies ist der letzte Teil der vierteiligen Blogreihe mit Einblicken in Chrome. der Verarbeitung von Code zum Anzeigen einer Website. Im vorherigen Beitrag haben wir uns mit dem Renderingprozess und dem Compositor vertraut gemacht. In diesem Beitrag schauen wir uns an, wie der Compositor reibungslose Interaktionen bei Nutzereingaben ermöglicht.
Eingabeereignisse aus Browsersicht
Wenn Sie „Ereignisse eingeben“ hören fällt Ihnen wahrscheinlich nur die Eingabe in ein Textfeld oder ein Mausklick ein. aus der Perspektive des Browsers bedeutet, bedeutet die Eingabe jede Geste des Nutzers. Das Scrollen mit dem Mausrad ist eine Eingabe, -Ereignis und Berühren oder Mouseover sind ebenfalls ein Eingabeereignis.
Wenn eine Nutzergeste wie eine Berührung auf einem Bildschirm auftritt, ist der Browserprozess derjenige, der die
zu beginnen. Der Browserprozess erkennt jedoch nur, wo die Geste seit
Inhalte innerhalb eines Tabs werden vom Renderer-Prozess verarbeitet. Der Browserprozess sendet also das Ereignis
-Typ (z. B. touchstart
) und seine Koordinaten an den Renderer-Prozess übergeben. Der Renderer-Prozess verarbeitet
indem Sie das Ereignisziel suchen und die angehängten Ereignis-Listener ausführen.
Compositor empfängt Eingabeereignisse
<ph type="x-smartling-placeholder">Im vorherigen Beitrag haben wir uns damit befasst, wie der Compositor das Scrollen durch gerasterten Ebenen zu erstellen. Wenn der Seite keine Eingabeereignis-Listener zugeordnet sind, kann der Compositor-Thread Erstellen Sie einen neuen zusammengesetzten Frame, der völlig unabhängig vom Hauptthread ist. Aber was ist, wenn ein Ereignis an die Seite angehängt wurden? Wie würde der Compositor-Thread herausfinden, ob das Ereignis gehandhabt werden?
Informationen zu nicht schnell scrollbarem Bereich
Da das Ausführen von JavaScript der Job des Hauptthreads ist, wird beim Erstellen einer Seite der Compositor-Thread verwendet. markiert einen Bereich der Seite, an den Event-Handler als "Region ohne schnelles Scrollen" angehängt sind. Von Mit diesen Informationen kann der Compositor-Thread sicherstellen, dass das Eingabeereignis an den Hauptthread gesendet wird. wenn das Ereignis in dieser Region auftritt. Wenn das Eingabeereignis von außerhalb dieser Region stammt, ist das Ereignis Der Compositor-Thread setzt den Aufbau eines neuen Frames fort, ohne auf den Hauptthread zu warten.
<ph type="x-smartling-placeholder">Vorsicht beim Schreiben von Event-Handlern
Ein gängiges Muster bei der Ereignisverarbeitung in der Webentwicklung ist die Ereignisdelegierung. Da Termine in Bubble erscheinen, kann einen Event-Handler an das oberste Element anhängen und Aufgaben basierend auf dem Ereignisziel delegieren. Ich Code wie den folgenden Code geschrieben oder gesehen haben.
document.body.addEventListener('touchstart', event => {
if (event.target === area) {
event.preventDefault();
}
});
Da Sie nur einen Event-Handler für alle Elemente schreiben müssen, ist die Ergonomie dieses Ereignisses Delegationsmuster sind attraktiv. Wenn Sie sich diesen Code jedoch vom Standpunkt des Browsers aus ansehen, angezeigt wird, ist jetzt die gesamte Seite als nicht schnell scrollbarer Bereich markiert. Selbst wenn Ihre Anwendung keine Eingaben aus bestimmten Teilen der Seite interessiert, muss der Compositor-Thread mit dem Hauptthread kommunizieren und bei jedem Eingang eines Eingabeereignisses darauf warten. Das heißt, die flüssiges Scrollen des Compositors wird verhindert.
<ph type="x-smartling-placeholder">Sie können passive: true
Optionen in Ihrem Ereignis übergeben, um dieses Problem zu vermeiden
Listener. Dies weist den Browser darauf hin, dass Sie das Ereignis im Hauptthread immer noch überwachen möchten.
compositor kann aber auch
einen neuen Frame zusammensetzen.
document.body.addEventListener('touchstart', event => {
if (event.target === area) {
event.preventDefault()
}
}, {passive: true});
Prüfen, ob der Termin abgesagt werden kann
<ph type="x-smartling-placeholder">Angenommen, Sie haben auf einer Seite ein Feld, in dem Sie die Scrollrichtung auf das horizontale Scrollen beschränken möchten.
Wenn Sie die Option passive: true
in Ihrem Zeigerereignis verwenden, kann das Scrollen der Seite gleichmäßig,
kann das vertikale Scrollen um die Zeit begonnen haben, die du preventDefault
, um die Begrenzung
Scrollrichtung. Sie können dies mithilfe der Methode event.cancelable
prüfen.
document.body.addEventListener('pointermove', event => {
if (event.cancelable) {
event.preventDefault(); // block the native scroll
/*
* do what you want the application to do here
*/
}
}, {passive: true});
Alternativ können Sie eine CSS-Regel wie touch-action
verwenden, um den Event-Handler vollständig zu entfernen.
#area {
touch-action: pan-x;
}
Ereignisziel finden
<ph type="x-smartling-placeholder">Wenn der zusammengesetzte Thread ein Eingabeereignis an den Hauptthread sendet, wird als Erstes ein Treffer ausgeführt um das Ereignisziel zu finden. Der Treffertest verwendet Paint-Datensatzdaten, die im Rendering generiert wurden. um herauszufinden, was sich unterhalb der Punktkoordinaten befindet, in denen das Ereignis aufgetreten ist.
Ereignisweiterleitungen an den Hauptthread minimieren
Im vorherigen Beitrag haben wir besprochen, wie ein herkömmliches Display den Bildschirm 60-mal pro Sekunde aktualisiert wie wir mit dem Rhythmus für eine flüssige Animation Schritt halten müssen. Ein typischer Touchscreen zur Eingabe 60- bis 120-mal pro Sekunde ein Touch-Ereignis, eine typische Maus 100-mal pro Sekunde 2. Das Eingabeereignis hat eine höhere Genauigkeit, als unser Bildschirm aktualisiert werden kann.
Wenn ein fortlaufendes Ereignis wie touchmove
120 Mal pro Sekunde an den Hauptthread gesendet wurde,
kann eine übermäßige Anzahl von Treffertests und JavaScript-Ausführungen auslösen, verglichen mit der langsamen Ausführung von
aktualisiert werden kann.
Um übermäßig viele Aufrufe an den Hauptthread zu minimieren, fasst Chrome kontinuierliche Ereignisse zusammen, z. B.
wheel
, mousewheel
, mousemove
, pointermove
, touchmove
) und Verzögerungen beim Versand bis
direkt vor dem nächsten requestAnimationFrame
ein.
Alle diskreten Ereignisse wie keydown
, keyup
, mouseup
, mousedown
, touchstart
und touchend
sofort versandt werden.
getCoalescedEvents
für Intra-Frame-Ereignisse verwenden
Bei den meisten Webanwendungen sollten zusammengeführte Ereignisse ausreichen, um eine gute Nutzererfahrung zu bieten.
Wenn Sie jedoch z. B. eine Zeichenanwendung erstellen und einen Pfad basierend auf
touchmove
-Koordinaten können die Koordinaten verloren gehen, um eine gleichmäßige Linie zu zeichnen. In diesem Fall
können Sie die Methode getCoalescedEvents
im Zeigerereignis verwenden, um Informationen über diese Ereignisse zu erhalten.
zusammengeführten Ereignissen.
window.addEventListener('pointermove', event => {
const events = event.getCoalescedEvents();
for (let event of events) {
const x = event.pageX;
const y = event.pageY;
// draw a line using x and y coordinates.
}
});
Nächste Schritte
In dieser Reihe haben wir uns mit der Funktionsweise eines Webbrowsers befasst. Wenn Sie noch nie darüber nachgedacht haben,
DevTools empfiehlt, deinem Event-Handler {passive: true}
hinzuzufügen oder warum du async
schreiben könntest
im Skript-Tag einfügen. Ich hoffe, dass Sie in dieser Reihe erklären konnten,
um eine schnellere und reibungslosere Weberfahrung zu bieten.
Lighthouse verwenden
Wenn Sie Ihren Code für den Browser ansprechend gestalten möchten, aber nicht wissen, wo Sie anfangen sollen, Lighthouse ist ein Tool, mit dem alle Websites geprüft werden können. darüber zu berichten, was richtig gemacht wird und was verbessert werden muss. Liste der Audits durchgehen vermittelt Ihnen auch eine Vorstellung davon, was für einen Browser wichtig ist.
Weitere Informationen zum Messen der Leistung
Die Leistungsoptimierung kann je nach Website variieren. Daher ist es wichtig, dass Sie die Leistung messen. Ihrer Website und entscheiden Sie, was am besten zu Ihrer Website passt. Das Chrome-Entwicklertools-Team bietet einige Tutorials zu Wie Sie die Leistung Ihrer Website messen können.
Funktionsrichtlinie zur Website hinzufügen
Wenn Sie einen zusätzlichen Schritt machen möchten, können Sie die Funktionsrichtlinien
Webplattformfunktion, die Sie bei der Erstellung Ihres Projekts Wird aktiviert
Funktionsrichtlinien garantiert ein bestimmtes Verhalten deiner App und verhindert Fehler.
Wenn Sie beispielsweise sicherstellen möchten, dass Ihre Anwendung das Parsing nie blockiert, können Sie Ihre Anwendung auf
Richtlinie für synchrone Skripts. Wenn sync-script: 'none'
aktiviert ist, wird JavaScript-Code, der den Parser blockiert,
ausgeführt werden kann. Dadurch wird verhindert, dass Ihr Code den Parser blockiert und der
muss der Parser vom Browser nicht pausiert werden.
Zusammenfassung
Als ich mit dem Erstellen von Websites anfing, war mir fast nur wichtig, wie ich meinen Code schreibe und was produktiver zu sein. Diese Dinge sind wichtig, aber wir sollten auch berücksichtigen, der von uns geschriebene Code übernimmt. Moderne Browser haben und investieren immer mehr in Möglichkeiten, um die Nutzererfahrung im Web zu verbessern. Um den Browser freundlich zu behandeln, indem wir unseren Code organisieren, verbessert die User Experience. Hoffentlich hilfst du mir bei unserem Bestreben, nett zu den Browsern zu sein!
Ein großes Dankeschön an alle, die erste Entwürfe dieser Serie gelesen haben, einschließlich, aber nicht beschränkt An): Alex Russell, Paul Irish, Meggin Kearney Eric Bidelman Mathias Bynens Addy Osmani, Kinuko Yasuda, Nasko Oskov und Charlie Reis.
Hat Ihnen diese Reihe gefallen? Wenn Sie Fragen oder Vorschläge für den zukünftigen Beitrag haben, Ich würde mich freuen, von dir unten in den Kommentaren zu hören oder @kosamari zu schreiben. auf Twitter.