Dane wejściowe trafią do kompozytora
To ostatnia część z 4 członków naszej serii poświęconej Chrome. jak działa, nasz kod do wyświetlenia witryny. W poprzednim poście przyglądaliśmy się procesowi renderowania i znajdowaliśmy kompozytor. W tym poście omówimy zobaczysz, jak kompozytor umożliwia płynną interakcję po otrzymaniu danych wejściowych użytkownika.
Wprowadzanie zdarzeń z perspektywy przeglądarki
Gdy usłyszysz „Zdarzenia wejściowe” że możemy napisać coś w polu tekstowym lub kliknąć myszą, z perspektywy przeglądarki, dane wejściowe oznaczają dowolny gest użytkownika. Przewijanie kółkiem myszy to wprowadzanie danych zdarzenie oraz dotknięcie lub najechanie myszą również zostanie zdarzeniem wejściowym.
Gdy następuje gest użytkownika taki jak dotknięcie ekranu, to proces przeglądarki otrzymuje
gest: Przeglądarka wie jednak tylko, gdzie miała miejsce gest, ponieważ
treść na karcie jest obsługiwana przez mechanizm renderowania. Proces przeglądarki wysyła więc zdarzenie
(np. touchstart
) i jego współrzędne do procesu renderowania. Mechanizm renderowania obsługuje
odpowiednie zdarzenie, znajdując cel zdarzenia i uruchomione detektory zdarzeń.
![zdarzenie wejściowe](https://developer.chrome.com/static/blog/inside-browser-part4/image/input-event-265a73164e715.png?authuser=7&hl=pl)
Kompozytor odbiera zdarzenia wejściowe
W poprzednim poście pokazaliśmy, jak kompozytor może płynnie obsługiwać przewijanie przez zrasteryzowanych warstw. Jeśli do strony nie są podłączone żadne detektory zdarzeń wejściowych, wątek kompozytora może aby utworzyć nową ramkę kompozytową całkowicie niezależną od wątku głównego. Ale co, jeśli jakieś zdarzenie do strony dodano słuchaczy? Jak wątek kompozytora może sprawdzić, czy zdarzenie wymaga zająć się sprawą?
Omówienie regionu z możliwością przewijania
Uruchamianie JavaScriptu jest zadaniem wątku głównego, więc gdy strona jest skomponowana, wątek kompozytora oznacza region strony, który zawiera moduły obsługi zdarzeń dołączone jako „Region nieprzewijany bez szybkości przewijania”. Według gdy ta informacja jest dostępna, wątek kompozytora może wysyłać zdarzenie wejściowe do wątku głównego. jeśli zdarzenie ma miejsce w danym regionie. Jeśli zdarzenie wejściowe pochodzi spoza tego regionu, wątek kompozytora kontynuuje komponowanie nowej ramki bez oczekiwania na wątek główny.
![ograniczony region bez możliwości szybkiego przewijania](https://developer.chrome.com/static/blog/inside-browser-part4/image/limited-non-fast-scrollab-376be5ee2cd6b.png?authuser=7&hl=pl)
Zachowaj ostrożność podczas pisania modułów obsługi zdarzeń
Typowym wzorcem obsługi zdarzeń w programowaniu stron internetowych jest przekazywanie zdarzeń. Od początku wydarzeń może dołączać 1 moduł obsługi zdarzeń u góry elementu i przekazywać zadania na podstawie celu zdarzenia. Ty mogło zobaczyć lub napisać kod podobny do tego poniżej.
document.body.addEventListener('touchstart', event => {
if (event.target === area) {
event.preventDefault();
}
});
Ponieważ wystarczy napisać jeden moduł obsługi zdarzeń dla wszystkich elementów, ergonomia tego zdarzenia jest atrakcyjny dla użytkowników. Jeśli jednak spojrzysz na ten kod z punktu widzenia przeglądarki , teraz cała strona jest oznaczona jako obszar, którego nie można szybko przewijać. Oznacza to, że nawet wtedy, gdy nie dba o dane wejściowe z określonych części strony, wątek kompozytora musi komunikują się z wątkiem głównym i czekają na niego za każdym razem, gdy pojawi się zdarzenie wejściowe. Dlatego funkcja płynnego przewijania w przypadku kompozytora jest tracona.
![cały obszar strony bez możliwości szybkiego przewijania](https://developer.chrome.com/static/blog/inside-browser-part4/image/full-page-non-fast-scroll-dd3010cc3ee0f.png?authuser=7&hl=pl)
Aby temu zapobiec, możesz przekazać w wydarzeniu opcje passive: true
słuchacz. Ten komunikat informuje przeglądarkę, że nadal chcesz nasłuchiwać zdarzenia w wątku głównym,
ale kompozytor może też przejść dalej i skomponować nową ramkę.
document.body.addEventListener('touchstart', event => {
if (event.target === area) {
event.preventDefault()
}
}, {passive: true});
Sprawdź, czy można anulować wydarzenie
![przewinięcie strony](https://developer.chrome.com/static/blog/inside-browser-part4/image/page-scroll-2cf8d804f8587.png?authuser=7&hl=pl)
Załóżmy, że masz pole na stronie, w którym chcesz ograniczyć kierunek przewijania tylko do przewijania w poziomie.
Użycie opcji passive: true
w zdarzeniu wskaźnika sprawia, że przewijanie strony może być płynne,
przewijanie w pionie mogło rozpocząć się przed preventDefault
, by ograniczyć
kierunek przewijania. Możesz to sprawdzić, używając metody event.cancelable
.
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});
Możesz też użyć reguły CSS, takiej jak touch-action
, by całkowicie wyeliminować moduł obsługi zdarzeń.
#area {
touch-action: pan-x;
}
Znajdowanie celu zdarzenia
![test wyników](https://developer.chrome.com/static/blog/inside-browser-part4/image/hit-test-39f1d20855064.png?authuser=7&hl=pl)
Gdy wątek kompozytora wysyła zdarzenie wejściowe do wątku głównego, pierwszym uruchomieniem jest działanie aby znaleźć cel zdarzenia. Test trafień wykorzystuje dane z rejestrów renderowania, które zostały wygenerowane podczas renderowania aby ustalić, co znajduje się pod współrzędnymi punktu, w którym doszło do zdarzenia.
Minimalizowanie wysyłania zdarzeń do wątku głównego
W poprzednim poście omówiliśmy, jak nasz typowy wyświetlacz odświeża ekran 60 razy na sekundę. na zachowanie tempa i płynności animacji. Do wprowadzania danych typowy ekran dotykowy urządzenie generuje zdarzenie dotknięcia 60–120 razy na sekundę, a typowa mysz – 100 razy sekunda. Zdarzenie wejściowe ma wyższą dokładność, niż można odświeżyć ekran.
Jeśli zdarzenie ciągłe, takie jak touchmove
, zostało wysłane do wątku głównego 120 razy na sekundę,
może wywołać nadmierną liczbę testów trafień i wykonania JavaScriptu w porównaniu do czasu
może odświeżyć ekran.
![niefiltrowane zdarzenia](https://developer.chrome.com/static/blog/inside-browser-part4/image/unfiltered-events-5c569da8f6466.png?authuser=7&hl=pl)
Aby zminimalizować liczbę wywołań wątku głównego, Chrome łączy zdarzenia ciągłe (takie jak
wheel
, mousewheel
, mousemove
, pointermove
, touchmove
) i opóźnienia w wysyłce do
tuż przed następnym requestAnimationFrame
.
![wydarzenia łączone](https://developer.chrome.com/static/blog/inside-browser-part4/image/coalesced-events-42fbb3813612d.png?authuser=7&hl=pl)
Dowolne zdarzenia, takie jak keydown
, keyup
, mouseup
, mousedown
, touchstart
i touchend
są wysyłane natychmiast.
Użyj getCoalescedEvents
, aby pobrać zdarzenia w ramce
W przypadku większości aplikacji internetowych połączone zdarzenia powinny zapewniać dobre wrażenia użytkowników.
Jeśli jednak tworzysz np. aplikację do rysowania i umieszczasz ścieżkę na podstawie
touchmove
. Aby narysować gładką linię, między współrzędnymi mogą zostać utracone obszary. W takim przypadku
możesz użyć metody getCoalescedEvents
w zdarzeniu wskaźnika, aby uzyskać informacje o tych
powiązane wydarzenia.
![getCoalescedEvents](https://developer.chrome.com/static/blog/inside-browser-part4/image/getcoalescedevents-ab59c1cb92e1b.png?authuser=7&hl=pl)
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.
}
});
Dalsze kroki
W tej serii omówiliśmy wewnętrzne działanie przeglądarki. Jeśli nigdy nie zastanawiasz się, dlaczego
Narzędzia deweloperskie zalecają dodanie elementu {passive: true}
do modułu obsługi zdarzeń lub powodzenie, dla którego warto wpisać async
w tagu skryptu, mam nadzieję, że ta seria pomoże Ci wyjaśnić, dlaczego przeglądarka
aby zapewnić szybsze i płynniejsze korzystanie z internetu.
Użyj narzędzia Lighthouse
Jeśli chcesz, aby kod działał dobrze w przeglądarce, ale nie wiesz, od czego zacząć, Lighthouse to narzędzie do przeprowadzania audytu każdej strony internetowej tworzyć raporty dotyczące tego, co zostało zrobione dobrze, a co wymaga poprawy. Czytanie listy kontroli pokazuje też, co jest ważne dla przeglądarki.
Dowiedz się, jak mierzyć skuteczność
Poprawa wydajności może się różnić w zależności od witryny, dlatego ważne jest, aby mierzyć jej skuteczność. i zdecyduj, co jest dla niej najlepsze. Zespół Narzędzi deweloperskich w Chrome ma kilka samouczków na temat jak mierzyć skuteczność witryny.
Dodawanie zasad dotyczących funkcji do witryny
Jeśli chcesz zrobić coś dodatkowego, zapoznaj się z Zasadami dotyczącymi funkcji
funkcja platformy internetowej, która może stanowić barierę przy tworzeniu projektu. Włączam
zasady dotyczące funkcji gwarantują określone działanie aplikacji i zapobiegają popełnieniu błędów.
Jeśli na przykład chcesz mieć pewność, że aplikacja nigdy nie będzie blokowała analizy, możesz ją uruchomić
zasady skryptów synchronicznych. Gdy zasada sync-script: 'none'
jest włączona, kod JavaScript blokujący parser
nie można zrealizować. Zapobiega to blokowaniu parsera w kodzie, a tag
nie musi się martwić wstrzymywaniem parsera.
Podsumowanie
![dziękuję](https://developer.chrome.com/static/blog/inside-browser-part4/image/thank-you-cae9a20f3c237.png?authuser=7&hl=pl)
Gdy zaczęłam tworzyć witryny, zależało mi tylko na tym, jak pisałem kod i co pomogłoby mi zwiększyć produktywność. To ważne, ale powinniśmy też zastanowić się, pobiera napisany przez nas kod. Nowoczesne przeglądarki nieustannie inwestują w sposoby i zapewnić użytkownikom lepsze wrażenia z korzystania z internetu. Dzięki uprzejmości względem przeglądarki przez organizację kodu z kolei poprawia wrażenia użytkownika. Mam nadzieję, że weźmiesz udział w tej misji i bawię się dobrze dla przeglądarek.
Serdecznie dziękujemy wszystkim, którzy przeglądali wczesne wersje robocze tej serii, w tym (ale nie tylko do): Alex Russell, Paul Ireland Meggin Kearney Eric Bidelman, Mathias Bynens Addy Osmani Kinuko Yasuda Nasko Oskov, i Charlie Reis.
Podobała Ci się ta seria? Jeśli masz jakieś pytania lub sugestie związane z kolejnym postem, Chętnie poznam Twoją opinię w sekcji komentarzy poniżej lub na koncie @kosamari. na Twitterze.