A részleges hidratáció esete (a Next és a Preact segítségével)

Tavasszal felelősek vagyunk az anyavállalatunk, az Axel Springer különféle média-webhelyeinek fenntartásáért. Az egyik legújabb kiadásunk, a welt.de, a leggyorsabb sajtó média honlap Németországban; az egyik legkeresettebb célunk a lehető legjobb teljesítmény folyamatos elérése, és ennek oka egyszerű: a jobb teljesítmény általában jobb felhasználói élményt és ezáltal magasabb felhasználói megtartást jelent.

tl; dr

Görgessen le a „Recap” ponthoz, hogy egy rövid összefoglalót kapjon egy infografikával. Dióhéjban ennek legfontosabb pontjai:
  • A teljesítmény alapvető fontosságú az internet számára
  • a nagy teljesítmény elérése érdekében a lehető legkevesebbet akarjuk elküldeni az ügyfélnek
  • ezt megtehetjük azáltal, hogy kiválasztjuk az összetevőket, amelyeket el akarunk küldeni, és hidratáljuk az ügyfélnek
  • az oldal többi részét statikusan hagyjuk, és többszörös renderelési gyökérrel rendelkezik
  • Mindez egyetlen kódbázissal működik
  • Az alábbiakban egy hosszú cikk olvasható arról, hogyan hajtottuk végre a fent említett lépéseket. Itt talál egy linket a megvalósítás WIP repójához is:
  • https://github.com/spring-media/next-super-performance

Teljesítmény az interneten

Ha követi Addy Osmanit, akkor már ismeri a fúrót, sokat ír a teljesítmény okáról és következményeiről az interneten. Az induláshoz ajánlom Addy „A JavaScript költségei 2018-ban” című cikkét. Két nagyon fontos dolog, amit megtanulhat ebből a cikkből:

  • A JavaScript költsége nem csak a csomag betöltéséhez szükséges idő
  • Ugyanilyen fontos a JavaScript elemzésének és végrehajtásának ideje

Természetesen sokkal több van a teljesítménytől, mint ehhez, beleértve a betöltési stratégiákat, a kritikus megjelenítési útvonalat, a teljesítmény-költségvetéseket és így tovább. Mindezek a dolgok azon a körül mozognak, hogy miként lehetne optimalizálni azt, amit végül az ügyfelének küld. Amit a részleges hidratációval kívánjuk összpontosítani, nem az, hogy hogyan optimalizáljuk azt, amit küld, hanem az, hogy mennyit küld.

Ennek kulcsfontosságú eleme a szerver oldali megjelenítés (SSR), mivel a szerveren sok mindent megtehetünk, amelyet nem kell az ügyfélen megtenni. Valójában ez a cikk lényege; Bármit is lehet tenni a szerveren, azt a szerveren is meg kell tenni, de az ügyfelet csak az ügyféloldalon végrehajtandó műveletekhez kell küldeni. Ezenkívül továbbra is alkalmazhat mindent, amit tud az internetes teljesítményről, de sokkal kevesebb tényezőt kell kezelnie, ezt mélyebben elmagyarázzuk a cikk alatt.

SSR és hidratáció

Egy előadó weboldal létrehozására irányuló célkitűzésünk megvalósításához a Next módosított változatát fogjuk használni. A Next-et rengeteg beépített teljesítménynövelő funkcióval szállítják, ami a legfontosabb, hogy a Next kiszolgálóoldali megjelenítést (SSR) kínál a dobozból. Ez azt jelenti, hogy a Next elvégzi az Ön alkalmazását, reagálva, és ebben a sorrendben:

  1. HTML karakterláncként jeleníti meg a kiszolgálón
  2. Küldje el a megjelenített HTML karakterláncot felhasználóinak forráskódként
  3. Küldje el React kódját JavaScript-ként a felhasználóknak
  4. És végül „hidratáld” a HTML-t a React-kóddal

A „hidratálás” ebben az esetben azt jelenti, hogy a Next eldobja a React kódot a HTML-en, majd egy kicsit így mondja meg a Reakciót:

Hé, reagál, itt van néhány HTML, amely pontosan megegyezik azzal, amit akkor adna, ha azt mondanám, hogy egy üres DOM csomópontban jelenítsen meg. a te napod

Reagálni fog

Oké, csak rád néztem HTML-t, és úgy tűnik, hogy pontosan megegyezik azzal, amit nyújtottam volna. Ez jó. Csak csatolok néhány eseménykezelőt a DOM-hoz, és az Ön oldala most egyoldalas alkalmazásként működik, mintha mindenekelőtt én magam csináltam volna.

A weboldal ilyen módon történő betöltésének előnyei egyszerűek: a felhasználók már látnak egy teljesen megjelenített oldalt, amikor betöltenek az Ön webhelyét (üres oldal helyett), majd az interaktívvá válik. Az Ön webhelyén is jelentős teljesítményjavulást élvezhet, mivel a böngészőnek nem kell újrafestenie (az oldalt újraraktározni a React segítségével).

Túl sok fölött

Ez a megközelítés fantasztikus, amikor webes alkalmazásokat, vagy más szóval webhelyeket szeretne létrehozni, amelyeket teljes mértékben a JavaScript irányításával kell kezelni, és bárhol kattintva is interaktívak. A termelésben alkalmazott ilyen megközelítésre példa a Facebook, a Twitter és a web alapú e-mail kliensek.

De a legtöbb weboldal nem ilyen, a legtöbb webhely statikus és néhány interaktív elemet is tartalmaz.

Most végül elküldi a teljes alkalmazáskódot a felhasználóknak, beleértve a React komponenseket az oldal minden címsorához vagy szöveges bekezdéséhez. Az eredmény egy szükségtelenül hatalmas csomag, amelyet be kell tölteni, értelmezni és végrehajtani. Ez nem optimális teljesítményt eredményez, oldala lassabb lesz, különösen a mobil felhasználók számára, és nincs jó ok!

És ez szar.

Szóval mit tehetnénk? Nos, nagyon sok stratégia és termék van odakint. Az egyik legjelentősebb a Gatsby, egy statikus webhelygenerátor (biztos vagyok benne, hogy már hallottál róla), amely nagy hangsúlyt fektet a teljesítmény optimalizálására. A Gatsby problémája az, hogy el kell generálnia az összes oldalt és aloldalt a fordítás idején, ami nem igazán működik, ha olyan webhelyekkel rendelkezik, amelyek CMS-hez kapcsolódnak, amelyek mindennapi frissítést végeznek, és milliónyi cikk tárolására szolgálnak - pontosan erre van szükségünk a médiaoldalak. Ez az oka annak, hogy a Next-t használjuk, és módosítjuk azt igényeinknek megfelelően.

Adja meg a részleges hidratációt

A fent említett problémák megoldására olyan dolgot találtunk ki, amelyet részleges hidratációnak hívunk.

Ha megvizsgálta ezt a témát, akkor valószínűleg olyan kifejezésekkel találkozik, mint a progresszív hidratálás vagy a lusta hidratálás. Mindegyik nem kifejezetten ugyanazt a dolgot jelenti, de mind összekapcsolódnak, és ugyanabba a szférába tartoznak.

A részleges hidratálás verziójának alapvető gondolata: Az SSR elvégzése helyett az alkalmazás teljes elküldése az ügyfélnek, az alkalmazás JavaScriptének csak azon részeit küldik az ügyfélnek, amelyek hidratálják webhelyének azon részeit, amelyek kifejezetten a JavaScript működéséhez szükségesek . Ha egy weboldalt ilyen módszerrel készítene, akkor több apró, reagáló „alkalmazás” lenne, amelyek több render gyökerével rendelkeznek az egyébként statikus webhelyén.

Az ilyen módon történő haladásnak hatalmas lendületet kell adnia webhelye teljesítményének, mivel a szállítás végén egyszerű HTML, CSS és az oldalához szükséges legkevesebb JavaScript szükséges. Egy dolog, amit meg kell jegyezni, a teljesítmény mérésénél nemcsak a betöltési időt, hanem az elemzés és a végrehajtás idejét is figyelembe kell venni.

Dönthet úgy is, hogy mindezen felül megfelelő teljesítménystratégiákat valósít meg, például a kódrészelést, a TCP lassú indulásának és a kritikus megjelenítési útvonalának gondozását stb.

Végrehajtás

Végrehajtásunk 2 csomagból áll:

  • A részleges hidratációhoz szükséges Preact könyvtárat úszómedence-kísérő-preakciónak nevezzük
  • A Next.js plugin a következő-szuper-teljesítményt hívta

Ez utóbbi könyvtár csak a Next.js pluginje, amely pool-kísérő-preaktort használ, tehát koncentráljunk a medence-kísérő-preaktumra. Lehetséges, hogy a jövőben valamilyen szakaszban nyomon követő üzenetet írok a következő szuper-előadásról.

pool-kísérő-preact

Elrendezés fejléccel, testtel, oldalsávval és 2 reaktív elemmel

Képzelje el ezt az elrendezést, és tegyünk úgy, mintha a szürke mezők teljesen statikus elemek lennének, és azt szeretné, hogy a lila színű interaktívak legyenek. Például a nagyobb lehet egy Twitter-hírcsatorna, a kisebb pedig egy apró szavazási eszköz. Tehát a JavaScriptet alkalmaznunk kell ezekre az elemekre, hogy interaktívvá váljunk, és a többi elemet statikus elemekként akarjuk hagyni.

Példa erre a megvalósításra a pool-attendant-preact használatával:

A 3–8. Sorok mind azok az összetevők, amelyeket meg akarunk jeleníteni, ezeket az összetevőket kiszolgálón jelenítik meg, majd HTML és CSS formátumban küldik el az ügyfélnek JavaScript nélkül.

A 10. és 11. sorban jelöljük meg a TwitterFeed és Poll összetevőket hidratáláshoz, és új alkatrészt kapunk cserébe. A 18. és 19. sorban használjuk őket.

A 22. vonal rendkívül fontos. Ez egy olyan elem, amely a hidratációs adatokat (kellékeket és alkotóelemneveket) adja az oldalra.

De hadd magyarázzam el. Ha normál hidratálást hajtunk végre reagálással, akkor a kódja így néz ki:

Két problémát kell megoldani itt, amikor részleges hidratálást hajtunk végre

  1. A ReactDOM.hydrate a DOM gyökércsomópontján működik, azon a csomóponton, amelyet a hidratálás kiindulópontjaként használ. Ennek a gyökércsomópontnak tartalmaznia kell egy szerver által nyújtott DOM-fát, amely megfelel az alkalmazás összetevőinek és állapotának. Fogás: A gyökér csomópontként való működéshez kifejezetten meg kell neveznie a DOM-csomópontot. Ebben a példában ez egyszerű, megadhat egy csomóponthoz azonosítót, használhatja a document.getElementbyId fájlt, majd dobhatja azt a csomópontba a ReactDOM.hydrate fájlba, és kész!
    A részleges hidratáció viszont azt jelenti, hogy a statikus oldalon több DOM elem lesz, amelyet hidratálni kell. Nem akarna kifejezetten megnevezni azokat, amelyek unalmas munka a fejlesztő számára.
  2. Mi van, ha a HydrateTwitterFeed vagy a HydratedPoll kiegészítőkhöz van szükség, amelyeket át kell adni nekik? Mondja, hogy valami olyan, mint a . Ha a ReactDOM.hydrate-t (, rootElementOnThePage) szeretnénk futtatni, honnan szerezzük a luke_schmuke-t? Hogyan tudna egy statikus oldal erről? Valahogy meg kell tárolnunk és el kell küldenünk az ügyfélnek.

Megoldás

Az, hogy hogyan kezeljük ezt a problémát, megérthető a withHydration végrehajtásával:

Nézzük meg közelebbről ezt: aHydration a magasabb rendû összetevõ technikát használja, a magasabb rendû összetevõ visszatér az eredeti alkotóelemhez az eredeti változatlan támaszkodással, de egy