CSS-in-JS: n kompromissit

Kuva: Artem Bali

Äskettäin kirjoitin korkeamman tason yleiskatsauksen CSS-in-JS: stä, puhuen lähinnä ongelmista, joita tämä lähestymistapa yrittää ratkaista. Kirjaston kirjoittajat sijoittavat harvoin aikaa kuvaamaan ratkaisunsa kompromisseja. Joskus se johtuu siitä, että he ovat liian puolueellisia, ja joskus he eivät vain tiedä kuinka käyttäjät käyttävät työkalua. Joten tämä on yritys kuvata kompromisseja, joita olen toistaiseksi nähnyt. Mielestäni on tärkeää mainita, että olen JSS: n laatija, joten minua pitäisi pitää puolueellisena.

Sosiaaliset vaikutukset

Eräs kerros ihmisiä työskentelee verkkoympäristössä eivätkä tiedä JavaScriptiä. Ne ihmiset saavat palkkaa HTML: n ja CSS: n kirjoittamisesta. CSS-in-JS on vaikuttanut valtavasti kehittäjien työnkulkuun. Todella muuttuvaa muutosta ei voida koskaan tehdä ilman, että jotkut ihmiset jäävät taakse. En tiedä, onko CSS-in-JS: n oltava ainoa tapa, mutta joukkohyväksyntä on selvä merkki CSS: n käytön ongelmista nykyaikaisissa sovelluksissa.

Suuri osa ongelmasta on kyvyttömyys kommunikoida tarkasti käyttötapauksissa, joissa CSS-in-JS paistaa ja kuinka käyttää sitä oikein tehtävään. Monet CSS-in-JS -harrastajat ovat onnistuneet edistämään tekniikkaa, mutta monet kritiikit eivät puhuneet kompromisseista rakentavasti, ottamatta halpoja keinuja työkaluilta. Seurauksena oli, että jätimme monet kompromissit piilotettuiksi eivätkä pyrkineet tarjoamaan selitystä ja kiertotapoja.

CSS-in-JS on yritys tehdä monimutkaisista käyttötapauksista helpompaa käsitellä, joten älä työnnä sitä sinne, missä sitä ei tarvita!

Suoritusaikakustannukset

Kun CSS luodaan JavaScript-palvelusta suorituksen aikana, selaimessa on luontainen yläpinta. Suorituksen kestoaika vaihtelee kirjastoittain. Tämä on hyvä yleinen vertailuarvo, mutta muista tehdä omat testisi. Suuret erot suorituksen aikana ilmestyvät riippuen siitä, tarvitaanko täysi CSS-jäsentäminen mallijonoista, optimointien määrä, dynaamisten tyylien toteutustiedot, hajautusalgoritmi ja puiteintegraatioiden kustannukset. *

Mahdollisen suoritusajan yläpuolella on harkittava 4 erilaista niputtamisstrategiaa, koska jotkut CSS-in-JS -kirjastokirjat tukevat useita strategioita ja käyttäjän on itse sovellettava niitä. *

Strategia 1: Vain ajonaikainen sukupolvi

Suorituksenainen CSS-sukupolvi on tekniikka, joka tuottaa CSS-merkkijonon JavaScriptin avulla ja ruiskuttaa sitten merkkijonon tyylitunnisteen avulla asiakirjaan. Tämä tekniikka tuottaa tyylisivun, EI sisäkkäisiä tyylejä.

Suorituksen aikaisen sukupolven kompromissi on kyvyttömyys tarjota tyylistä sisältöä varhaisessa vaiheessa, kun asiakirja alkaa latautua. Tämä lähestymistapa sopii yleensä sovelluksille, joilla ei ole sisältöä, josta voi olla hyötyä heti. Tällaiset sovellukset vaativat yleensä käyttäjän vuorovaikutusta, ennen kuin niistä voi tulla todella hyödyllisiä käyttäjälle. Usein tällaiset sovellukset toimivat niin dynaamisen sisällön kanssa, että se vanhenee heti, kun lataat sen, joten sinun on luotava päivitysputki varhain, esimerkiksi Twitter. Lisäksi, kun käyttäjä on kirjautuneena sisään, SEO: ta ei tarvitse toimittaa HTML-muodossa.

Jos vuorovaikutus vaatii JavaScriptiä, kimppu on ladattava ennen kuin sovellus on valmis. Voit esimerkiksi näyttää oletuskanavan sisällön lataamalla Slack-tiedostoa asiakirjaan, mutta on todennäköistä, että käyttäjä haluaa vaihtaa kanavan heti sen jälkeen. Joten jos latasit alkuperäisen sisällön vain heittää ne heti pois.

Tällaisten sovellusten havaittua suorituskykyä voidaan parantaa paikkamerkkeillä ja muilla temppuilla, jotta sovellus tuntuu hetkellisemmältä kuin se todellisuudessa on. Tällaiset sovellukset ovat yleensä joka tapauksessa erittäin painavia, joten niistä ei ole hyötyä yhtä nopeasti kuin artikkeleita.

Strategia 2: Suorituksenaikainen sukupolvi kriittisen CSS: n avulla

Kriittinen CSS on CSS: n vähimmäismäärä, jota tarvitaan sivun muotoiluun alkuperäisessä tilassa. Se tehdään käyttämällä tyylitunnistetta asiakirjan päässä. Tätä tekniikkaa käytetään laajalti CSS-in-JS: n kanssa ja ilman. Molemmissa tapauksissa sinun on todennäköisesti kaksinkertainen CSS-sääntöjen lataaminen, kerran osana kriittistä CSS: ää ja kerran osana JavaScriptiä tai CSS-pakettia. Kriittisen CSS: n koko voi olla melko suuri sisällön määrästä riippuen. Yleensä asiakirjaa ei tallenneta välimuistiin.

Ilman kriittistä CSS: ää, staattisen sisällön sisältävä yhden sivun sovellus, jossa on ajonaikainen CSS-in-JS, on näytettävä paikkamerkkejä sisällön sijasta. Tämä on huonoa, koska siitä olisi voinut olla hyötyä käyttäjälle paljon aikaisemmin, mikä parantaa huonojen laitteiden ja matalan kaistanleveyden yhteyksien saavutettavuutta.

Kriittisellä CSS: llä ajonaikainen CSS-generointi voidaan tehdä myöhemmässä vaiheessa estämättä käyttöliittymää alkuperäisessä vaiheessa. Varo kuitenkin, että huippuluokan mobiililaitteissa, jotka ovat vähintään 5 vuotta vanhoja, CSS: n luominen JavaScriptillä voi vaikuttaa kielteisesti suorituskykyyn. Se riippuu voimakkaasti syntyvän CSS-määrän ja käytetyn kirjaston määrästä, joten sitä ei voida yleistää.

Tämän strategian kompromissi on kriittisen CSS: n erottamisen kustannukset ja suorituksen CSS: n tuottamisen kustannukset.

Strategia 3: Vain rakennusajan poiminta

Tämä strategia on oletusstrategia verkossa ilman CSS-in-JS: tä. Joidenkin CSS-in-JS -kirjastojen avulla voit purkaa staattisen CSS: n rakennusajankohtana. * Tässä tapauksessa suoritusaikaan liittyviä otsikoita ei ole, CSS-sivusto esitetään sivulla linkkitunnisteen avulla. CSS-sukupolven kustannukset maksetaan kerran etukäteen.

Täällä on 2 suurta vaihtoa:

  1. Et voi käyttää joitain dynaamista sovellusliittymää CSS-in-JS-tarjouksista suorituksen aikana, koska sinulla ei ole tilaa tilille. Usein et edelleenkään voi käyttää CSS-mukautettuja ominaisuuksia, koska niitä ei tueta kaikissa selaimissa, eikä niitä voida täyttää luonteeltaan moninkertaisesti rakennusaikana. Tällöin joudut tekemään kiertotapoja dynaamisen käyttöönoton ja tilapohjaisen muotoilun aikaansaamiseksi. *
  2. Ilman kriittistä CSS: ää ja tyhjellä välimuistilla voit estää ensimmäisen maalin, kunnes CSS-paketti latautuu. Asiakirjan päässä oleva linkkielementti estää HTML: n renderoinnin.
  3. Ei-deterministinen spesifisyys sivupohjaisen paketin jakamisen kanssa yhden sivun sovelluksissa. *

Strategia 4: Rakennusajan poiminta kriittisellä CSS: llä

Tämä strategia ei ole myöskään ainutlaatuinen CSS-in-JS: lle. Täydellinen staattinen uutto kriittisellä CSS: llä tarjoaa parhaan suorituskyvyn työskennellessäsi staattisemman sovelluksen kanssa. Tällä lähestymistavalla on edelleen yllä mainitut staattisen CSS: n vaihtoehdot, paitsi että estävän linkin tunniste voidaan siirtää dokumentin alaosaan.

CSS-mallinnusstrategioita on 4. Vain 2 niistä on tarkoitettu CSS-in-JS: lle eikä mikään niistä koske kaikkia kirjastoja.

saavutettavuus

CSS-in-JS voi vähentää saavutettavuutta väärin käytettynä. Tämä tapahtuu, kun suurelta osin staattinen sisältösivusto toteutetaan ilman kriittistä CSS-erotusta, joten HTML: ää ei voida maalata ennen kuin JavaScript-paketti ladataan ja arvioidaan. Näin voi tapahtua myös silloin, kun valtava CSS-tiedosto hahmonnetaan käyttämällä estävää linkkitunnistetta asiakirjan päässä, mikä on suosituin nykyinen ongelma perinteisessä upotuksessa eikä ole erityinen CSS-in-JS: lle.

Kehittäjien on otettava vastuu saavutettavuudesta. Vielä on vahvasti harhaanjohtava ajatus siitä, että epävakaa Internet-yhteys on taloudellisesti heikkojen maiden ongelma. Meillä on taipumus unohtaa, että meillä on yhteysongelmia joka päivä, kun astumme maanalaiseen rautatiejärjestelmään tai suureen rakennukseen. Vakaa kaapelivapaa matkaviestinyhteys on myytti. Vakaata WiFi-yhteyttä ei ole edes helppoa, esimerkiksi 2,4 GHz: n WI-FI-verkko voi saada häiriöitä mikroaaltouunista!

Kriittisen CSS: n kustannukset palvelinpuolen renderoinnin kanssa

Tarvitsemme SSR: n saadaksesi kriittisen CSS-uutteen CSS-in-JS: lle. SSR on prosessi, jolla luodaan lopullinen HTML palvelimelle annetulle sovelluksen tietylle tilalle. Itse asiassa se voi olla melko monimutkainen ja kallis prosessi. Se vaatii tietyn määrän CPU-jaksoja palvelimella jokaiselle HTTP-pyynnölle.

CSS-in-JS hyödyntää yleensä sitä tosiasiaa, että se on koukussa HTML-hahmonnusputkeen. * Se tietää, mitä HTML tehtiin ja mitä CSS: ää tarvitaan, jotta se pystyy tuottamaan absoluuttisen pienen määrän sitä. Kriittinen CSS lisää ylimääräisiä yleiskustannuksia palvelimen HTML-renderöintiin, koska CSS on myös käännettävä lopulliseksi CSS-merkkijonoksi. Joissakin tilanteissa palvelimen välimuistin tallentaminen on vaikeaa tai jopa mahdotonta.

Renderöinti musta laatikko

Sinun on oltava tietoinen siitä, kuinka käyttämäsi CSS-in-JS-kirjasto tuottaa CSS: n. Esimerkiksi ihmiset eivät usein ole tietoisia siitä, kuinka tyylit ja komponentit toteuttavat dynaamiset tyylit. Dynaaminen tyylit on syntaksi, joka sallii Java-toimintojen käytön tyylien ilmoituksen sisällä. Nämä toiminnot hyväksyvät rekvisiitta ja palauttavat CSS-lohkon.

Lähdejärjestyksen spesifisyyden pitämiseksi molemmat yllä mainitut kirjastot luovat uuden CSS-säännön, jos se sisältää dynaamisen ilmoituksen ja komponenttipäivitykset uusilla rekvisiiteilla. Luodakseni tämän hiekkalaatikon osoittaakseni mitä tarkoitan. JSS: ssä päätimme käyttää erilaista vaihtoa, jonka avulla voimme päivittää dynaamiset ominaisuudet tuottamatta uusia CSS-sääntöjä. *

Jyrkkä oppimiskäyrä

CSS-perehtyneille, mutta JavaScriptille uutta käyttäville ihmisille CSS-in-JS -sovelluksen nopeuttamiseen liittyvän työn alkuperäinen määrä saattaa olla melko suuri.

Sinun ei tarvitse olla ammattimainen JavaScriptin kehittäjä kirjoittaaksesi CSS-in-JS: n, kunnes siihen pisteeseen, missä monimutkainen logiikka on mukana. Tyylien monimutkaisuutta ei voida yleistää, koska se todella riippuu käyttötapauksesta. Tapauksissa, joissa CSS-in-JS tulee monimutkainen, on todennäköistä, että vanilja CSS: n kanssa toteutus olisi vielä monimutkaisempi.

CSS-in-JS -muotoilussa on osata ilmoittaa muuttujat, käyttää mallijonojonoja ja interpoloida JavaScript-arvoja. Jos käytetään objektimerkintää, täytyy tietää, kuinka työskennellä JavaScript-objektien ja kirjastokohtaisen objektipohjaisen syntaksin kanssa. Jos kyseessä on dynaaminen muotoilu, täytyy tietää, kuinka JavaScriptin toimintoja ja ehtoja käytetään.

Kaiken kaikkiaan oppimiskäyrä on, emme voi kieltää sitä. Tämä oppimiskäyrä ei kuitenkaan yleensä ole paljon suurempi kuin Sassin oppiminen. Itse asiassa olen luonut tämän munapääkurssin osoittamaan sitä.

Ei yhteentoimivuutta

Suurin osa CSS-in-JS -levyistä ei ole yhteentoimivia. Tämä tarkoittaa, että yhdellä kirjastolla kirjoitettuja tyylejä ei voida tehdä toisella kirjastolla. Käytännössä se tarkoittaa, että et voi vaihtaa koko sovellusta helposti toteutuksesta toiseen. Se tarkoittaa myös, että et voi helposti jakaa käyttöliittymääsi NPM: ssä tuomalla haluamasi CSS-in-JS -kirjasto kuluttajan pakettiin, ellei sinulla ole rakennusajan staattista uutetta CSS: lle.

Olemme alkaneet työskennellä ISTF-muodossa, jonka on tarkoitus korjata tämä ongelma, mutta valitettavasti meillä ei ole vielä ollut aikaa saada se tuotantoon valmis tilaan. *

Uskon, että uudelleenkäytettävien kehysagnostisten käyttöliittymäkomponenttien jakaminen julkisella alueella on edelleen vaikea ratkaista ongelma.

Turvallisuusriskit

CSS-in-JS: llä on mahdollista ottaa käyttöön tietoturvavuotoja. Kuten kaikissa asiakaspuolen sovelluksissa, sinun on aina vältettävä käyttäjän syöttämiä tietoja ennen niiden tekemistä.

Tämä artikkeli antaa sinulle enemmän käsityksiä ja joitain kauhistuttavia esimerkkejä.

Lukemattomat luokanimet

Jotkut ihmiset pitävät edelleen tärkeänä, että pidämme mielekkäästi luettavissa olevia luokan nimiä verkossa. Tällä hetkellä monet CSS-in-JS -kirjastot tarjoavat merkityksellisiä luokan nimiä deklaraation nimen tai komponentin nimen perusteella kehitystilassa. Jotkut niistä jopa antavat sinun mukauttaa luokan nimen generaattoritoimintoa.

Tuotantotilassa kuitenkin suurin osa heistä tuottaa lyhyempiä nimiä pienemmälle hyötykuormalle. Tämä on kompromissi, jonka kirjaston käyttäjän on tehtävä ja mukautettava kirjasto tarvittaessa.

johtopäätös

Kompromisseja on olemassa, enkä luultavasti edes maininnut niitä kaikkia. Mutta suurin osa niistä ei yleisesti koske kaikkia CSS-in-JS -järjestelmiä. Ne riippuvat siitä, mitä kirjastoa käytät ja kuinka käytät sitä.

* Tämän virkkeen selittämiseen tarvitaan oma artikkeli. Kerro minulle Twitterissä (@ oleg008) mistä haluaisit lukea lisää.