Pagerinkite svetainių našumą analizuodami ir optimizuodami kritinį atvaizdavimo kelią. Išsamus vadovas kūrėjams apie JavaScript įtaką atvaizdavimui.
JavaScript našumo optimizavimas: išsami kritinio atvaizdavimo kelio analizė
Interneto programavimo pasaulyje greitis yra ne tik funkcija – tai geros vartotojo patirties pagrindas. Lėtai įsikelianti svetainė gali lemti didesnį atmetimo rodiklį, mažesnes konversijas ir nuviltą auditoriją. Nors svetainės našumą lemia daug veiksnių, viena iš pagrindinių ir dažnai klaidingai suprantamų koncepcijų yra kritinis atvaizdavimo kelias (CRP). Supratimas, kaip naršyklės atvaizduoja turinį ir, svarbiausia, kaip JavaScript sąveikauja su šiuo procesu, yra būtinas kiekvienam kūrėjui, rimtai žiūrinčiam į našumą.
Šis išsamus vadovas padės jums gilintis į kritinį atvaizdavimo kelią, ypatingą dėmesį skiriant JavaScript vaidmeniui. Išnagrinėsime, kaip jį analizuoti, nustatyti kliūtis ir taikyti galingus optimizavimo metodus, kurie padarys jūsų interneto programas greitesnes ir jautresnes pasaulinei vartotojų bazei.
Kas yra kritinis atvaizdavimo kelias?
Kritinis atvaizdavimo kelias – tai veiksmų seka, kurią naršyklė turi atlikti, kad paverstų HTML, CSS ir JavaScript matomais pikseliais ekrane. Pagrindinis CRP optimizavimo tikslas yra kuo greičiau atvaizduoti vartotojui pradinį, matomą be slinkimo turinį („above-the-fold“). Kuo greičiau tai įvyksta, tuo greičiau vartotojas suvokia, kad puslapis kraunasi.
Šis kelias susideda iš kelių pagrindinių etapų:
- DOM konstravimas: Procesas prasideda, kai naršyklė iš serverio gauna pirmuosius HTML dokumento baitus. Ji pradeda analizuoti HTML žymėjimą simbolis po simbolio ir kuria Dokumento objektų modelį (DOM). DOM yra medžio pavidalo struktūra, vaizduojanti visus HTML dokumento mazgus (elementus, atributus, tekstą).
- CSSOM konstravimas: Kai naršyklė kuria DOM, jei ji aptinka CSS stilių lentelę (
<link>žymoje arba<style>bloke), ji pradeda kurti CSS objektų modelį (CSSOM). Panašiai kaip DOM, CSSOM yra medžio struktūra, kurioje yra visi puslapio stiliai ir jų ryšiai. Skirtingai nei HTML, CSS pagal numatytuosius nustatymus yra atvaizdavimą blokuojantis. Naršyklė negali atvaizduoti jokios puslapio dalies, kol neatsisiunčia ir neapdoros viso CSS, nes vėlesni stiliai gali pakeisti ankstesnius. - Atvaizdavimo medžio konstravimas: Kai DOM ir CSSOM yra paruošti, naršyklė juos sujungia, kad sukurtų Atvaizdavimo medį. Šiame medyje yra tik tie mazgai, kurie reikalingi puslapiui atvaizduoti. Pavyzdžiui, elementai su
display: none;ir<head>žyma neįtraukiami į Atvaizdavimo medį, nes jie nėra vizualiai atvaizduojami. Atvaizdavimo medis žino, ką rodyti, bet ne kur ar kokio dydžio. - Išdėstymas (arba Reflow): Sukūrus Atvaizdavimo medį, naršyklė pereina į Išdėstymo etapą. Šiame etape ji apskaičiuoja tikslų kiekvieno Atvaizdavimo medžio mazgo dydį ir padėtį atsižvelgiant į peržiūros sritį (viewport). Šio etapo rezultatas yra „dėžutės modelis“ (box model), kuris apibrėžia tikslią kiekvieno elemento geometriją puslapyje.
- Piešimas (Paint): Galiausiai naršyklė paima išdėstymo informaciją ir „nupiešia“ kiekvieno mazgo pikselius ekrane. Tai apima teksto, spalvų, paveikslėlių, rėmelių ir šešėlių piešimą – iš esmės, visų vizualinių puslapio dalių rasterizavimą. Šis procesas gali vykti keliais sluoksniais, siekiant pagerinti efektyvumą.
- Komponavimas (Composite): Jei puslapio turinys buvo nupieštas keliais sluoksniais, naršyklė turi juos sujungti teisinga tvarka, kad ekrane būtų parodytas galutinis vaizdas. Šis žingsnis ypač svarbus animacijoms ir slinkimui, nes komponavimas paprastai reikalauja mažiau skaičiavimo resursų nei Išdėstymo ir Piešimo etapų pakartojimas.
Griaunantis JavaScript vaidmuo kritiniame atvaizdavimo kelyje
Taigi, kur šioje schemoje yra JavaScript? JavaScript yra galinga kalba, galinti modifikuoti tiek DOM, tiek CSSOM. Tačiau ši galia turi savo kainą. JavaScript gali, ir dažnai tai daro, blokuoti kritinį atvaizdavimo kelią, o tai lemia didelius atvaizdavimo vėlavimus.
Analizatorių blokuojantis JavaScript
Pagal numatytuosius nustatymus, JavaScript yra analizatorių blokuojantis. Kai naršyklės HTML analizatorius aptinka <script> žymą, jis turi sustabdyti DOM kūrimo procesą. Tada jis atsisiunčia (jei išorinis), analizuoja ir vykdo JavaScript failą. Šis procesas blokuoja, nes scenarijus gali atlikti veiksmą, pavyzdžiui, document.write(), kuris gali pakeisti visą DOM struktūrą. Naršyklė neturi kito pasirinkimo, kaip tik laukti, kol scenarijus baigs veikti, prieš saugiai tęsdama HTML analizę.
Jei šis scenarijus yra jūsų dokumento <head> dalyje, jis blokuoja DOM kūrimą pačioje pradžioje. Tai reiškia, kad naršyklė neturi turinio, kurį galėtų atvaizduoti, o vartotojas mato tuščią baltą ekraną, kol scenarijus bus visiškai apdorotas. Tai yra pagrindinė prasto suvokiamo našumo priežastis.
DOM ir CSSOM manipuliacija
JavaScript taip pat gali gauti informaciją iš CSSOM ir jį modifikuoti. Pavyzdžiui, jei jūsų scenarijus prašo apskaičiuoto stiliaus, pvz., element.style.width, naršyklė pirmiausia turi užtikrinti, kad visas CSS būtų atsiųstas ir išanalizuotas, kad pateiktų teisingą atsakymą. Tai sukuria priklausomybę tarp jūsų JavaScript ir CSS, kai scenarijaus vykdymas gali būti blokuojamas laukiant, kol CSSOM bus paruoštas.
Be to, jei JavaScript modifikuoja DOM (pvz., prideda ar pašalina elementą) arba CSSOM (pvz., keičia klasę), tai gali sukelti naršyklės darbo kaskadą. Pakeitimas gali priversti naršyklę iš naujo apskaičiuoti Išdėstymą („reflow“) ir tada iš naujo Nupiešti („re-Paint“) paveiktas ekrano dalis ar net visą puslapį. Dažnos ar netinkamu laiku atliekamos manipuliacijos gali sukelti lėtą, nereaguojančią vartotojo sąsają.
Kaip analizuoti kritinį atvaizdavimo kelią
Prieš optimizuodami, pirmiausia turite išmatuoti. Naršyklės kūrėjų įrankiai yra geriausias jūsų draugas analizuojant CRP. Susitelkime į „Chrome DevTools“, kuris siūlo galingą įrankių rinkinį šiam tikslui.
Naudojant „Performance“ skiltį
„Performance“ (Našumo) skiltis pateikia išsamią laiko juostą apie viską, ką naršyklė daro atvaizduodama jūsų puslapį.
- Atidarykite „Chrome DevTools“ (Ctrl+Shift+I arba Cmd+Option+I).
- Eikite į Performance skiltį.
- Įsitikinkite, kad pažymėtas „Web Vitals“ langelis, kad matytumėte pagrindinius rodiklius laiko juostoje.
- Spustelėkite perkrovimo mygtuką (arba paspauskite Ctrl+Shift+E / Cmd+Shift+E), kad pradėtumėte puslapio įkėlimo profiliavimą.
Kai puslapis įsikels, pamatysite liepsnos diagramą (flame chart). Štai į ką reikia atkreipti dėmesį Main (Pagrindinės gijos) sekcijoje:
- Long Tasks (Ilgos užduotys): Bet kuri užduotis, trunkanti ilgiau nei 50 milisekundžių, pažymėta raudonu trikampiu. Tai yra pagrindiniai optimizavimo kandidatai, nes jie blokuoja pagrindinę giją ir gali padaryti vartotojo sąsają nereaguojančia.
- Parse HTML (HTML analizė, mėlyna): Tai rodo, kur naršyklė analizuoja jūsų HTML. Jei matote didelius tarpus ar pertraukas, greičiausiai tai dėl blokuojančio scenarijaus.
- Evaluate Script (Scenarijaus vykdymas, geltona): Čia vykdomas JavaScript. Ieškokite ilgų geltonų blokų, ypač puslapio įkėlimo pradžioje. Tai yra jūsų blokuojantys scenarijai.
- Recalculate Style (Stiliaus perskaičiavimas, violetinė): Tai rodo CSSOM konstravimą ir stilių skaičiavimus.
- Layout (Išdėstymas, violetinė): Šie blokai vaizduoja Išdėstymo arba „reflow“ etapą. Jei matote daug tokių blokų, jūsų JavaScript gali sukelti „išdėstymo trankymą“ (layout thrashing), nuolat skaitant ir rašant geometrines savybes.
- Paint (Piešimas, žalia): Tai yra piešimo procesas.
Naudojant „Network“ skiltį
„Network“ (Tinklo) skilties krioklio diagrama (waterfall chart) yra neįkainojama norint suprasti išteklių atsisiuntimo tvarką ir trukmę.
- Atidarykite „DevTools“ ir eikite į Network skiltį.
- Perkraukite puslapį.
- Krioklio vaizdas rodo, kada kiekvienas išteklius (HTML, CSS, JS, paveikslėliai) buvo užklaustas ir atsiųstas.
Atkreipkite ypatingą dėmesį į užklausas krioklio viršuje. Galite lengvai pastebėti CSS ir JavaScript failus, kurie atsisiunčiami prieš pradedant atvaizduoti puslapį. Tai yra jūsų atvaizdavimą blokuojantys ištekliai.
Naudojant „Lighthouse“
„Lighthouse“ yra automatinis audito įrankis, integruotas į „Chrome DevTools“ („Lighthouse“ skiltyje). Jis pateikia aukšto lygio našumo balą ir praktines rekomendacijas.
Svarbiausias CRP auditas yra „Eliminate render-blocking resources“ (Pašalinti atvaizdavimą blokuojančius išteklius). Ši ataskaita aiškiai nurodys CSS ir JavaScript failus, kurie vėlina Pirmojo turinio atvaizdavimą (FCP), suteikdama jums aiškų optimizavimo tikslų sąrašą.
Pagrindinės JavaScript optimizavimo strategijos
Dabar, kai žinome, kaip nustatyti problemas, panagrinėkime sprendimus. Tikslas yra sumažinti JavaScript kiekį, kuris blokuoja pradinį atvaizdavimą.
1. `async` ir `defer` galia
Paprasčiausias ir efektyviausias būdas neleisti JavaScript blokuoti HTML analizatoriaus yra naudoti `async` ir `defer` atributus savo <script> žymose.
- Standartinė
<script>:<script src="script.js"></script>
Kaip jau aptarėme, tai blokuoja analizatorių. HTML analizė sustoja, scenarijus atsisiunčiamas ir vykdomas, o tada analizė tęsiama. <script async>:<script src="script.js" async></script>
Scenarijus atsisiunčiamas asinchroniškai, lygiagrečiai su HTML analize. Kai tik scenarijus baigia atsisiuntimą, HTML analizė sustabdoma ir scenarijus vykdomas. Vykdymo tvarka negarantuojama; scenarijai vykdomi, kai tik tampa prieinami. Tai geriausiai tinka nepriklausomiems, trečiųjų šalių scenarijams, kurie nepriklauso nuo DOM ar kitų scenarijų, pavyzdžiui, analitikos ar reklamos scenarijams.<script defer>:<script src="script.js" defer></script>
Scenarijus atsisiunčiamas asinchroniškai, lygiagrečiai su HTML analize. Tačiau scenarijus vykdomas tik po to, kai HTML dokumentas yra visiškai išanalizuotas (prieš pat `DOMContentLoaded` įvykį). Scenarijai su `defer` taip pat garantuotai vykdomi tokia tvarka, kokia jie pateikiami dokumente. Tai yra pageidaujamas metodas daugumai scenarijų, kuriems reikia sąveikauti su DOM ir kurie nėra kritiškai svarbūs pradiniam piešimui.
Bendra taisyklė: Naudokite `defer` savo pagrindiniams programos scenarijams. Naudokite `async` nepriklausomiems trečiųjų šalių scenarijams. Venkite naudoti blokuojančius scenarijus <head> dalyje, nebent jie yra absoliučiai būtini pradiniam atvaizdavimui.
2. Kodo skaidymas (Code Splitting)
Šiuolaikinės interneto programos dažnai yra supakuotos į vieną, didelį JavaScript failą. Nors tai sumažina HTTP užklausų skaičių, tai verčia vartotoją atsisiųsti daug kodo, kuris gali būti nereikalingas pradiniam puslapio vaizdui.
Kodo skaidymas yra procesas, kurio metu didelis paketas (bundle) suskaidomas į mažesnes dalis, kurias galima įkelti pagal poreikį. Pavyzdžiui:
- Pradinė dalis: Sudėtyje yra tik būtinas JavaScript, reikalingas matomai dabartinio puslapio daliai atvaizduoti.
- Pagal poreikį įkeliamos dalys: Sudėtyje yra kodas kitiems maršrutams, modaliniams langams ar funkcijoms, esančioms žemiau matomos srities. Jos įkeliamos tik tada, kai vartotojas pereina į tą maršrutą arba sąveikauja su funkcija.
Šiuolaikiniai paketų kūrėjai, tokie kaip Webpack, Rollup ir Parcel, turi integruotą kodo skaidymo palaikymą naudojant dinaminę `import()` sintaksę. Karkasai, tokie kaip „React“ (su `React.lazy`) ir „Vue“, taip pat suteikia lengvų būdų skaidyti kodą komponentų lygmeniu.
3. „Tree Shaking“ ir nenaudojamo kodo šalinimas
Net ir su kodo skaidymu, jūsų pradiniame pakete gali būti kodo, kuris iš tikrųjų nenaudojamas. Tai dažnai nutinka, kai importuojate bibliotekas, bet naudojate tik nedidelę jų dalį.
„Tree Shaking“ yra procesas, kurį naudoja šiuolaikiniai paketų kūrėjai, siekdami pašalinti nenaudojamą kodą iš jūsų galutinio paketo. Jis statiškai analizuoja jūsų `import` ir `export` sakinius ir nustato, kuris kodas yra nepasiekiamas. Užtikrindami, kad siunčiate tik tą kodą, kurio reikia jūsų vartotojams, galite žymiai sumažinti paketų dydžius, o tai lemia greitesnį atsisiuntimą ir analizės laiką.
4. Minifikavimas ir glaudinimas
Tai yra fundamentalūs žingsniai bet kuriai produkcinei svetainei.
- Minifikavimas: Tai automatinis procesas, kuris pašalina nereikalingus simbolius iš jūsų kodo – pavyzdžiui, tarpus, komentarus ir naujas eilutes – ir sutrumpina kintamųjų pavadinimus, nekeisdamas jo funkcionalumo. Tai sumažina failo dydį. Dažnai naudojami įrankiai, tokie kaip „Terser“ (JavaScript) ir „cssnano“ (CSS).
- Glaudinimas: Po minifikavimo, jūsų serveris turėtų suglaudinti failus prieš siųsdamas juos į naršyklę. Algoritmai, tokie kaip Gzip ir, dar efektyviau, Brotli, gali sumažinti failų dydžius iki 70-80%. Naršyklė juos išskleidžia gavusi. Tai yra serverio konfigūracija, tačiau ji yra labai svarbi siekiant sumažinti tinklo perdavimo laiką.
5. Kritinio JavaScript įterpimas (naudoti atsargiai)
Labai mažoms JavaScript dalims, kurios yra absoliučiai būtinos pirmajam piešimui (pvz., temos nustatymui ar kritiniam polifilui), galite jas įterpti tiesiai į savo HTML <script> žymoje <head> dalyje. Tai sutaupo tinklo užklausą, kas gali būti naudinga esant didelės delsos mobiliesiems ryšiams. Tačiau tai turėtų būti naudojama saikingai. Įterptas kodas padidina jūsų HTML dokumento dydį ir negali būti atskirai talpinamas naršyklės podėlyje (cache). Tai kompromisas, kurį reikėtų atidžiai apsvarstyti.
Pažangios technikos ir šiuolaikiniai metodai
Serverio pusės atvaizdavimas (SSR) ir statinis svetainių generavimas (SSG)
Karkasai, tokie kaip „Next.js“ („React“), „Nuxt.js“ („Vue“) ir „SvelteKit“, išpopuliarino SSR ir SSG. Šios technikos perkelia pradinio atvaizdavimo darbą iš kliento naršyklės į serverį.
- SSR: Serveris atvaizduoja visą HTML užklaustam puslapiui ir siunčia jį į naršyklę. Naršyklė gali nedelsiant parodyti šį HTML, todėl Pirmojo turinio atvaizdavimas (FCP) yra labai greitas. Tada JavaScript įsikrauna ir „hidratuoja“ puslapį, paversdamas jį interaktyviu.
- SSG: Kiekvieno puslapio HTML yra sugeneruojamas kūrimo metu (build time). Kai vartotojas užklausia puslapio, statinis HTML failas akimirksniu pateikiamas iš CDN. Tai greičiausias metodas turiniu gausioms svetainėms.
Tiek SSR, tiek SSG drastiškai pagerina CRP našumą, pateikdami prasmingą pirmąjį piešinį dar prieš pradedant vykdyti didžiąją dalį kliento pusės JavaScript.
Web Workers
Jei jūsų programai reikia atlikti sudėtingus, ilgai trunkančius skaičiavimus (pvz., sudėtingą duomenų analizę, vaizdų apdorojimą ar kriptografiją), tai darydami pagrindinėje gijoje blokuosite atvaizdavimą ir jūsų puslapis atrodys sustingęs. Web Workers siūlo sprendimą, leisdami vykdyti šiuos scenarijus fono gijoje, visiškai atskirai nuo pagrindinės vartotojo sąsajos gijos. Tai palaiko jūsų programos reaktyvumą, kol sunkūs darbai vyksta užkulisiuose.
Praktinė CRP optimizavimo darbo eiga
Sujunkime viską į praktinę darbo eigą, kurią galite taikyti savo projektuose.
- Auditas: Pradėkite nuo bazinės būklės. Paleiskite „Lighthouse“ ataskaitą ir „Performance“ profilį savo produkcinei versijai, kad suprastumėte dabartinę situaciją. Užsirašykite savo FCP, LCP, TTI rodiklius ir nustatykite bet kokias ilgas užduotis ar atvaizdavimą blokuojančius išteklius.
- Identifikavimas: Gilinkitės į „DevTools“ „Network“ ir „Performance“ skiltis. Tiksliai nustatykite, kurie scenarijai ir stilių lentelės blokuoja pradinį atvaizdavimą. Paklauskite savęs apie kiekvieną išteklių: „Ar tai absoliučiai būtina, kad vartotojas pamatytų pradinį turinį?“
- Prioritetų nustatymas: Sutelkite savo pastangas į kodą, kuris veikia matomą be slinkimo turinį. Tikslas yra kuo greičiau pateikti šį turinį vartotojui. Visa kita galima įkelti vėliau.
- Optimizavimas:
- Pritaikykite
defervisiems neesminiams scenarijams. - Naudokite
asyncnepriklausomiems trečiųjų šalių scenarijams. - Įdiekite kodo skaidymą savo maršrutams ir dideliems komponentams.
- Užtikrinkite, kad jūsų kūrimo procesas apimtų minifikavimą ir „tree shaking“.
- Bendradarbiaukite su savo infrastruktūros komanda, kad įjungtumėte „Brotli“ ar „Gzip“ glaudinimą savo serveryje.
- CSS atveju, apsvarstykite galimybę įterpti kritinį CSS, reikalingą pradiniam vaizdui, ir atidėti likusios dalies įkėlimą (lazy-loading).
- Pritaikykite
- Matavimas: Įgyvendinę pakeitimus, paleiskite auditą iš naujo. Palyginkite savo naujus balus ir laikus su pradiniais. Ar jūsų FCP pagerėjo? Ar sumažėjo atvaizdavimą blokuojančių išteklių?
- Iteravimas: Svetainės našumas nėra vienkartinis pataisymas; tai nuolatinis procesas. Augant jūsų programai, gali atsirasti naujų našumo kliūčių. Padarykite našumo auditą reguliaria savo kūrimo ir diegimo ciklo dalimi.
Išvada: įvaldant kelią į našumą
Kritinis atvaizdavimo kelias yra planas, kurio naršyklė laikosi, kad atgaivintų jūsų programą. Mūsų, kaip kūrėjų, supratimas ir kontrolė šio kelio, ypač kalbant apie JavaScript, yra vienas galingiausių svertų, kuriuos turime gerinti vartotojo patirtį. Pereidami nuo mąstysenos „rašyti kodą, kuris veikia“ prie „rašyti kodą, kuris veikia našiai“, galime kurti programas, kurios yra ne tik funkcionalios, bet ir greitos, prieinamos ir malonios vartotojams visame pasaulyje.
Kelionė prasideda nuo analizės. Atidarykite savo kūrėjo įrankius, profiliuokite savo programą ir pradėkite kvestionuoti kiekvieną išteklių, kuris stovi tarp jūsų vartotojo ir pilnai atvaizduoto puslapio. Taikydami scenarijų atidėjimo, kodo skaidymo ir turinio minimizavimo strategijas, galite atlaisvinti kelią naršyklei daryti tai, ką ji moka geriausiai: atvaizduoti turinį žaibišku greičiu.