Performanță front-end 2021: definirea mediului

Publicat: 2022-03-10
Rezumat rapid ↬ Să facem 2021... repede! O listă anuală de verificare a performanței front-end cu tot ce trebuie să știți pentru a crea experiențe rapide pe web astăzi, de la valori până la instrumente și tehnici front-end. Actualizat din 2016.

Cuprins

  1. Pregătirea: planificare și valori
  2. Stabilirea obiectivelor realiste
  3. Definirea Mediului
  4. Optimizări ale activelor
  5. Construiți optimizări
  6. Optimizări de livrare
  7. Rețea, HTTP/2, HTTP/3
  8. Testare și monitorizare
  9. Victorii rapide
  10. Totul pe o singură pagină
  11. Descărcați Lista de verificare (PDF, Apple Pages, MS Word)
  12. Abonați-vă la buletinul nostru informativ prin e-mail pentru a nu rata următoarele ghiduri.

Definirea Mediului

  1. Alegeți și configurați-vă instrumentele de construcție.
    Nu acordați prea multă atenție la ceea ce se presupune că este cool în aceste zile. Țineți de mediul dvs. pentru a construi, fie că este Grunt, Gulp, Webpack, Parcel sau o combinație de instrumente. Atâta timp cât obțineți rezultatele de care aveți nevoie și nu aveți probleme în menținerea procesului de construcție, vă descurci bine.

    Printre instrumentele de construire, Rollup continuă să câștige acțiune, la fel și Snowpack, dar Webpack pare să fie cel mai stabilit, cu literalmente sute de plugin-uri disponibile pentru a optimiza dimensiunea construcțiilor tale. Atenție la Foaia de parcurs Webpack 2021.

    Una dintre cele mai notabile strategii care a apărut recent este fragmentarea granulară cu Webpack în Next.js și Gatsby pentru a minimiza codul duplicat. În mod implicit, modulele care nu sunt partajate în fiecare punct de intrare pot fi solicitate pentru rutele care nu îl folosesc. Acest lucru ajunge să devină o suprasarcină, deoarece se descarcă mai mult cod decât este necesar. Cu fragmentarea granulară în Next.js, putem folosi un fișier manifest de compilare pe partea serverului pentru a determina ce fragmente rezultate sunt utilizate de diferite puncte de intrare.

    Pentru a reduce codul duplicat în proiectele Webpack, putem folosi fragmentarea granulară, activată în Next.js și Gatsby în mod implicit
    Pentru a reduce codul duplicat în proiectele Webpack, putem folosi fragmentarea granulară, activată în Next.js și Gatsby în mod implicit. Credit imagine: Addy Osmani. (Previzualizare mare)

    Cu SplitChunksPlugin, mai multe bucăți divizate sunt create în funcție de un număr de condiții pentru a preveni preluarea codului duplicat pe mai multe rute. Acest lucru îmbunătățește timpul de încărcare a paginii și stocarea în cache în timpul navigării. Livrat în Next.js 9.2 și în Gatsby v2.20.7.

    Începerea cu Webpack poate fi totuși dificilă. Deci, dacă doriți să vă scufundați în Webpack, există câteva resurse excelente:

    • Documentația Webpack – evident – ​​este un bun punct de plecare, la fel și Webpack – The Confusing Bits de Raja Rao și An Annotated Webpack Config de Andrew Welch.
    • Sean Larkin are un curs gratuit despre Webpack: Conceptele de bază, iar Jeffrey Way a lansat un curs gratuit fantastic despre Webpack pentru toată lumea. Ambele sunt introduceri grozave pentru scufundarea în Webpack.
    • Webpack Fundamentals este un curs foarte cuprinzător de 4 ore cu Sean Larkin, lansat de FrontendMasters.
    • Exemplele Webpack au sute de configurații Webpack gata de utilizare, clasificate după subiect și scop. Bonus: există și un configurator de configurare Webpack care generează un fișier de configurare de bază.
    • awesome-webpack este o listă organizată de resurse, biblioteci și instrumente utile Webpack, inclusiv articole, videoclipuri, cursuri, cărți și exemple pentru proiecte Angular, React și agnostice de framework.
    • Călătoria către construirea rapidă a activelor de producție cu Webpack este studiul de caz al Etsy despre modul în care echipa a trecut de la utilizarea unui sistem de compilare JavaScript bazat pe RequireJS la utilizarea Webpack și modul în care și-au optimizat versiunile, gestionând peste 13.200 de active în medie în 4 minute .
    • Sfaturi de performanță Webpack este un fir de aur al lui Ivan Akulov, care conține multe sfaturi axate pe performanță, inclusiv cele axate în mod special pe Webpack.
    • awesome-webpack-perf este o mină de aur GitHub repo cu instrumente utile Webpack și pluginuri pentru performanță. De asemenea, întreținut de Ivan Akulov.
O vizualizare a călătoriei Etsy către versiuni de producție rapide cu Webpack
Călătoria Etsy către versiuni rapide de producție cu Webpack (prin Addy Osmani) (previzualizare mare)
  1. Utilizați îmbunătățirea progresivă ca implicită.
    Totuși, după toți acești ani, păstrarea îmbunătățirii progresive ca principiu ghid al arhitecturii și implementării tale front-end este un pariu sigur. Proiectați și construiți mai întâi experiența de bază, apoi îmbunătățiți experiența cu funcții avansate pentru browsere capabile, creând experiențe rezistente. Dacă site-ul dvs. rulează rapid pe o mașină lentă cu un ecran slab într-un browser slab într-o rețea suboptimă, atunci va rula mai rapid doar pe o mașină rapidă cu un browser bun într-o rețea decentă.

    De fapt, cu modul de servire adaptiv, se pare că ducem îmbunătățirea progresivă la un alt nivel, oferind experiențe de bază „lite” dispozitivelor de ultimă generație și îmbunătățirea cu funcții mai sofisticate pentru dispozitivele de ultimă generație. Îmbunătățirea progresivă nu va dispărea în curând.

  2. Alegeți o bază de performanță puternică.
    Cu atât de multe necunoscute care influențează încărcarea — rețea, limitarea termică, evacuarea memoriei cache, scripturi terță parte, modele de blocare a analizatorului, I/O disc, latența IPC, extensii instalate, software antivirus și firewall-uri, sarcini de fundal ale CPU, constrângeri hardware și memorie, diferențe de cache L2/L3, RTTS — JavaScript are cel mai mare cost al experienței, alături de fonturile web care blochează redarea în mod implicit și imaginile care consumă adesea prea multă memorie. Pe măsură ce blocajele de performanță se îndepărtează de la server la client, în calitate de dezvoltatori, trebuie să luăm în considerare toate aceste necunoscute mult mai detaliat.

    Cu un buget de 170 KB care conține deja calea critică HTML/CSS/JavaScript, router, management de stat, utilități, cadrul și logica aplicației, trebuie să examinăm amănunțit costul de transfer al rețelei, timpul de analizare/compilare și costul de rulare. a cadrului ales de noi. Din fericire, am observat o îmbunătățire uriașă în ultimii ani în ceea ce privește viteza cu care browserele pot analiza și compila scripturi. Cu toate acestea, execuția JavaScript este încă principalul blocaj, așa că acordarea unei atenții sporite timpului de execuție a scriptului și rețelei poate avea impact.

    Tim Kadlec a efectuat o cercetare fantastică asupra performanței cadrelor moderne și le-a rezumat în articolul „Framelor JavaScript au un cost”. Vorbim adesea despre impactul cadrelor de sine stătătoare, dar, după cum remarcă Tim, în practică, nu este neobișnuit să aveți mai multe cadre în uz . Poate că o versiune mai veche a jQuery care este migrată încet la un cadru modern, împreună cu câteva aplicații vechi care folosesc o versiune mai veche de Angular. Prin urmare, este mai rezonabil să explorezi costul cumulativ al octeților JavaScript și al timpului de execuție a procesorului, care pot face cu ușurință experiențele utilizatorului abia utilizabile, chiar și pe dispozitivele de ultimă generație.

    În general, cadrele moderne nu acordă prioritate dispozitivelor mai puțin puternice , așa că experiențele pe un telefon și pe desktop vor fi adesea dramatic diferite în ceea ce privește performanța. Conform cercetărilor, site-urile cu React sau Angular petrec mai mult timp pe procesor decât altele (ceea ce, desigur, nu înseamnă neapărat că React este mai scump pe procesor decât Vue.js).

    Potrivit lui Tim, un lucru este evident: „dacă utilizați un cadru pentru a vă construi site-ul, faceți un compromis în ceea ce privește performanța inițială – chiar și în cele mai bune scenarii”.

Costul cadrelor, timpul CPU JavaScript: site-urile SPA funcționează slab
Costul cadrelor, JavaScript byes: site-urile SPA (încă) funcționează prost
Timpul CPU legat de scripturi pentru dispozitive mobile și octeți JavaScript pentru dispozitivele desktopv. În general, site-urile cu React sau Angular petrec mai mult timp pe procesor decât altele. Dar depinde de cum construiești site-ul. Cercetare de Tim Kadlec. (Previzualizare mare)
  1. Evaluați cadrele și dependențele.
    Acum, nu orice proiect are nevoie de un cadru și nu fiecare pagină a unei aplicații cu o singură pagină trebuie să încarce un cadru. În cazul Netflix, „eliminând React, mai multe biblioteci și codul de aplicație corespunzător din partea clientului a redus cantitatea totală de JavaScript cu peste 200 KB, provocând o reducere de peste 50% a timpului de interactivitate al Netflix pentru pagina de pornire deconectată. ." Apoi, echipa a folosit timpul petrecut de utilizatori pe pagina de destinație pentru a prelua React pentru paginile ulterioare pe care ar putea ajunge utilizatorii (citiți mai departe pentru detalii).

    Deci, ce se întâmplă dacă eliminați cu totul un cadru existent pe paginile critice? Cu Gatsby, puteți verifica gatsby-plugin-no-javascript care elimină toate fișierele JavaScript create de Gatsby din fișierele HTML statice. Pe Vercel, puteți permite, de asemenea, dezactivarea JavaScript de rulare în producție pentru anumite pagini (experimental).

    Odată ce un cadru este ales, vom rămâne cu el cel puțin câțiva ani, așa că, dacă trebuie să folosim unul, trebuie să ne asigurăm că alegerea noastră este informată și bine luată în considerare - și asta este valabil mai ales pentru valorile cheie de performanță pe care le avem îți pasă de.

    Datele arată că, în mod implicit, cadrele sunt destul de scumpe: 58,6% dintre paginile React sunt livrate peste 1 MB de JavaScript, iar 36% din încărcările paginilor Vue.js au un First Contentful Paint de <1,5 secunde. Potrivit unui studiu realizat de Ankur Sethi, „aplicația dvs. React nu se va încărca niciodată mai repede de aproximativ 1,1 secunde pe un telefon mediu din India, indiferent cât de mult îl optimizați. Aplicația Angular va dura întotdeauna cel puțin 2,7 secunde pentru a porni. utilizatorii aplicației tale Vue vor trebui să aștepte cel puțin o secundă înainte de a putea începe să o folosească.” Oricum, s-ar putea să nu vizați India ca piață principală, dar utilizatorii care vă accesează site-ul cu condiții de rețea suboptime vor avea o experiență comparabilă.

    Bineînțeles că este posibil să facem SPA-uri rapid, dar nu sunt rapid scoase din cutie, așa că trebuie să luăm în considerare timpul și efortul necesar pentru a le face și a le menține rapid. Probabil că va fi mai ușor dacă aleg de la început un cost de performanță de bază ușor.

    Deci, cum alegem un cadru ? Este o idee bună să luați în considerare cel puțin costul total pe dimensiune + timpii inițiali de execuție înainte de a alege o opțiune; Opțiunile ușoare precum Preact, Inferno, Vue, Svelte, Alpine sau Polymer pot face treaba foarte bine. Mărimea liniei de bază va defini constrângerile pentru codul aplicației dvs.

    După cum a menționat Seb Markbage, o modalitate bună de a măsura costurile de pornire pentru cadre este să randați mai întâi o vizualizare, apoi să o ștergeți și apoi să randați din nou , deoarece vă poate spune cum se scalează cadrul. Prima randare tinde să încălzească o grămadă de cod compilat leneș, de care un copac mai mare poate beneficia atunci când se scalează. A doua randare este practic o emulare a modului în care reutilizarea codului pe o pagină afectează caracteristicile de performanță pe măsură ce pagina crește în complexitate.

    Puteți merge până la evaluarea candidaților (sau a oricărei biblioteci JavaScript în general) pe sistemul de notare pe scară de 12 puncte al lui Sacha Greif, explorând funcții, accesibilitate, stabilitate, performanță, ecosistem de pachete , comunitate, curba de învățare, documentație, instrumente, istoric. , echipa, compatibilitate, securitate de exemplu.

    Perf Track urmărește performanța cadrului la scară
    Perf Track urmărește performanța cadrului la scară. (Previzualizare mare)

    De asemenea, vă puteți baza pe datele colectate pe web pe o perioadă mai lungă de timp. De exemplu, Perf Track urmărește performanța cadrului la scară, arătând scorurile Core Web Vitals agregate la origine pentru site-urile web construite în Angular, React, Vue, Polymer, Preact, Ember, Svelte și AMP. Puteți chiar să specificați și să comparați site-uri web create cu aplicația Gatsby, Next.js sau Create React, precum și site-uri web create cu Nuxt.js (Vue) sau Sapper (Svelte).

    Un bun punct de plecare este să alegeți o stivă implicită bună pentru aplicația dvs. Gatsby (React), Next.js (React), Vuepress (Vue), Preact CLI și PWA Starter Kit oferă valori implicite rezonabile pentru încărcarea rapidă din cutie pe hardware-ul mobil mediu. ​​De asemenea, aruncați o privire la ghidurile de performanță specifice cadrului web.dev pentru React și Angular ( mulțumesc, Phillip! ).

    Și poate că ați putea adopta o abordare puțin mai revigorantă pentru a construi aplicații cu o singură pagină - Turbolinks, o bibliotecă JavaScript de 15 KB care utilizează HTML în loc de JSON pentru a reda vizualizări. Deci, atunci când urmați un link, Turbolinks preia automat pagina, schimbă <body> și îmbină <head> , totul fără a suporta costul unei încărcări complete a paginii. Puteți verifica detalii rapide și documentația completă despre stivă (Hotwire).

Un grafic asemănător histogramei care arată performanța de calcul a telefoanelor cele mai vândute
Procesorul și performanța de calcul a telefoanelor cele mai vândute (Credit imagine: Addy Osmani) (Previzualizare mare)
  1. Redare pe partea client sau pe partea server? Ambii!
    E o conversație destul de aprinsă. Abordarea finală ar fi să configurați un fel de pornire progresivă: utilizați randarea pe server pentru a obține o primă vopsea rapidă, dar includeți și niște JavaScript necesar minim pentru a menține timpul de interactiv aproape de First Contentful Paint. Dacă JavaScript vine prea târziu după FCP, browserul va bloca firul principal în timp ce analizează, compilează și execută JavaScript descoperit târziu, astfel cătușând interactivitatea site-ului sau a aplicației.

    Pentru a evita acest lucru, împărțiți întotdeauna execuția funcțiilor în sarcini separate, asincrone și, acolo unde este posibil, utilizați requestIdleCallback . Luați în considerare încărcarea leneșă a părților interfeței de utilizare folosind suportul pentru import() dinamic de la WebPack, evitând costurile de încărcare, analiză și compilare până când utilizatorii chiar au nevoie de ele ( mulțumesc Addy! ).

    După cum am menționat mai sus, Time to Interactive (TTI) ne indică timpul dintre navigare și interactivitate. În detaliu, valoarea este definită analizând prima fereastră de cinci secunde după redarea conținutului inițial, în care nicio activitate JavaScript nu durează mai mult de 50 ms ( Sarcini lungi ). Dacă are loc o sarcină de peste 50 ms, căutarea unei ferestre de cinci secunde începe de la capăt. Drept urmare, browserul va presupune mai întâi că a ajuns la Interactiv , doar pentru a trece la Înghețat , doar pentru a reveni în cele din urmă la Interactiv .

    Odată ce ajungem la Interactive , putem apoi, fie la cerere, fie în funcție de timp, să pornim părți neesențiale ale aplicației. Din păcate, după cum a observat Paul Lewis, cadrele nu au de obicei un concept simplu de prioritate care să poată fi prezentat dezvoltatorilor și, prin urmare, pornirea progresivă nu este ușor de implementat cu majoritatea bibliotecilor și cadrelor.

    Totuși, ajungem acolo. În aceste zile, există câteva opțiuni pe care le putem explora, iar Houssein Djirdeh și Jason Miller oferă o imagine de ansamblu excelentă asupra acestor opțiuni în discursul lor despre Rendering on the Web și în articolul lui Jason și Addy despre arhitecturile moderne front-end. Prezentare generală de mai jos se bazează pe munca lor stelară.

    • Redare completă pe partea de server (SSR)
      În SSR clasic, cum ar fi WordPress, toate solicitările sunt gestionate în întregime pe server. Conținutul solicitat este returnat ca o pagină HTML finalizată, iar browserele îl pot reda imediat. Prin urmare, aplicațiile SSR nu pot folosi cu adevărat API-urile DOM, de exemplu. Diferența dintre First Contentful Paint și Time to Interactive este de obicei mică, iar pagina poate fi redată imediat pe măsură ce HTML este transmis în flux în browser.

      Acest lucru evită călătoriile dus-întors suplimentare pentru preluarea datelor și modelarea pe client, deoarece acestea sunt gestionate înainte ca browserul să primească un răspuns. Cu toate acestea, ajungem la un timp de gândire mai lung de server și, în consecință, Time To First Byte și nu folosim funcțiile receptive și bogate ale aplicațiilor moderne.

    • Redare statică
      Construim produsul ca o aplicație cu o singură pagină, dar toate paginile sunt preredate în HTML static cu JavaScript minim ca pas de construire. Aceasta înseamnă că, cu randarea statică, producem fișiere HTML individuale pentru fiecare adresă URL posibilă înainte de timp, ceea ce nu își pot permite multe aplicații. Dar pentru că HTML-ul pentru o pagină nu trebuie să fie generat din mers, putem obține un Time To First Byte constant rapid. Astfel, putem afișa rapid o pagină de destinație și apoi prefacem un cadru SPA pentru paginile ulterioare. Netflix a adoptat această abordare reducând încărcarea și Time-to-Interactive cu 50%.

    • Redare pe server cu (re)hidratare (Răzare universală, SSR + CSR)
      Putem încerca să folosim tot ce este mai bun din ambele lumi - abordările SSR și CSR. Cu hidratare în amestec, pagina HTML returnată de la server conține și un script care încarcă o aplicație completă pe partea clientului. În mod ideal, se obține o primă vopsea cu conținut rapid (cum ar fi SSR) și apoi se continuă randarea cu (re)hidratare. Din păcate, asta se întâmplă rar. Mai des, pagina pare gata, dar nu poate răspunde la inputul utilizatorului, producând clicuri furioase și abandonuri.

      Cu React, putem folosi modulul ReactDOMServer pe un server Node precum Express și apoi apelăm metoda renderToString pentru a reda componentele de nivel superior ca șir HTML static.

      Cu Vue.js, putem folosi vue-server-renderer pentru a reda o instanță Vue în HTML folosind renderToString . În Angular, putem folosi @nguniversal pentru a transforma cererile clienților în pagini HTML redate complet pe server. O experiență complet redată pe server poate fi obținută și imediat cu Next.js (React) sau Nuxt.js (Vue).

      Abordarea are dezavantajele ei. Drept urmare, obținem flexibilitate deplină a aplicațiilor de pe partea client, oferind în același timp o randare mai rapidă pe partea de server, dar ajungem și la un decalaj mai lung între First Contentful Paint și Time To Interactive și o întârziere crescută pentru prima introducere. Rehidratarea este foarte costisitoare și, de obicei, această strategie singură nu va fi suficient de bună, deoarece întârzie foarte mult Time To Interactive.

    • Redare în flux pe server cu hidratare progresivă (SSR + CSR)
      Pentru a minimiza diferența dintre Time To Interactive și First Contentful Paint, redăm mai multe solicitări simultan și trimitem conținutul în bucăți pe măsură ce sunt generate. Deci, nu trebuie să așteptăm șirul complet de HTML înainte de a trimite conținut către browser și, prin urmare, să îmbunătățim Time To First Byte.

      În React, în loc de renderToString() , putem folosi renderToNodeStream() pentru a canaliza răspunsul și a trimite codul HTML în bucăți. În Vue, putem folosi renderToStream() care poate fi transmis și transmis în flux. Cu React Suspense, am putea folosi și redarea asincronă în acest scop.

      Pe partea clientului, mai degrabă decât pornirea întregii aplicații deodată, pornim componentele progresiv . Secțiunile aplicațiilor sunt mai întâi împărțite în scripturi de sine stătătoare cu împărțirea codului și apoi hidratate treptat (în ordinea priorităților noastre). De fapt, putem hidrata mai întâi componentele critice, în timp ce restul ar putea fi hidratate mai târziu. Rolul redării pe partea client și pe partea serverului poate fi apoi definit diferit pe componentă. De asemenea, putem amâna hidratarea unor componente până când acestea apar sau sunt necesare pentru interacțiunea cu utilizatorul sau când browserul este inactiv.

      Pentru Vue, Markus Oberlehner a publicat un ghid despre reducerea timpului de interacțiune al aplicațiilor SSR folosind hidratarea în interacțiunea utilizatorului, precum și vue-lazy-hydration, un plugin în stadiu incipient care permite hidratarea componentelor pe vizibilitate sau interacțiunea utilizatorului specific. Echipa Angular lucrează la hidratarea progresivă cu Ivy Universal. Puteți implementa hidratarea parțială și cu Preact și Next.js.

    • Redare trizomorfă
      Cu lucrătorii de servicii la locul lor, putem folosi redarea serverului de streaming pentru navigarea inițială/non-JS și apoi îl putem lăsa pe lucrătorul de service să preia redarea HTML pentru navigații după ce acesta a fost instalat. În acest caz, lucrătorul de servicii redă în prealabil conținutul și activează navigarea în stil SPA pentru redarea de noi vizualizări în aceeași sesiune. Funcționează bine atunci când puteți partaja același cod de șabloane și rutare între server, pagina client și lucrător de service.

    O ilustrație care arată modul în care redarea trisomorfă funcționează în 3 locuri, cum ar fi redarea DOM, randarea anterioară a lucrătorului de servicii și redarea pe server
    Redare trisomorfă, cu aceeași redare a codului în oricare 3 locuri: pe server, în DOM sau într-un service worker. (Sursa imagine: Google Developers) (Previzualizare mare)
    • CSR cu prerendare
      Pre-rendarea este similară cu redarea pe server, dar mai degrabă decât redarea dinamică a paginilor de pe server, redăm aplicația la HTML static în momentul construirii. În timp ce paginile statice sunt complet interactive, fără prea mult JavaScript la nivel de client, pre- rendarea funcționează diferit . Practic, captează starea inițială a unei aplicații de pe partea client ca HTML static la momentul construirii, în timp ce cu pre-rendarea aplicația trebuie să fie pornită pe client pentru ca paginile să fie interactive.

      Cu Next.js, putem folosi exportul HTML static prin predarea unei aplicații în HTML static. În Gatsby, un generator de site-uri static open source care folosește React, folosește metoda renderToStaticMarkup în loc de metoda renderToString în timpul build-urilor, cu fragmentul JS principal preîncărcat și rutele viitoare sunt preîncărcate, fără atribute DOM care nu sunt necesare pentru paginile statice simple.

      Pentru Vue, putem folosi Vuepress pentru a atinge același obiectiv. De asemenea, puteți utiliza pre-render-loader cu Webpack. Navi oferă și randare statică.

      Rezultatul este un Time To First Byte și First Contentful Paint mai bun și reducem decalajul dintre Time To Interactive și First Contentful Paint. Nu putem folosi abordarea dacă se preconizează că conținutul se va schimba mult. În plus, toate adresele URL trebuie cunoscute din timp pentru a genera toate paginile. Așadar, unele componente ar putea fi redate folosind prerendarea, dar dacă avem nevoie de ceva dinamic, trebuie să ne bazăm pe aplicație pentru a prelua conținutul.

    • Redare completă la nivelul clientului (CSR)
      Toată logica, randarea și pornirea se fac pe client. Rezultatul este de obicei un decalaj uriaș între Time To Interactive și First Contentful Paint. Ca rezultat, aplicațiile se simt adesea lente , deoarece întreaga aplicație trebuie pornită pe client pentru a reda orice.

      Deoarece JavaScript are un cost de performanță, pe măsură ce cantitatea de JavaScript crește cu o aplicație, împărțirea agresivă a codului și amânarea JavaScript va fi absolut necesar pentru a diminua impactul JavaScript. Pentru astfel de cazuri, o redare pe partea serverului va fi de obicei o abordare mai bună în cazul în care nu este nevoie de multă interactivitate. Dacă nu este o opțiune, luați în considerare utilizarea modelului App Shell.

      În general, SSR este mai rapid decât CSR. Cu toate acestea, este o implementare destul de frecventă pentru multe aplicații de acolo.

    Deci, partea client sau partea serverului? În general, este o idee bună să limitați utilizarea cadrelor pe partea clientului la paginile care le necesită absolut. Pentru aplicațiile avansate, nici nu este o idee bună să te bazezi doar pe randarea serverului. Atât redarea serverului, cât și redarea clientului sunt un dezastru dacă sunt făcute prost.

    Indiferent dacă înclinați spre CSR sau SSR, asigurați-vă că redați pixeli importanți cât mai curând posibil și minimizați decalajul dintre acea redare și Time To Interactive. Luați în considerare pre-rendarea dacă paginile dvs. nu se schimbă prea mult și amânați pornirea cadrelor dacă puteți. Transmiteți HTML în bucăți cu randare pe partea de server și implementați hidratarea progresivă pentru randarea pe partea clientului - și hidratați-vă pe vizibilitate, interacțiune sau în timpul inactiv pentru a obține ce este mai bun din ambele lumi.

Un tabel care compară opțiunile pentru randarea pe partea client versus pe partea serverului
Spectrul de opțiuni pentru randarea pe partea client versus pe partea serverului. De asemenea, verificați discursul lui Jason și Houssein la Google I/O despre Implicațiile de performanță ale arhitecturii aplicațiilor. (Sursa imagine: Jason Miller) (Previzualizare mare)
Un exemplu de site-ul web al AirBnB care arată fără hidratare progresivă în stânga și cu hidratare progresivă în dreapta
AirBnB a experimentat hidratarea progresivă; ele amână componentele care nu sunt necesare, se încarcă pe interacțiunea utilizatorului (defilare) sau în timpul inactiv și testele arată că poate îmbunătăți TTI. (Previzualizare mare)
  1. Cât putem servi static?
    Indiferent dacă lucrați la o aplicație mare sau un site mic, merită să luați în considerare ce conținut ar putea fi servit static dintr-un CDN (adică JAM Stack), mai degrabă decât să fie generat dinamic din mers. Chiar dacă aveți mii de produse și sute de filtre cu o mulțime de opțiuni de personalizare, este posibil să doriți totuși să vă difuzați paginile de destinație critice în mod static și să decuplați aceste pagini de cadrul ales.

    Există o mulțime de generatoare de site-uri statice și paginile pe care le generează sunt adesea foarte rapide. Cu cât putem preconstrui mai mult conținut din timp în loc să generăm vizualizări de pagină pe un server sau client la momentul solicitării, cu atât vom obține o performanță mai bună.

    În Construirea de site-uri web statice parțial hidratate, îmbunătățite progresiv, Markus Oberlehner arată cum să construiți site-uri web cu un generator de site-uri static și un SPA, obținând în același timp îmbunătățiri progresive și o dimensiune minimă a pachetului JavaScript. Markus folosește Eleventy și Preact ca instrumente și arată cum să configurați instrumentele, să adăugați hidratare parțială, hidratare leneșă, fișier de introducere a clientului, configurați Babel pentru Preact și combinați Preact cu Rollup - de la început până la sfârșit.

    Odată cu JAMStack folosit pe site-uri mari în zilele noastre, a apărut un nou aspect de performanță: timpul de construire . De fapt, construirea chiar și a mii de pagini cu fiecare implementare nouă poate dura câteva minute, așa că este promițător să vedem versiuni incrementale în Gatsby care îmbunătățesc timpul de construcție de 60 de ori , cu o integrare în soluții CMS populare precum WordPress, Contentful, Drupal, Netlify CMS si altii.

    O diagramă de flux care arată utilizatorul 1 în stânga sus și utilizatorul 2 în stânga jos care arată procesul de regenerare incrementală a stării
    Regenerare statică incrementală cu Next.js. (Credit imagine: Prisma.io) (Previzualizare mare)

    De asemenea, Next.js a anunțat generarea statică anticipată și incrementală, ceea ce ne permite să adăugăm noi pagini statice în timpul execuției și să actualizăm paginile existente după ce au fost deja construite, redându-le în fundal pe măsură ce traficul intră. .

    Aveți nevoie de o abordare și mai ușoară? În discursul său despre Eleventy, Alpine și Tailwind: spre un Jamstack ușor, Nicola Goutay explică diferențele dintre CSR, SSR și tot ceea ce există între ele și arată cum să folosești o abordare mai ușoară - împreună cu un depozit GitHub care arată abordarea in practica.

  2. Luați în considerare utilizarea modelului PRPL și a arhitecturii shell a aplicației.
    Cadrele diferite vor avea efecte diferite asupra performanței și vor necesita strategii diferite de optimizare, așa că trebuie să înțelegeți clar toate piulițele și șuruburile cadrului pe care vă veți baza. Când construiți o aplicație web, analizați modelul PRPL și arhitectura shell-ului aplicației. Ideea este destul de simplă: împingeți codul minim necesar pentru a deveni interactiv pentru ca ruta inițială să fie redată rapid, apoi utilizați service worker pentru stocarea în cache și resursele de pre-caching și apoi rutele de încărcare leneră de care aveți nevoie, în mod asincron.
Model PRPL în arhitectura shell-ului aplicației
PRPL înseamnă Pushing critical resource, Rendering initial route, Pre-caching rute rămase și Lazy-loading resting rute on demand.
Arhitectura shell de aplicație
Un shell de aplicație este HTML, CSS și JavaScript minim care alimentează o interfață cu utilizatorul.
  1. Ați optimizat performanța API-urilor dvs.?
    API-urile sunt canale de comunicare pentru ca o aplicație să expună date la aplicații interne și terțe prin intermediul punctelor finale . Când proiectăm și construim un API, avem nevoie de un protocol rezonabil pentru a permite comunicarea dintre server și solicitările terților. Transferul de stat reprezentativ ( REST ) este o alegere logică bine stabilită: definește un set de constrângeri pe care dezvoltatorii le urmează pentru a face conținutul accesibil într-un mod performant, fiabil și scalabil. Serviciile web care se conformează constrângerilor REST se numesc servicii web RESTful .

    Ca și în cazul cererilor HTTP vechi, atunci când datele sunt preluate dintr-un API, orice întârziere în răspunsul serverului se va propaga către utilizatorul final, prin urmare întârzierea redării . Când o resursă dorește să recupereze unele date dintr-un API, va trebui să solicite datele de la punctul final corespunzător. O componentă care redă date din mai multe resurse, cum ar fi un articol cu ​​comentarii și fotografii ale autorului în fiecare comentariu, poate avea nevoie de mai multe călătorii dus-întors la server pentru a prelua toate datele înainte de a putea fi redate. În plus, cantitatea de date returnată prin REST este adesea mai mare decât ceea ce este necesar pentru a reda acea componentă.

    Dacă multe resurse necesită date de la un API, API-ul poate deveni un blocaj de performanță. GraphQL oferă o soluție performantă la aceste probleme. În sine, GraphQL este un limbaj de interogare pentru API-ul dvs. și un timp de execuție pe partea de server pentru executarea interogărilor utilizând un sistem de tipuri pe care îl definiți pentru datele dvs. Spre deosebire de REST, GraphQL poate prelua toate datele într-o singură solicitare , iar răspunsul va fi exact ceea ce este necesar, fără preluarea excesivă sau insuficientă a datelor, așa cum se întâmplă de obicei cu REST.

    În plus, deoarece GraphQL folosește o schemă (metadatele care indică modul în care sunt structurate datele), poate deja organiza datele în structura preferată, așa că, de exemplu, cu GraphQL, am putea elimina codul JavaScript folosit pentru gestionarea statului, producând un cod de aplicație mai curat, care rulează mai rapid pe client.

    Dacă doriți să începeți cu GraphQL sau să întâlniți probleme de performanță, aceste articole ar putea fi foarte utile:

    • A GraphQL Primer: De ce avem nevoie de un nou tip de API de Eric Baer,
    • A GraphQL Primer: Evoluția designului API de Eric Baer,
    • Proiectarea unui server GraphQL pentru performanță optimă de către Leonardo Losoviz,
    • Performanța GraphQL explicată de Wojciech Trocki.
Două exemple de interfețe mobile pentru mesaje în timp ce utilizați Redux/REST (stânga) și Apollo/GraphQL (dreapta)
O diferență între REST și GraphQL, ilustrată printr-o conversație între Redux + REST în stânga, un Apollo + GraphQL în dreapta. (Sursa imagine: Hacker Noon) (Previzualizare mare)
  1. Veți folosi AMP sau Instant Articles?
    În funcție de prioritățile și strategia organizației dvs., vă recomandăm să luați în considerare utilizarea AMP de la Google sau articolele instantanee de la Facebook sau Apple News de la Apple. Puteți obține performanțe bune fără ele, dar AMP oferă un cadru de performanță solid cu o rețea gratuită de livrare a conținutului (CDN), în timp ce articolele instantanee vă vor spori vizibilitatea și performanța pe Facebook.

    Beneficiul aparent evident al acestor tehnologii pentru utilizatori este performanța garantată , așa că uneori ar putea chiar prefera linkurile AMP-/Apple News/Instant Pages în locul paginilor „obișnuite” și potențial umflate. Pentru site-urile web cu conținut intens, care au de-a face cu o mulțime de conținut terță parte, aceste opțiuni ar putea ajuta la accelerarea dramatică a timpilor de randare.

    Doar dacă nu o fac. Potrivit lui Tim Kadlec, de exemplu, „documentele AMP tind să fie mai rapide decât omologii lor, dar nu înseamnă neapărat că o pagină este performantă. Nu AMP este ceea ce face diferența cea mai mare din perspectiva performanței”.

    Un beneficiu pentru proprietarul site-ului este evident: descoperirea acestor formate pe platformele respective și vizibilitate sporită în motoarele de căutare.

    Ei bine, cel puțin așa era înainte. Întrucât AMP nu mai este o cerință pentru Top Stories , editorii ar putea să treacă de la AMP la o stivă tradițională ( mulțumesc, Barry! ).

    Totuși, ai putea crea și AMP-uri web progresive, reutilizand AMP-urile ca sursă de date pentru PWA. Dezavantaj? Evident, o prezență într-o grădină cu pereți plasează dezvoltatorii în situația de a produce și de a menține o versiune separată a conținutului lor, iar în cazul articolelor Instant și Apple News fără URL-uri reale (mulțumesc Addy, Jeremy!) .

  2. Alege-ți CDN-ul cu înțelepciune.
    După cum s-a menționat mai sus, în funcție de câte date dinamice aveți, este posibil să puteți „externaliza” o parte din conținut către un generator de site static, împingând-o către un CDN și servind o versiune statică din acesta, evitând astfel solicitările către Server. De fapt, unii dintre acești generatori sunt de fapt compilatori de site-uri web, cu multe optimizări automate furnizate de la cutie. Pe măsură ce compilatorii adaugă optimizări în timp, rezultatul compilat devine mai mic și mai rapid în timp.

    Observați că CDN-urile pot difuza (și descărca) și conținut dinamic. Deci, restricționarea CDN-ului dvs. la active statice nu este necesară. Verificați de două ori dacă CDN-ul dvs. efectuează compresie și conversie (de exemplu, optimizarea imaginii și redimensionarea la margine), dacă oferă suport pentru lucrătorii serverului, testare A/B, precum și include de la margine, care asambla părți statice și dinamice ale paginilor la marginea CDN-ului (adică serverul cel mai apropiat de utilizator) și alte sarcini. De asemenea, verificați dacă CDN-ul dvs. acceptă HTTP prin QUIC (HTTP/3).

    Katie Hempenius a scris un ghid fantastic pentru CDN-uri care oferă informații despre cum să alegeți un CDN bun , cum să-l reglați și toate lucrurile mici de care trebuie să aveți în vedere atunci când evaluați unul. În general, este o idee bună să stocați în cache conținutul cât mai agresiv posibil și să activați funcții de performanță CDN precum Brotli, TLS 1.3, HTTP/2 și HTTP/3.

    Notă : pe baza cercetărilor lui Patrick Meenan și Andy Davies, prioritizarea HTTP/2 este efectiv întreruptă pe multe CDN-uri, așa că aveți grijă când alegeți un CDN. Patrick are mai multe detalii în discursul său despre prioritizarea HTTP/2 ( mulțumesc, Barry! ).

    Previzualizare CDNPerf a numelor CDN și viteza de interogare în ms
    CDNPerf măsoară viteza de interogare pentru CDN-uri prin adunarea și analizarea a 300 de milioane de teste în fiecare zi. (Previzualizare mare)

    Atunci când alegeți un CDN, puteți utiliza aceste site-uri de comparare cu o prezentare detaliată a caracteristicilor lor:

    • CDN Comparison, o matrice de comparație CDN pentru Cloudfront, Aazure, KeyCDN, Fastly, Verizon, Stackpach, Akamai și multe altele.
    • CDN Perf măsoară viteza de interogare pentru CDN-uri prin colectarea și analiza a 300 de milioane de teste în fiecare zi, toate rezultatele fiind bazate pe datele RUM de la utilizatori din întreaga lume. Verificați, de asemenea, Comparația performanței DNS și Comparația performanței cloud.
    • CDN Planet Guides oferă o prezentare generală a CDN-urilor pentru anumite subiecte, cum ar fi Servire învechit, Purge, Origin Shield, Prefetch și Compression.
    • Almanahul web: Adopția și utilizarea CDN oferă informații despre furnizorii de top CDN, gestionarea lor RTT și TLS, timpul de negociere TLS, adoptarea HTTP/2 și altele. (Din păcate, datele sunt doar din 2019).

Cuprins

  1. Pregătirea: planificare și valori
  2. Stabilirea obiectivelor realiste
  3. Definirea Mediului
  4. Optimizări ale activelor
  5. Construiți optimizări
  6. Optimizări de livrare
  7. Rețea, HTTP/2, HTTP/3
  8. Testare și monitorizare
  9. Victorii rapide
  10. Totul pe o singură pagină
  11. Descărcați Lista de verificare (PDF, Apple Pages, MS Word)
  12. Abonați-vă la buletinul nostru informativ prin e-mail pentru a nu rata următoarele ghiduri.