Primo CSS generico: un nuovo modo di pensare prima sui dispositivi mobili
Pubblicato: 2022-03-10Penso che si possa affermare con sicurezza che il Responsive Web Design di Ethan Marcotte è stata una rivelazione gradita per gli sviluppatori web di tutto il mondo. Ha innescato un'ondata completamente nuova di pensiero progettuale e nuove meravigliose tecniche di front-end. Anche il regno dei siti Web m dot spesso disprezzati era finito. Nella stessa epoca e quasi altrettanto influente fu la metodologia Mobile First di Luke Wroblewski, un solido miglioramento che si basava sulle impressionanti basi di Marcotte.
Queste tecniche sono alla base della vita della maggior parte degli sviluppatori web e ci hanno servito bene, ma purtroppo i tempi cambiano e gli sviluppatori ripetono costantemente. Man mano che aumentiamo l'efficienza dei nostri metodi e i requisiti del progetto diventano più complessi, emergono nuove frustrazioni.
Il viaggio verso il generico First
Non riesco a individuare esattamente cosa mi abbia fatto cambiare il modo in cui scrivo i miei CSS perché è stata davvero una progressione naturale per me avvenuta quasi inconsciamente. Guardando indietro, penso che fosse più un sottoprodotto dell'ambiente di sviluppo in cui stavo lavorando. Il team con cui ho lavorato aveva un bel flusso di lavoro SCSS in corso con un piccolo e ingegnoso mixin per aggiungere facilmente punti di interruzione all'interno delle nostre dichiarazioni CSS. Probabilmente usi una tecnica simile.
Questo meraviglioso piccolo mixin SCSS ha improvvisamente reso facile scrivere query multimediali super granulari. Prendi un ipotetico blocco biografico che assomigli un po' a questo:
.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. Tipico mobile first con media query a cascata
Funziona bene: in passato ho scritto molti CSS come questo. Tuttavia, un giorno mi sono reso conto che sovrascrivere le dichiarazioni CSS all'aumentare della larghezza del dispositivo non aveva senso. Perché dichiarare una proprietà CSS in modo che venga sovrascritta solo nella dichiarazione seguente?
Questo è ciò che mi ha portato a iniziare a scrivere media query compartimentalizzate in opposizione all'approccio più comune delle media query che scendono a cascata verso l'alto (o verso il basso) come nell'esempio in Fig.1.
Invece di scrivere media query che aumentano a cascata con l'aumento delle dimensioni dello schermo, ho iniziato a creare media query mirate che incapsulassero gli stili alle larghezze dello schermo desiderate. Il mixin di query sui media entrerebbe davvero in gioco qui. Ora le mie query multimediali SCSS iniziano ad apparire così:
.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 esempio di media query compartimentate
Questo nuovo approccio mi è sembrato più intuitivo, ha ridotto la necessità di ripristinare gli stili dal punto di interruzione precedente e semplificava la lettura del CSS. Ancora più importante, stava rendendo le query dei media auto-documentanti in un modo più significativo.
Tuttavia, non ero ancora soddisfatto al 100% di quanto sopra, sembrava che ci fosse ancora un grosso problema da superare.
Il problema con i dispositivi mobili prima di tutto
Il problema con il mobile first è che, per definizione, molto probabilmente dovrai sovrascrivere gli stili mobile first nelle media-query successive. Questo sembra un po' un anti-modello.
Quindi, per me, la risposta era ovvia: portiamo l'idea della compartimentazione delle query multimediali alla sua logica conclusione: compartimentizzeremo anche gli stili specifici per dispositivi mobili nelle loro stesse query multimediali. Lo so, lo so, questo va contro la convenzione comune che abbiamo imparato nel corso degli anni. "Mobile First" è così onnipresente che di solito è una delle domande sulle "competenze" che un responsabile delle assunzioni pone. Quindi sicuramente qualsiasi alternativa deve essere sbagliata, no? Questa è di solito la parte in cui le persone scuotono la testa verso di me mentre pronunciano mobile prima e ancora.
Ok, quindi sveleremo il dogma mobile first e compartimentizzeremo tutti i nostri stili nelle query sui media pertinenti. Quello che ci resta ora sono stili generici puri dichiarati su un selettore CSS, con tutti gli altri stili specifici del dispositivo incapsulati in query multimediali che si applicano solo alle dimensioni dello schermo rilevanti. Ora abbiamo 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 esempio di Generic First CSS
Sì, ci sono un po 'più di query sui media, tuttavia, lo vedo come un vantaggio, qualsiasi sviluppatore ora può guardare questo CSS e vedere esattamente quali stili vengono applicati a ogni dimensione dello schermo senza il sovraccarico cognitivo di dover separare i media- specificità della query.
Questo può essere ottimo per le persone che non hanno familiarità con la base di codice o anche per il futuro!
Quando non compartimentalizzare
Ci sono ancora momenti in cui la compartimentazione delle media query è un peso e in alcuni casi una buona vecchia media query >= va bene. Ricorda, tutto ciò che stiamo cercando di fare è evitare la sovrascrittura delle proprietà.
Dev Tool Bliss
Una delle principali conseguenze indesiderate della scrittura di Generic First CSS compartimentati è l'esperienza che otterrai dal pannello di stile degli strumenti di sviluppo. Senza la cascata di media query, ora avrai una panoramica più chiara di quali stili vengono applicati — Non avrai un pannello di stile pieno di dichiarazioni cancellate da regole di media query sovrascritte — Il rumore è sparito! Questo — per me — è uno dei maggiori vantaggi della tecnica Generic First CSS. Porta un po' di sanità mentale in più all'esperienza di debug CSS, e questo vale il suo peso in oro. Ringraziami più tardi.
Implicazioni sulle prestazioni
Quindi tutti questi vantaggi di Generic First CSS stanno iniziando a suonare abbastanza bene, ma penso che ci sia un'ultima domanda chiave che penso debba essere affrontata. È in tema di ottimizzazione delle prestazioni. Ora non lo so ancora per certo, ma ho la sensazione che le query multimediali completamente compartimentate possano avere un leggero vantaggio in termini di prestazioni.
I browser eseguono un'attività di rendering chiamata calcolo dello stile calcolato . È il modo in cui i browser calcolano quali stili devono essere applicati a un elemento in un dato momento. Questa attività viene sempre eseguita al caricamento iniziale della pagina, ma può essere eseguita anche se il contenuto della pagina cambia o se vengono eseguite altre azioni del browser. Qualsiasi spinta che puoi dare alla velocità del processo sarà ottima per il caricamento iniziale della pagina e potrebbe avere un effetto composto sul ciclo di vita delle pagine dei tuoi siti web.
Quindi, tornando al primo CSS generico: ci sono problemi di prestazioni relativi al browser che deve elaborare la specificità CSS di una moltitudine di media query a cascata?
Per rispondere, ho ideato un test case che può essere utilizzato per misurare eventuali vantaggi o svantaggi di velocità.
Il caso di prova
Il test case è costituito da una pagina HTML di base che restituisce un blocco "bio" 5000 volte, il markup è lo stesso per ogni blocco, ma le classi sono leggermente diverse (differenziatore numerico), anche il CSS per questo blocco viene emesso 5000 volte , con i nomi delle classi l'unica cosa a differire. Il CSS emesso viene inviato tramite pipe tramite uno strumento chiamato CSS MQPacker, questo aiuta a ridurre drasticamente le dimensioni del file CSS che utilizza molte query multimediali in linea combinando tutte le istanze separate di una specifica query multimediale in una — È un ottimo strumento che probabilmente ne trarrà vantaggio più moderne basi di codice CSS: l'ho usato come strumento cli autonomo tramite un'attività npm nel pacchetto di progetti di test.json, puoi anche usarlo come plug-in postcss, il che è bello e conveniente!
Il primo test case è un esempio di media query mobile first, il secondo test case è una prima variante generica compartimentata del CSS. Il CSS per questi casi è un po' prolisso e potrebbe probabilmente essere scritto in termini molto più concisi, ma in realtà serve solo come esempio approssimativo per testare l'argomento.
Il test è stato eseguito 20 volte per ogni variazione CSS in Google Chrome v70 desktop, non un enorme insieme di dati, ma abbastanza per darmi un'idea approssimativa di un guadagno/perdita di prestazioni.
Le metriche di test che ho scelto di utilizzare sono:
- Tempo di caricamento complessivo della pagina
Una metrica di base per controllare il tempo di caricamento della pagina utilizzando gli indicatori dell'API delle prestazioni all'inizio di <head> e alla fine di <body> - Lo stile di ricalcolo
Tempo dall'interno del riquadro delle prestazioni degli strumenti di sviluppo. - Il rendering generale della pagina
Tempo dall'interno del riquadro delle prestazioni degli strumenti di sviluppo.
Tabella dei risultati (tutti i tempi in millisecondi)
Mobile First | Primo generico | ||||||
---|---|---|---|---|---|---|---|
Tempo di caricamento | Calcola gli stili | Tempo di rendering totale | Tempo di caricamento | Calcola gli stili | Tempo di rendering totale | ||
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 | 15.1903 |
Fig.6. 20 esecuzioni di test che misurano le metriche di caricamento/rendering delle chiavi del mobile first rispetto al primo CSS generico.
Dal mio set di dati certamente piccolo, sembra che il mio sospetto iniziale possa essere corretto. In media, vedo che l'attività di ricalcolo dello stile impiega 42 ms in meno, il che è un aumento della velocità del 7,6% e quindi diminuisce anche il tempo di rendering complessivo. La differenza non è strabiliante, ma è un miglioramento. Non penso che il set di dati sia abbastanza grande da essere conclusivo al 100% e il test case è un po' irrealistico, ma sono molto contento di non vedere un degrado delle prestazioni.
Sarei molto interessato a vedere la prima metodologia generica applicata a una base di codice esistente nel mondo reale che è stata scritta nel modo mobile-first: le metriche prima dopo sarebbero molto più realistiche per la pratica quotidiana.
E se qualcuno ha suggerimenti su come automatizzare questo test su un insieme più ampio di iterazioni, fatemelo sapere nei commenti! Immagino che ci debba essere uno strumento in grado di farlo.
Conclusione
Per ricapitolare i vantaggi di questa nuova metodologia di sviluppo...
- CSS che fa esattamente come previsto, senza indovinare;
- Query sui media autodocumentanti;
- Una migliore esperienza con gli strumenti di sviluppo;
- Pagine che eseguono il rendering più velocemente.
Mi piacerebbe pensare di non essere l'unica persona che sposa la scrittura di CSS in questo stile. Se hai già adottato la prima mentalità generica, evviva! Ma in caso contrario, penso che apprezzerai davvero i vantaggi che porta. Personalmente ho tratto grandi benefici dall'esperienza ordinata degli strumenti di sviluppo, che di per sé sarà un enorme vantaggio per molti sviluppatori. la natura di auto-documentazione di questo modo di scrivere le tue domande sui media avrà anche vantaggi per te e per il team più ampio (se ne hai uno). E infine, questi vantaggi non ti costeranno nulla in termini di prestazioni, e infatti hanno dimostrato di avere guadagni di velocità marginali!
Parola finale
Come tutte le metodologie di sviluppo, potrebbe non essere adatto a tutti, ma sono caduto in Generic First CSS in modo abbastanza naturale, ora lo vedo come un metodo di lavoro prezioso che mi offre tutti i vantaggi del mobile first con alcune nuove aggiunte positive che rendono il duro lavoro di sviluppo front-end che poco sia più facile.
Risorse
Repository del caso di prova
Se desideri avviare il test case e provarlo tu stesso, puoi trovarlo su GitHub, mi piacerebbe vedere alcuni rapporti di altri.
Utensili
- CSS MQPacker
- Includi media