Jak ulepszyliśmy nasze kluczowe wskaźniki internetowe (studium przypadku)

Opublikowany: 2022-03-10
Krótkie podsumowanie ↬ „Aktualizacja funkcji strony” Google zacznie być wprowadzana w czerwcu. Na początku witryny, które spełniają progi Core Web Vitals, będą miały niewielką przewagę w rankingu w wyszukiwarce mobilnej we wszystkich przeglądarkach. Wyszukiwanie jest ważne dla każdej firmy, a oto historia o tym, jak Beau Hartshorne i jego zespół w Instant Domain Search poprawili swoje wyniki w Core Web Vitals. Plus narzędzie open-source, które zbudowali po drodze.

W zeszłym roku Google zaczął podkreślać znaczenie kluczowych wskaźników internetowych i tego, jak odzwierciedlają one rzeczywiste wrażenia użytkownika podczas odwiedzania witryn w sieci. Wydajność jest podstawową cechą naszej firmy, Instant Domain Search — jest w nazwie. Wyobraź sobie nasze zaskoczenie, gdy stwierdziliśmy, że nasze wyniki życiowe nie były dobre dla wielu osób. Nasze szybkie komputery i światłowodowy internet zamaskowały wrażenia, jakie mają prawdziwi ludzie na naszej stronie. Nie minęło wiele czasu, zanim nasza uwaga wymagała morza czerwonych „słabych” i żółtych komunikatów „wymaga poprawy” w naszej Google Search Console. Entropia wygrała, a my musieliśmy wymyślić, jak usunąć to szarpnięcie — i przyspieszyć naszą witrynę.

Zrzut ekranu z Google Search Console pokazujący, że musimy ulepszyć nasze podstawowe wskaźniki Web Vitals
To jest zrzut ekranu z naszego raportu Podstawowe wskaźniki internetowe dla urządzeń mobilnych w Google Search Console. Przed nami jeszcze dużo pracy! (duży podgląd)

Założyłem Instant Domain Search w 2005 roku i trzymałem to jako poboczną pracę, podczas gdy pracowałem w firmie Y Combinator (Snipshot, W06), zanim zacząłem pracować jako inżynier oprogramowania na Facebooku. Niedawno rozrosliśmy się do małej grupy z siedzibą głównie w Victorii w Kanadzie i pracujemy nad długą listą nowych funkcji i ulepszeń wydajności. Nasze słabe wyniki wskaźników internetowych i zbliżająca się aktualizacja Google Update skłoniły nas do znalezienia i rozwiązania tych problemów.

Kiedy uruchomiono pierwszą wersję strony, zbudowałem ją za pomocą PHP, MySQL i XMLHttpRequest. Internet Explorer 6 był w pełni obsługiwany, Firefox zyskiwał na popularności, a Chrome wciąż dzielił lata od premiery. Z biegiem czasu ewoluowaliśmy dzięki różnym statycznym generatorom witryn, frameworkom JavaScript i technologiom serwerowym. Nasz obecny stos front-end to React obsługiwany z Next.js i wbudowaną usługą backendu Rust, aby odpowiedzieć na nasze wyszukiwania nazw domen. Staramy się postępować zgodnie z najlepszymi praktykami, udostępniając jak najwięcej w sieci CDN, unikając jak największej liczby skryptów innych firm i używając prostych grafik SVG zamiast bitmapowych plików PNG. To nie wystarczyło.

Next.js pozwala nam budować nasze strony i komponenty w React i TypeScript. W połączeniu z VS Code doświadczenie programistyczne jest niesamowite. Next.js zazwyczaj działa poprzez przekształcanie komponentów React w statyczny HTML i CSS. W ten sposób początkowa treść może być serwowana z CDN, a następnie Next może „uwodnić” stronę, aby elementy były dynamiczne. Po uwodnieniu strony nasza witryna zamienia się w jednostronicową aplikację, w której użytkownicy mogą wyszukiwać i generować nazwy domen. Nie polegamy na Next.js w wykonywaniu dużej ilości pracy po stronie serwera, większość naszych treści jest statycznie eksportowana jako HTML, CSS i JavaScript, które mają być obsługiwane z CDN.

Więcej po skoku! Kontynuuj czytanie poniżej ↓

Gdy ktoś zaczyna szukać nazwy domeny, zastępujemy treść strony wynikami wyszukiwania. Aby wyszukiwanie było jak najszybsze, front-end bezpośrednio odpytuje nasz backend Rust, który jest mocno zoptymalizowany pod kątem wyszukiwań domen i sugestii. Na wiele pytań możemy odpowiedzieć natychmiast, ale w przypadku niektórych TLD musimy wykonywać wolniejsze zapytania DNS, których rozwiązanie może zająć sekundę lub dwie. Gdy niektóre z tych wolniejszych zapytań rozwiążą się, zaktualizujemy interfejs użytkownika o wszelkie nowe informacje. Strony z wynikami wyszukiwania są różne dla każdego i może być nam trudno przewidzieć, w jaki sposób każda osoba odbiera witrynę.

Narzędzia Chrome DevTools są doskonałe i są dobrym miejscem do rozpoczęcia poszukiwania problemów z wydajnością. Widok Wydajność pokazuje dokładnie, kiedy wysyłane są żądania HTTP, gdzie przeglądarka spędza czas na ocenie kodu JavaScript i nie tylko:

Zrzut ekranu panelu Wydajność w Chrome DevTools
Zrzut ekranu panelu Wydajność w Chrome DevTools. Włączyliśmy funkcje Web Vitals, które pozwalają nam zobaczyć, który element spowodował LCP. (duży podgląd)

Istnieją trzy podstawowe wskaźniki sieciowe, których Google użyje, aby pomóc w pozycjonowaniu witryn w nadchodzącej aktualizacji algorytmu wyszukiwania. Google dzieli doświadczenia na „Dobre”, „Wymaga poprawy” i „Złe” w oparciu o wyniki LCP, FID i CLS, jakie mają prawdziwi ludzie w witrynie:

  • LCP lub Largest Contentful Paint definiuje czas, po którym największy element zawartości stanie się widoczny.
  • FID , czyli opóźnienie pierwszego wejścia, odnosi się do czasu reakcji witryny na interakcję — czasu między dotknięciem, kliknięciem lub naciśnięciem klawisza w interfejsie a reakcją ze strony.
  • CLS (Cumulative Layout Shift) śledzi, jak elementy poruszają się lub przesuwają na stronie bez czynności, takich jak klawiatura lub zdarzenie kliknięcia.
Grafika przedstawiająca zakresy akceptowalnych wyników LCP, FID i CLS
Podsumowanie LCP, FID i CLS. (Źródło zdjęcia: Web Vitals autorstwa Philipa Waltona) (duży podgląd)

Chrome jest skonfigurowany do śledzenia tych danych wśród wszystkich zalogowanych użytkowników Chrome i wysyła anonimowe statystyki podsumowujące doświadczenia klienta w witrynie z powrotem do Google w celu oceny. Te wyniki są dostępne w raporcie z doświadczeń użytkowników Chrome i są wyświetlane podczas sprawdzania adresu URL za pomocą narzędzia PageSpeed ​​Insights. Wyniki reprezentują 75. percentyl dla osób odwiedzających ten adres URL w ciągu ostatnich 28 dni. Jest to numer, którego będą używać do ustalania rankingu witryn w aktualizacji.

Wskaźnik 75 percentyla (p75) zapewnia rozsądną równowagę pod względem celów wydajnościowych. Na przykład branie średniej ukryłoby wiele złych doświadczeń, jakie mają ludzie. Mediana, czyli 50. percentyl (p50), oznaczałaby, że połowa osób korzystających z naszego produktu miała gorsze doświadczenia. Z drugiej strony, 95. percentyl (p95) jest trudny do zbudowania, ponieważ wychwytuje zbyt wiele ekstremalnych wartości odstających na starych urządzeniach z nierównymi połączeniami. Uważamy, że punktacja oparta na 75. percentylu jest słusznym standardem do spełnienia.

Wykres ilustrujący rozkład wartości p50 i p75
Mediana, znana również jako 50. percentyl lub p50, jest zaznaczona na zielono. 75. percentyl, czyli p75, jest tutaj pokazany na żółto. Na tej ilustracji pokazujemy 20 sesji. 15. najgorsza sesja to 75. percentyl i to, czego Google użyje do oceny jakości tej witryny. (duży podgląd)

Aby uzyskać kontrolę nad naszymi wynikami, najpierw zwróciliśmy się do Lighthouse po doskonałe narzędzia wbudowane w Chrome i hostowane na web.dev/measure/ i PageSpeed ​​Insights. Narzędzia te pomogły nam znaleźć ogólne problemy techniczne z naszą witryną. Widzieliśmy, że sposób, w jaki Next.js łączy nasz CSS i spowalnia nasz początkowy czas renderowania, co wpłynęło na nasz FID. Pierwsza łatwa wygrana pochodziła z eksperymentalnej funkcji Next.js,optimCss, która pomogła znacząco poprawić nasz ogólny wynik wydajności.

Lighthouse wykrył również błędną konfigurację pamięci podręcznej, która uniemożliwiła obsługę niektórych naszych zasobów statycznych z naszego CDN. Jesteśmy hostowani na Google Cloud Platform, a Google Cloud CDN wymaga, aby nagłówek Cache-Control zawierał „public”. Next.js nie pozwala na skonfigurowanie wszystkich emitowanych nagłówków, więc musieliśmy je zastąpić, umieszczając serwer Next.js za Caddy, lekkim serwerem proxy HTTP zaimplementowanym w Go. Skorzystaliśmy również z okazji, aby upewnić się, że serwujemy to, co możemy, dzięki stosunkowo nowej obsłudze nieaktualnej aktualizacji w nowoczesnych przeglądarkach, która umożliwia CDN pobieranie treści ze źródła (naszego serwera Next.js) asynchronicznie w tle.

Dodanie do produktu prawie wszystkiego, czego potrzebujesz z npm, jest łatwe — może nawet zbyt proste. Wzrost rozmiarów pakietów nie trwa długo. Pobieranie dużych pakietów w wolnych sieciach trwa dłużej, a 75-centylowy telefon komórkowy będzie spędzał dużo czasu na blokowaniu głównego wątku interfejsu użytkownika, próbując zrozumieć cały pobrany właśnie kod. Podobał nam się BundlePhobia, który jest darmowym narzędziem, które pokazuje, ile zależności i bajtów pakiet npm doda do twojego pakietu. Doprowadziło nas to do wyeliminowania lub zastąpienia wielu animacji opartych na mechanizmie React-Spring prostszymi przejściami CSS:

Zrzut ekranu narzędzia BundlePhobia pokazujący, że reakcja-spring dodaje 162,8 kB JavaScript
Wykorzystaliśmy BundlePhobia, aby wyśledzić duże zależności, bez których moglibyśmy się obejść. (duży podgląd)

Dzięki wykorzystaniu BundlePhobia i Lighthouse stwierdziliśmy, że oprogramowanie innych firm do rejestrowania i analizy błędów znacząco przyczyniło się do rozmiaru naszego pakietu i czasu ładowania. Usunęliśmy i zastąpiliśmy te narzędzia własnym logowaniem po stronie klienta, które wykorzystuje nowoczesne interfejsy API przeglądarki, takie jak sendBeacon i ping. Logowanie i analizy wysyłamy do naszej własnej infrastruktury Google BigQuery, gdzie możemy odpowiadać na pytania, na których nam zależy, bardziej szczegółowo, niż mogłoby to zapewnić jakiekolwiek z gotowych narzędzi. Eliminuje to również wiele plików cookie stron trzecich i daje nam znacznie większą kontrolę nad tym, w jaki sposób i kiedy wysyłamy dane logowania od klientów.

Nasz wynik CLS nadal ma najwięcej do poprawy. Sposób, w jaki Google oblicza CLS jest skomplikowany — otrzymujesz maksymalne „okno sesji” z 1-sekundową przerwą, ograniczone do 5 sekund od początkowego wczytania strony lub z interakcji klawiatury lub kliknięcia, aby zakończyć przenoszenie rzeczy po witrynie . Jeśli chcesz zagłębić się w ten temat, oto świetny przewodnik na ten temat. To karze wiele rodzajów nakładek i wyskakujących okienek, które pojawiają się zaraz po wejściu na stronę. Na przykład reklamy, które przesuwają treść lub oferty dodatkowe, które mogą się pojawić, gdy zaczniesz przewijać reklamy, by dotrzeć do treści. Ten artykuł zawiera doskonałe wyjaśnienie sposobu obliczania wyniku CLS i uzasadnienia tego.

Jesteśmy zasadniczo przeciwni tego rodzaju cyfrowemu bałaganowi, więc byliśmy zaskoczeni, widząc, jak wiele miejsca na ulepszenia nalegał Google. Chrome ma wbudowaną nakładkę Web Vitals, do której można uzyskać dostęp za pomocą menu poleceń "Pokaż nakładkę Core Web Vitals". Aby dokładnie zobaczyć, które elementy Chrome bierze pod uwagę w swoich obliczeniach CLS, uznaliśmy, że opcja „Console Logging” rozszerzenia Chrome Web Vitals w ustawieniach jest bardziej pomocna. Po włączeniu ta wtyczka pokazuje wyniki LCP, FID i CLS dla bieżącej strony. Z konsoli możesz zobaczyć dokładnie, które elementy na stronie są powiązane z tymi partyturami. Nasze wyniki CLS miały najwięcej miejsca na poprawę.

Zrzut ekranu z widokiem heads-up-display wtyczki Chrome Web Vitals
Rozszerzenie Chrome Web Vitals pokazuje, jak Chrome ocenia bieżącą stronę na podstawie jej wskaźników internetowych. Niektóre z tych funkcji zostaną wbudowane w Chrome 90. (duży podgląd)

Spośród trzech metryk CLS jest jedynym, który gromadzi się podczas interakcji ze stroną. Rozszerzenie Web Vitals ma opcję rejestrowania, która pokaże dokładnie, które elementy powodują CLS podczas interakcji z produktem. Zobacz, jak metryki CLS są dodawane, gdy przewijamy stronę główną Smashing Magazine:

Po włączeniu rejestrowania w rozszerzeniu Chrome Web Vitals zmiany układu są rejestrowane w konsoli podczas interakcji z witryną.

Google będzie z czasem dostosowywać sposób obliczania CLS, dlatego ważne jest, aby być na bieżąco z informacjami na temat bloga Google poświęconego tworzeniu stron internetowych. Podczas korzystania z narzędzi takich jak rozszerzenie Chrome Web Vitals ważne jest, aby włączyć ograniczanie procesora i sieci, aby uzyskać bardziej realistyczne wrażenia. Możesz to zrobić za pomocą narzędzi programistycznych, symulując mobilny procesor.

Zrzut ekranu pokazujący, jak włączyć ograniczanie procesora w Chrome DevTools
Ważne jest, aby zasymulować wolniejszy procesor i połączenie sieciowe podczas szukania problemów z Web Vitals w witrynie. (duży podgląd)

Najlepszym sposobem śledzenia postępów od jednego wdrożenia do następnego jest mierzenie wrażeń ze strony w taki sam sposób, jak robi to Google. Jeśli masz skonfigurowane Google Analytics, prostym sposobem na to jest zainstalowanie modułu web-vitals Google i podłączenie go do Google Analytics. Zapewnia to przybliżoną miarę postępów i sprawia, że ​​są one widoczne na pulpicie nawigacyjnym Google Analytics.

Wykres przedstawiający średnie wyniki naszych wartości CLS w czasie
Google Analytics może pokazać średnią wartość wyników Web Vitals. (duży podgląd)

Tutaj uderzamy w ścianę. Widzieliśmy nasz wynik CLS i chociaż znacznie go poprawiliśmy, wciąż mieliśmy pracę do wykonania. Nasz wynik CLS wynosił z grubsza 0,23 i musieliśmy go obniżyć poniżej 0,1 — a najlepiej do 0. Jednak w tym momencie nie mogliśmy znaleźć czegoś, co mówiłoby nam dokładnie, które komponenty i na których stronach nadal wpływają na wynik. Widzieliśmy, że Chrome ujawnił wiele szczegółów w swoich narzędziach Core Web Vitals, ale agregatory rejestrowania wyrzuciły najważniejszą część: dokładnie który element strony spowodował problem.

Zrzut ekranu konsoli Chrome DevTools pokazujący, które elementy powodują CLS.
To pokazuje dokładnie, które elementy składają się na Twój wynik CLS. (duży podgląd)

Aby uchwycić wszystkie potrzebne nam szczegóły, zbudowaliśmy funkcję bezserwerową do przechwytywania danych z przeglądarek internetowych. Ponieważ nie musimy uruchamiać zapytań o dane w czasie rzeczywistym, przesyłamy je strumieniowo do interfejsu API przesyłania strumieniowego Google BigQuery w celu przechowywania. Ta architektura oznacza, że ​​możemy niedrogo przechwycić tyle punktów danych, ile jesteśmy w stanie wygenerować.

Po nauczeniu się kilku lekcji podczas pracy z Web Vitals i BigQuery, zdecydowaliśmy się połączyć tę funkcjonalność i udostępnić te narzędzia jako open source na vitals.dev.

Korzystanie z funkcji Instant Vitals to szybki sposób na rozpoczęcie śledzenia wyników funkcji Web Vitals w BigQuery. Oto przykład tworzonego przez nas schematu tabeli BigQuery:

Zrzut ekranu naszych schematów BigQuery do przechwytywania FCP
Jeden z naszych schematów BigQuery. (duży podgląd)

Integracja z Instant Vitals jest łatwa. Możesz zacząć od integracji z biblioteką klienta, aby wysyłać dane do swojego zaplecza lub funkcji bezserwerowej:

 import { init } from "@instantdomain/vitals-client"; init({ endpoint: "/api/web-vitals" });

Następnie na swoim serwerze możesz zintegrować się z biblioteką serwera, aby uzupełnić obwód:

 import fs from "fs"; import { init, streamVitals } from "@instantdomain/vitals-server"; // Google libraries require service key as path to file const GOOGLE_SERVICE_KEY = process.env.GOOGLE_SERVICE_KEY; process.env.GOOGLE_APPLICATION_CREDENTIALS = "/tmp/goog_creds"; fs.writeFileSync( process.env.GOOGLE_APPLICATION_CREDENTIALS, GOOGLE_SERVICE_KEY ); const DATASET_; init({ datasetId: DATASET_ID }).then().catch(console.error); // Request handler export default async (req, res) => { const body = JSON.parse(req.body); await streamVitals(body, body.name); res.status(200).end(); };

Po prostu wywołaj streamVitals , podając treść żądania i nazwę metryki, aby wysłać metrykę do BigQuery. Biblioteka zajmie się tworzeniem zestawu danych i tabel za Ciebie.

Po zebraniu danych z jednego dnia uruchomiliśmy to zapytanie, takie jak to:

 SELECT `<project_name>.web_vitals.CLS`.Value, Node FROM `<project_name>.web_vitals.CLS` JOIN UNNEST(Entries) AS Entry JOIN UNNEST(Entry.Sources) WHERE Node != "" ORDER BY value LIMIT 10

To zapytanie daje takie wyniki:

Wartość Węzeł
4.6045324800736724E-4 /html/body/div[1]/main/div/div/div[2]/div/div/blockquote
7.183070668914928E-4 /html/body/div[1]/header/div/div/header/div
0.031002668277977697 /html/body/div[1]/footer
0.035830703317463526 /html/body/div[1]/main/div/div/div[2]
0.035830703317463526 /html/body/div[1]/footer
0.035830703317463526 /html/body/div[1]/main/div/div/div[2]
0.035830703317463526 /html/body/div[1]/main/div/div/div[2]
0.035830703317463526 /html/body/div[1]/footer
0.035830703317463526 /html/body/div[1]/footer
0.03988482067913317 /html/body/div[1]/footer

To pokazuje nam, które elementy na których stronach mają największy wpływ na CLS. Stworzył listę dziurek, którą nasz zespół może zbadać i naprawić. W wyszukiwarce błyskawicznej domeny okazuje się, że powolne lub złe połączenia komórkowe potrzebują ponad 500 ms, aby załadować niektóre z naszych wyników wyszukiwania. Jednym z najgorszych współtwórców CLS dla tych użytkowników była nasza stopka.

Wynik przesunięcia układu jest obliczany jako funkcja rozmiaru poruszającego się elementu i tego, jak daleko się posuwa. W naszym widoku wyników wyszukiwania, jeśli urządzenie odbiera i renderuje wyniki wyszukiwania dłużej niż określoną ilość czasu, widok wyników zwija się do zero-height , wyświetlając stopkę. Kiedy pojawiają się wyniki, przesuwają stopkę z powrotem na dół strony. Duży element DOM, który posunął się tak daleko, dodał wiele do naszego wyniku CLS. Aby poprawnie to przepracować, musimy zrestrukturyzować sposób zbierania i renderowania wyników wyszukiwania. Zdecydowaliśmy się po prostu usunąć stopkę w widoku wyników wyszukiwania, aby szybko włamać się, aby zapobiec odbijaniu się na wolnych połączeniach.

Obecnie regularnie przeglądamy ten raport, aby śledzić, jak się poprawiamy — i używamy go do walki z gorszymi wynikami w miarę postępów. Widzieliśmy, jak ważna jest dodatkowa uwaga poświęcana nowo wprowadzonym funkcjom i produktom w naszej witrynie i przeprowadziliśmy konsekwentne kontrole, aby upewnić się, że kluczowe wskaźniki działają na korzyść naszego rankingu. Mamy nadzieję, że udostępniając Instant Vitals, możemy pomóc innym programistom w poprawie ich wyników w Core Web Vitals.

Google zapewnia doskonałe narzędzia wydajności wbudowane w Chrome i wykorzystaliśmy je do znalezienia i rozwiązania wielu problemów z wydajnością. Dowiedzieliśmy się, że dane terenowe dostarczone przez Google stanowiły dobre podsumowanie postępów naszego p75, ale nie zawierały szczegółów umożliwiających podjęcie działań. Musieliśmy dowiedzieć się dokładnie, które elementy DOM powodowały przesunięcia układu i opóźnienia wejściowe. Gdy zaczęliśmy zbierać własne dane terenowe — za pomocą zapytań XPath — byliśmy w stanie zidentyfikować konkretne możliwości poprawy doświadczenia wszystkich użytkowników naszej witryny. Z pewnym wysiłkiem obniżyliśmy nasze rzeczywiste wyniki terenowe Core Web Vitals do akceptowalnego zakresu w ramach przygotowań do czerwcowej aktualizacji Page Experience. Cieszymy się, że te liczby spadają i przesuwają się w prawo!

Zrzut ekranu Google PageSpeed ​​Insights pokazujący, że przechodzimy test Core Web Vitals
Google PageSpeed ​​Insights pokazuje, że teraz przechodzimy test Core Web Vitals. (duży podgląd)