Generic First CSS: New Thinking On Mobile First
Publicat: 2022-03-10Cred că este sigur să spun că Designul web responsiv al lui Ethan Marcotte a fost o revelație binevenită pentru dezvoltatorii web din întreaga lume. A declanșat un val cu totul nou de gândire la design și noi tehnici minunate de front-end. Domnia site-urilor de multe ori disprețuite m dot s-a încheiat și ea. În aceeași epocă și aproape la fel de influentă a fost metodologia Mobile First a lui Luke Wroblewski - o îmbunătățire solidă care s-a construit pe bazele impresionante ale lui Marcotte.
Aceste tehnici sunt la baza vieții majorității dezvoltatorilor web și ne-au servit bine, dar, din păcate, vremurile se schimbă, iar dezvoltatorii repetă în mod constant. Pe măsură ce creștem eficiența metodelor noastre și cerințele proiectului devin mai complexe, apar noi frustrări.
Călătoria către generic mai întâi
Nu pot identifica exact ce m-a făcut să schimb modul în care îmi scriu CSS-ul, deoarece a fost într-adevăr o progresie naturală pentru mine, care s-a întâmplat aproape subconștient. Privind în urmă, cred că a fost mai degrabă un produs secundar al mediului de dezvoltare în care lucram. Echipa cu care am lucrat avea un flux de lucru SCSS drăguț, cu un mic mixin frumos pentru a adăuga cu ușurință puncte de întrerupere în declarațiile noastre CSS. Probabil că folosești o tehnică similară.
Acest minunat mic mixin SCSS a făcut dintr-o dată ușor să scrieți interogări media super granulare. Luați un bloc de biografie ipotetică care arată cam așa:
.bio { display: block; width: 100%; background-color: #ece9e9; padding: 20px; margin: 20px 0; @include media('>=small') { max-width: 400px; background-color: white; margin: 20px auto; } @include media('>=medium') { max-width: 600px; padding: 30px; margin: 30px auto; } @include media('>=large') { max-width: 800px; padding: 40px; margin: 40px auto; } @include media('>=huge') { max-width: 1000px; padding: 50px; margin: 50px auto; } }
Fig.1. În primul rând, mobilul tipic cu interogări media în cascadă
Funcționează bine — am scris multe CSS ca acesta în trecut. Cu toate acestea, într-o zi mi-am dat seama că suprascrierea declarațiilor CSS pe măsură ce lățimea dispozitivului creștea pur și simplu nu avea sens. De ce să declari o proprietate CSS pentru ca aceasta să fie doar suprascrisă în următoarea declarație?
Acesta este ceea ce m-a determinat să încep să scriu interogări media compartimentate , spre deosebire de abordarea mai comună a interogărilor media care cascadă în sus (sau în jos), ca exemplul din Fig.1.
În loc să scriu interogări media care cresc în cascadă odată cu creșterea dimensiunii ecranului, am început să creez interogări media vizate care să încapsuleze stiluri la lățimea dorită a ecranului. Mixin-ul de interogări media și-ar veni cu adevărat în sine aici. Acum interogările mele media SCSS încep să arate astfel:
.bio { display: block; width: 100%; padding: 20px; margin: 20px 0; @include media('>=small', ' < medium') { max-width: 400px; margin: 20px auto; } @include media('>=medium', ' < large') { max-width: 600px; padding: 30px; margin: 30px auto; } @include media('>=large', ' < huge') { max-width: 800px; padding: 40px; margin: 40px auto; } @include media('>=huge') { max-width: 1000px; padding: 50px; margin: 50px auto; } }
Fig.2. Un exemplu de interogări media compartimentate
Această nouă abordare mi s-a părut mai intuitivă, a redus nevoia de a reseta stilurile de la punctul de întrerupere anterior și a făcut CSS-ul mai ușor de citit. Mai important, a făcut ca interogările media să se auto-documenteze într-un mod mai semnificativ.
Totuși, încă nu am fost 100% mulțumit de cele de mai sus, se părea că mai era o problemă majoră de depășit.
Problema cu Mobile First
Problema cu mobil primul este că, prin definiție, cel mai probabil va trebui să înlocuiți stilurile mobile-first în interogările media ulterioare. Se simte ca un pic de anti-model.
Deci, pentru mine, răspunsul a fost evident: să luăm ideea de compartimentare a interogărilor media până la concluzia sa logică – vom compartimenta, de asemenea, stilurile specifice mobile în propriile interogări media. Știu, știu, asta contravine convenției comune pe care am învățat-o de-a lungul anilor. „Mobile First” este atât de omniprezent încât este, de obicei, una dintre întrebările de „aptitudini” pe care le pune un manager de angajare. Deci, cu siguranță orice alternativă trebuie să fie greșită, nu-i așa? Aceasta este de obicei partea în care oamenii scutură din cap la mine în timp ce rostesc mai întâi mobil , iar și iar.
Bine, așa că vom străpunge dogma primul mobil și vom compartimenta toate stilurile noastre în interogările media relevante. Ceea ce ne rămâne acum sunt stiluri generice pure declarate pe un selector CSS, cu toate celelalte stiluri specifice dispozitivului încapsulate în interogări media care se aplică numai dimensiunilor relevante ale ecranului. Acum avem Generic First CSS :
.bio { display: block; width: 100%; @include media('>=0', ' < small') { padding: 20px; margin: 20px 0; } @include media('>=small', ' < medium') { max-width: 400px; margin: 20px auto; } @include media('>=medium', ' < large') { max-width: 600px; padding: 30px; margin: 30px auto; } @include media('>=large', ' < huge') { max-width: 800px; padding: 40px; margin: 40px auto; } @include media('>=huge') { max-width: 1000px; padding: 50px; margin: 50px auto; } }
Fig.3. Un exemplu de Generic First CSS
Da, există puțin mai multe interogări media, totuși, văd acest lucru ca un beneficiu, orice dezvoltator poate acum să se uite la acest CSS și să vadă exact ce stiluri sunt aplicate la fiecare dimensiune a ecranului, fără a avea suprasolicitarea cognitivă de a alege media- specificitatea interogării.
Acest lucru poate fi grozav pentru persoanele care nu sunt familiarizate cu baza de cod sau chiar cu viitorul dvs.!
Când să nu se compartimenteze
Există încă momente în care compartimentarea interogărilor media este o povară și, în unele cazuri, o interogare media veche >= este în regulă. Amintiți-vă, tot ceea ce încercăm să facem este să evităm suprascrierile de proprietate.
Dev Tool Bliss
O consecință majoră neintenționată a scrierii compartimentate Generic First CSS este experiența pe care o veți obține din panoul de stil al instrumentelor pentru dezvoltatori. Fără cascada de interogare media, veți avea acum o imagine de ansamblu mai clară asupra stilurilor aplicate — Nu veți avea un panou de stil plin de declarații eliminate din regulile de interogare media suprascrise — Zgomotul a dispărut! Acesta – pentru mine – este unul dintre cele mai mari beneficii ale tehnicii Generic First CSS. Aduce un pic de sens în plus experienței de depanare CSS, iar acest lucru își merită greutatea în aur. Mulțumește-mi mai târziu.
Implicații de performanță
Deci, toate aceste beneficii Generic First CSS încep să sune destul de bine, dar cred că există o ultimă întrebare cheie care cred că trebuie abordată. Este vorba despre optimizarea performanței. Acum nu știu încă sigur, dar am bănuiala că interogările media complet compartimentate pot avea un ușor avantaj de performanță.
Browserele efectuează o sarcină de randare numită calcul al stilului calculat . Este modul browserului de a calcula ce stiluri trebuie aplicate unui element la un moment dat. Această sarcină este întotdeauna efectuată la încărcarea inițială a paginii, dar poate fi efectuată și dacă conținutul paginii se modifică sau dacă au loc alte acțiuni ale browserului. Orice spor pe care îl puteți oferi vitezei procesului va fi grozav pentru încărcarea inițială a paginii și ar putea avea un efect compus asupra ciclului de viață al paginilor site-ului dvs.
Deci, revenind la primul CSS generic: Există probleme de performanță legate de faptul că browserul trebuie să elaboreze specificul CSS al unei multitudini de interogări media în cascadă?
Pentru a răspunde la asta, am conceput un caz de testare care poate fi folosit pentru a măsura orice avantaje sau chiar dezavantaje ale vitezei.
Cazul de testare
Cazul de testare este format dintr-o pagină HTML de bază care scoate un bloc „bio” de 5000 de ori, marcajul este același pentru fiecare bloc, dar clasele sunt ușor diferite (diferențiator numeric), CSS-ul pentru acest bloc este, de asemenea, afișat de 5000 de ori , numele claselor fiind singurul lucru care diferă. CSS-ul ieșit este transmis printr-un instrument numit CSS MQPacker, acest lucru ajută la reducerea dramatică a dimensiunii fișierului CSS care utilizează o mulțime de interogări media inline, combinând toate instanțele separate ale unei interogări media specifice într-un singur instrument - Este un instrument grozav care probabil va beneficia cele mai moderne baze de cod CSS — l-am folosit ca instrument cli autonom printr-o sarcină npm în pachetul de proiecte de testare.json, îl puteți folosi și ca plugin postcss, ceea ce este frumos și convenabil!
Primul caz de testare este un exemplu de interogări media în cascadă pe mobil, al doilea caz de testare este o primă variantă generică compartimentată a CSS. CSS-ul pentru aceste cazuri este puțin verbos și probabil ar putea fi scris în termeni mult mai conciși, dar într-adevăr servește doar ca un exemplu aproximativ pentru a testa argumentul.
Testul a fost rulat de 20 de ori pentru fiecare variantă CSS din desktop Google Chrome v70, nu un set masiv de date, dar suficient pentru a-mi oferi o idee aproximativă despre un câștig/pierdere de performanță.
Valorile de testare pe care am ales să le folosesc sunt:
- Timpul general de încărcare a paginii
O valoare de bază pentru a verifica timpul de încărcare a paginii folosind marcatorii Performance API la începutul <head> și chiar la sfârșitul <body> - Stilul de recalculare
Timp din panoul de performanță al instrumentelor de dezvoltare. - Redarea generală a paginii
Timp din panoul de performanță al instrumentelor de dezvoltare.
Tabel cu rezultate (toate ori în milisecunde)
În primul rând mobil | În primul rând generic | ||||||
---|---|---|---|---|---|---|---|
Timp de încărcare | Calculați stiluri | Timp total de randare | Timp de încărcare | Calculați stiluri | Timp total de randare | ||
1135 | 565,7 | 1953 | 1196 | 536,9 | 2012 | ||
1176 | 563,5 | 1936 | 1116 | 506,9 | 1929 | ||
1118 | 563,1 | 1863 | 1148 | 514,4 | 1853 | ||
1174 | 568,3 | 1929 | 1124 | 507.1 | 1868 | ||
1204 | 577,2 | 1924 | 1115 | 518,4 | 1854 | ||
1155 | 554,7 | 1991 | 1177 | 540,8 | 1905 | ||
1112 | 554,5 | 1912 | 1111 | 504,3 | 1886 | ||
1110 | 557,9 | 1854 | 1104 | 505,3 | 1954 | ||
1106 | 544,5 | 1895 | 1148 | 525,4 | 1881 | ||
1162 | 559,8 | 1920 | 1095 | 508,9 | 1941 | ||
1146 | 545,9 | 1897 | 1115 | 504,4 | 1968 | ||
1168 | 566,3 | 1882 | 1112 | 519,8 | 1861 | ||
1105 | 542,7 | 1978 | 1121 | 515,7 | 1905 | ||
1123 | 566,6 | 1970 | 1090 | 510,7 | 1820 | ||
1106 | 514,5 | 1956 | 1127 | 515,2 | 1986 | ||
1135 | 575,7 | 1869 | 1130 | 504,2 | 1882 | ||
1164 | 545,6 | 2450 | 1169 | 525,6 | 1934 | ||
1144 | 565 | 1894 | 1092 | 516 | 1822 | ||
1115 | 554,5 | 1955 | 1091 | 508,9 | 1986 | ||
1133 | 554,8 | 2572 | 1001 | 504,5 | 1812 | ||
AVG | 1139,55 | 557,04 | 1980 | 1119.1 | 514,67 | 1903.15 |
Fig.6. 20 de teste care măsoară valorile de încărcare/randare a cheilor pentru primul CSS mobil vs primul CSS generic.
Din setul meu de date, desigur, mic, se pare că suspiciunea mea inițială ar putea fi corectă. În medie, văd că sarcina de recalculare a stilului durează cu 42 ms mai puțin, ceea ce reprezintă o creștere a vitezei cu 7,6% și, prin urmare, timpul general de randare scade și el. Diferența nu este uimitoare, dar este o îmbunătățire. Nu cred că setul de date este suficient de mare pentru a fi 100% concludent, iar cazul de testare este puțin nerealist, dar sunt foarte bucuros că nu văd o degradare a performanței.
Aș fi foarte interesat să văd prima metodologie generică aplicată la o bază de cod existentă în lumea reală, care a fost scrisă în primul mod mobil - metricile înainte de după ar fi mult mai realiste pentru practica de zi cu zi.
Și dacă cineva are sugestii despre cum să automatizeze acest test printr-un set mai larg de iterații, vă rog să-mi spuneți în comentarii! Mi-aș imagina că trebuie să existe un instrument care poate face asta.
Concluzie
Pentru a recapitula beneficiile acestei noi metodologii de dezvoltare...
- CSS care face exact așa cum este intenționat, fără nicio a doua ghicire;
- Interogări media cu auto-documentare;
- O experiență mai bună cu instrumentele de dezvoltare;
- Pagini care se redau mai rapid.
Aș dori să cred că nu sunt singura persoană care susține scrierea CSS în acest stil. Dacă ai adoptat deja prima mentalitate generică, ura! Dar dacă nu, cred că îți vor plăcea foarte mult beneficiile pe care le aduce. Personal, am beneficiat foarte mult de experiența simplă a instrumentelor de dezvoltare, care în sine va fi un foarte pozitiv pentru mulți dezvoltatori. natura de auto-documentare a acestui mod de a vă scrie interogările media va avea, de asemenea, beneficii pentru dvs. și pentru echipa mai largă (dacă aveți una). Și, în sfârșit, aceste beneficii nu vă vor costa nimic în termeni de performanță și, de fapt, s-a dovedit că au câștiguri marginale de viteză!
Cuvântul final
Ca toate metodologiile de dezvoltare, s-ar putea să nu fie pentru toată lumea, dar am căzut în Generic First CSS destul de natural, acum îl văd ca pe un mod valoros de lucru care îmi oferă toate beneficiile mobile first cu câteva completări pozitive noi care fac sarcina grea de dezvoltare front-end care poate fi mai ușoară.
Resurse
Test Case Repo
Dacă doriți să porniți cazul de testare și să încercați singur, îl puteți găsi pe GitHub, mi-ar plăcea să văd câteva rapoarte de la alții.
Instrumente
- CSS MQPacker
- Includeți media