CSS-in-JS kompromissid

Foto autor: Artem Bali

Hiljuti kirjutasin kõrgema taseme ülevaate CSS-in-JS-ist, rääkides enamasti probleemidest, mida see lähenemisviis üritab lahendada. Raamatukogu autorid investeerivad harva aega oma lahenduse kompromisside kirjeldamisse. Mõnikord on selle põhjuseks see, et nad on liiga kallutatud, ja mõnikord nad lihtsalt ei tea, kuidas kasutajad tööriista rakendavad. Nii et see on katse kirjeldada kompromisse, mida ma seni näinud olen. Arvan, et on oluline mainida, et olen JSSi autor, seega tuleks mind pidada erapoolikuks.

Sotsiaalne mõju

On üks osa inimesi, kes töötavad veebiplatvormil ja ei tea JavaScripti. Neile inimestele makstakse HTML-i ja CSS-i kirjutamist. CSS-in-JS on avaldanud arendajate töövoole tohutut mõju. Tõeliselt ümberkujundavat muutust ei saa kunagi teha ilma, et mõni inimene maha jääks. Ma ei tea, kas CSS-in-JS peab olema ainus viis, kuid massiline kasutuselevõtt on selge märk probleemidest CSS-i kasutamisel tänapäevastes rakendustes.

Suur osa probleemist on meie võimetus täpselt suhelda kasutusjuhtumitega, kus CSS-in-JS paistab ja kuidas seda ülesande jaoks õigesti kasutada. Paljud CSS-in-JS-i entusiastid on tehnoloogia edendamisel edukad olnud, kuid mitte paljud kriitikud ei rääkinud kompromissidest konstruktiivselt, ilma et oleks vaja tööriistu odavalt osta. Selle tulemusel jätsime paljud kompromissid peidetuks ega teinud pingutusi selgituse ja lahenduste pakkumisel.

CSS-in-JS on katse muuta keerukate kasutamise juhtumite käsitlemine lihtsamaks, nii et ärge lükake seda sinna, kus seda pole vaja!

Kestus maksab

Kui CSS genereeritakse JavaScripti kaudu käitusel, on brauseris omane üldkulud. Runtime overhead varieerub raamatukogus. See on hea üldine mõõdupuu, kuid tehke kindlasti oma testid. Käivituse ajal ilmnevad suured erinevused sõltuvalt vajadusest mallide stringide täieliku CSS-i parsimise järele, optimeerimiste hulgast, dünaamiliste stiilide rakendamise üksikasjadest, räsialgoritmi ja raamistiku integreerimise maksumusest. *

Lisaks võimalikule käitusaja üldkulule peate arvestama 4 erineva komplekteerimisstrateegiaga, sest mõned CSS-in-JS-i teegid toetavad mitut strateegiat ja kasutaja on nende rakendamine. *

1. strateegia: ainult tööaja genereerimine

Runtime CSS genereerimine on tehnika, mis genereerib CSS-i stringi JavaScriptis ja seejärel süstib selle stringi stiilisildi abil dokumenti. Selle tehnika abil saadakse stiilileht, MITTE tekstisiseseid stiile.

Käitusaja genereerimise kompromiss on võimetus pakkuda stiilset sisu juba varases staadiumis, kuna dokument hakkab laadima. See lähenemisviis sobib tavaliselt rakenduste jaoks, millel pole sisu, mis oleks kohe kasulik. Tavaliselt vajavad sellised rakendused kasutajaga suhtlemist, enne kui need saavad kasutajale tõeliselt kasulikud olla. Sageli töötavad sellised rakendused sisuga, mis on nii dünaamiline, et see vananeb kohe, kui laadite selle, nii et peate varakult looma värskenduste torujuhtme, näiteks Twitteri. Lisaks ei pea kasutaja sisselogimisel SEO HTML-i pakkuma.

Kui interaktsioon nõuab JavaScripti, tuleb kimp enne rakenduse valmimist laadida. Näiteks saate dokumendi Slack laadimisel näidata vaikekanali sisu, kuid on tõenäoline, et kasutaja soovib kanalit kohe pärast seda vahetada. Nii et kui laadisite algse sisu lihtsalt selleks, et need kohe ära visata.

Selliste rakenduste tajutavat toimivust saab parendada kohahoidjate ja muude nippidega, et rakendusel oleks kiirem tunne kui tegelikult. Sellised rakendused on niikuinii tavaliselt rasked, nii et need pole nii kiiresti kasulikud kui artikkel.

2. strateegia: Runtime genereerimine kriitilise CSS-iga

Kriitiline CSS on CSS-i minimaalne kogus, mis on vajalik lehe algkujul oleku kujundamiseks. Selle renderdamiseks kasutatakse dokumendi peas stiilsilti. Seda tehnikat kasutatakse laialdaselt koos CSS-in-JS-ga ja ilma selleta. Mõlemal juhul laadite tõenäoliselt CSS-i reeglid topelt, üks kord kriitilise CSS-i osana ja üks kord JavaScripti või CSS-i paketi osana. Kriitilise CSS-i suurus võib olla üsna suur, sõltuvalt sisu mahust. Tavaliselt ei salvestata dokumenti vahemällu.

Ilma kriitilise CSS-ita peab staatiline sisuga üheleheline rakendus koos käivitusaegse CSS-in-JS-ga näitama sisu asemel kohahoidjaid. See on halb, kuna see oleks võinud olla kasutajale kasulik juba palju varem, parandades nutitelefonide ja madala ribalaiusega ühenduste juurdepääsetavust.

Kriitilise CSS-i korral saab käitusaja CSS-i genereerida hiljem, UI-d algfaasis blokeerimata. Siiski tuleb hoiatada, et nutitelefonides, mis on vähemalt 5 aastat vanad, võib CSS-i genereerimine JavaScripti toimivusele negatiivset mõju avaldada. See sõltub suuresti loodava CSS-i hulgast ja kasutatavast teegist, nii et seda ei saa üldistada.

Selle strateegia kompromissiks on kriitilise CSS-i ekstraheerimise kulud ja CSS-i genereerimise käitamise kulud.

3. strateegia: ainult ehitustööde ajal toimuv kaevandamine

See strateegia on veebis vaikimisi ilma CSS-in-JS-ita. Mõned CSS-in-JS-i teegid võimaldavad teil staatilist CSS-i ekstraktida ehituse ajal. * Sel juhul pole käitusaja üldkulusid vaja, CSS-i renderdatakse lehel lingisildi abil. CSS-i genereerimise kulud tasutakse üks kord enne tähtaega.

Siin on 2 peamist kompromissi:

  1. Mõne dünaamilise API-liidese CSS-in-JS pakkumist ei saa käitusel kasutada, kuna teil pole olekule juurdepääsu. Tihti ei saa te CSS-i kohandatud atribuute endiselt kasutada, kuna neid ei toetata igas brauseris ja neid ei saa loomupäraselt täita. Sel juhul peate dünaamiliseks muutmiseks ja olekupõhiseks kujundamiseks tegema ümmargused toimingud. *
  2. Ilma kriitilise CSS-ita ja tühja vahemäluga blokeerite esimese värvi, kuni teie CSS-i kimp laaditakse. Lingi element dokumendi päises blokeerib HTML-i renderdamise.
  3. Mittedeterministlik eripära koos lehepõhise kimpude jagamisega ühelehelistes rakendustes. *

4. strateegia: ehituse ajalise kaevandamine kriitilise CSS-iga

See strateegia pole ka CSS-in-JS puhul ainulaadne. Täielik staatiline ekstraheerimine kriitilise CSS-iga tagab staatilisema rakendusega töötamisel parima jõudluse. Sellel lähenemisviisil on endiselt eelnimetatud staatilise CSS-i kompromissid, välja arvatud see, et blokeeriva lingi sildi saab teisaldada dokumendi põhja.

CSS-i renderdamise strateegiaid on 4. Ainult 2 neist on CSS-in-JS-i spetsiifilised ja ükski neist ei kehti kõigi raamatukogude kohta.

Juurdepääsetavus

CSS-in-JS võib valel kasutamisel vähendada juurdepääsetavust. See juhtub siis, kui suures osas staatiline sisusait rakendatakse ilma CSS-i kriitilise ekstraheerimiseta, nii et HTML-i ei saa enne JavaScripti kimbu laadimist ja hindamist maalida. See võib juhtuda ka siis, kui hiiglaslik CSS-fail renderdatakse dokumendi päises oleva blokeeriva lingi sildi abil, mis on traditsioonilise manustamise korral kõige populaarsem probleem ja pole CSS-in-JS-i spetsiifiline.

Arendajad peavad vastutama juurdepääsetavuse eest. Endiselt on tugev ekslik idee, et ebastabiilne Interneti-ühendus on majanduslikult nõrkade riikide probleem. Me kipume unustama, et maa-alusesse raudteesüsteemi või suuresse hoonesse sisenedes on ühenduvusega probleeme iga päev. Stabiilne kaablivaba mobiiliühendus on müüt. Stabiilse WiFi-ühenduse olemasolu pole isegi lihtne, näiteks 2,4 GHz WI-FI-võrk võib mikrolaineahjust häireid saada!

Serveripoolse renderdamisega kriitilise CSS-i maksumus

CSS-in-JS jaoks kriitilise CSS-i ekstraheerimise saamiseks vajame SSR-i. SSR on serveris oleva rakenduse oleku jaoks lõpliku HTML-i genereerimise protsess. Tegelikult võib see olla üsna keeruline ja kallis protsess. Iga HTTP-päringu jaoks on vaja serveris teatud arvu CPU-tsükleid.

CSS-in-JS kasutab tavaliselt ära fakti, et see on HTML-i renderdamise torujuhtmesse haaratud. * Ta teab, mis HTML muudeti ja millist CSS-i ta vajab, et ta suudaks toota selle absoluutset minimaalset kogust. Kriitiline CSS lisab serveri HTML-i renderdusele täiendavaid üldkulusid, kuna see CSS tuleb ka kompileerida lõplikuks CSS-i stringiks. Mõne stsenaariumi korral on serveris vahemälu salvestamine siiski raske või isegi võimatu.

Renderdamine must kast

Peate olema teadlik sellest, kuidas teie kasutatav CSS-in-JS-i teeki teie CSS-i renderdab. Näiteks pole inimesed sageli teadlikud sellest, kuidas stiilikomponendid ja emotsioonid dünaamilisi stiile rakendavad. Dünaamilised stiilid on süntaks, mis võimaldab teie stiilideklaratsioonis kasutada JavaScripti funktsioone. Need funktsioonid aktsepteerivad rekvisiite ja tagastavad CSS-i ploki.

Allika järjekorra spetsiifilisuse järjepidevuse tagamiseks loovad mõlemad ülalnimetatud teegid uue CSS-i reegli, kui see sisaldab dünaamilist deklaratsiooni ja komponenti värskendatakse uute rekvisiitidega. Selle demonstreerimiseks lõin selle liivakasti. JSS-is otsustasime kasutada teistsugust kompromissi, mis võimaldab dünaamilisi omadusi värskendada ilma uusi CSS-i reegleid genereerimata. *

Järsk õppimiskõver

Inimeste jaoks, kes tunnevad CSS-i, kuid pole JavaScripti algsed, võib CSS-in-JS-i kiirendamiseks vajaminev esialgne töö olla üsna suur.

CSS-in-JS-i kirjutamiseks ei pea te olema professionaalne JavaScripti arendaja, kuni keerulise loogika kaasamiseni. Me ei saa stiilimise keerukust üldistada, kuna see sõltub tõesti kasutusviisist. Juhtudel, kui CSS-in-JS muutub keerukaks, on vanilla CSS-iga rakendamine tõenäoliselt veelgi keerukam.

CSS-in-JS-i stiilide põhiliseks kujundamiseks peab olema teada, kuidas muutujaid deklareerida, malli stringe kasutada ja JavaScripti väärtusi interpoleerida. Objektimärgistuse kasutamisel tuleb teada, kuidas töötada JavaScripti objektide ja teegispetsiifilise objektipõhise süntaksiga. Kui tegemist on dünaamilise stiiliga, tuleb teada, kuidas JavaScripti funktsioone ja tingimusi kasutada.

Üldiselt on olemas õppimiskõver, me ei saa seda eitada. See õppimiskõver pole tavaliselt siiski palju suurem kui Sassi õppimine. Tegelikult lõin selle munapea kursuse selle demonstreerimiseks.

Koostalitlusvõime puudub

Enamik CSS-in-JS-i libisid pole koostalitlusvõimelised. See tähendab, et ühe teegi abil kirjutatud stiile ei saa teisendada teise raamatukogu abil. Praktiliselt tähendab see, et te ei saa kogu rakendust hõlpsalt ühelt teisele vahetada. See tähendab ka seda, et te ei saa hõlpsalt oma kasutajaliidest NPM-is jagada, ilma et viiksite valitud CSS-in-JS-i teeki tarbijapaketti, kui teil pole CSS-i jaoks staatilist ehitust.

Oleme hakanud töötama ISTF-vormingu kallal, mis peaks selle probleemi lahendama, kuid kahjuks pole meil veel olnud aega selle tootmiseks valmis olekusse jõudmiseks. *

Arvan, et korduvkasutatavate raamistiku agnostiliste kasutajaliidese komponentide jagamine üldkasutatavas valdkonnas on endiselt üldiselt raskesti lahendatav probleem.

Turvariskid

Turvalisuse lekkeid on võimalik sisse viia CSS-in-JS-iga. Nagu kõigi kliendirakenduste puhul, peate ka enne renderdamist alati kasutaja sisestusest hoiduma.

See artikkel annab teile rohkem teavet ja mõningaid hirmutavaid näiteid.

Loetamatud klassinimed

Mõne inimese arvates on endiselt oluline, et me hoitaks veebis tähendusrikkalt loetavaid klassinimesid. Praegu pakuvad paljud CSS-in-JS-i teegid arendusrežiimis deklaratsiooninime või komponendi nime põhjal tähendusrikkaid klassinimesid. Mõni neist lubab teil isegi klassinime generaatori funktsiooni kohandada.

Tootmisrežiimis loob enamik neist lühemaid nimesid väiksema kasuliku koormuse jaoks. See on kompromiss, mille raamatukogu kasutaja peab vajaduse korral teeki tegema ja kohandama.

Järeldus

Kompromissid on olemas ja ma ilmselt ei maininud neid kõiki. Kuid enamik neist ei kehti üldiselt kõigi CSS-in-JS-i puhul. Need sõltuvad sellest, millist teeki te kasutate ja kuidas seda kasutate.

* Selle lause selgitamiseks kulub spetsiaalne artikkel. Andke mulle Twitteris (@ oleg008) teada, kumba soovite rohkem lugeda.