Salta la navigazione
Parte I Capitolo 2

JavaScript

Introduzione

JavaScript ha fatto molta strada dalle sue umili origini come l’ultimo dei tre capisaldi del web, insieme a CSS e HTML. Oggi JavaScript ha iniziato a infiltrarsi in un ampio spettro dello stack tecnico. Non è più limitato al lato client ed è una scelta sempre più popolare per gli strumenti di compilazione e lo scripting lato server. JavaScript si sta facendo strada anche nel livello CDN grazie alle soluzioni di edge computing.

Gli sviluppatori adorano un po’ di JavaScript. Secondo il capitolo Markup, l’elemento script è il sesto elemento HTML più popolare in uso (prima di elementi come p e i, tra innumerevoli altri). Spendiamo circa 14 volte più byte su HTML rispetto a HTML, l’elemento costitutivo del Web, e 6 volte più byte rispetto a CSS.

Figura 2.1. Peso medio della pagina per tipo di contenuto.

Ma niente è gratuito, e questo è particolarmente vero per JavaScript: tutto quel codice ha un costo. Approfondiamo e diamo un’occhiata più da vicino a quanto script usiamo, come lo usiamo e quali sono le conseguenze.

Quanto JavaScript utilizziamo?

Abbiamo detto che il tag script è il sesto elemento HTML più utilizzato. Analizziamo un po’ più a fondo per vedere quanto JavaScript effettivamente ammonta.

Il sito mediano (il 50° percentile) invia 444 KB di JavaScript quando viene caricato su un dispositivo desktop e leggermente meno (411 KB) a un dispositivo mobile.

Figura 2.2. Distribuzione della quantità di kilobyte JavaScript caricati per pagina.

È un po’ deludente che qui non ci sia un divario maggiore. Sebbene sia pericoloso fare troppe ipotesi sulla rete o sulla potenza di elaborazione in base al fatto che il dispositivo in uso sia un telefono o un desktop (o una via di mezzo), vale la pena notare che Test mobile di HTTP Archive vengono eseguiti emulando un Moto G4 e una rete 3G. In altre parole, se ci fosse del lavoro da fare per adattarsi a circostanze tutt’altro che ideali passando meno codice, questi test dovrebbero mostrarlo.

La tendenza sembra anche essere a favore dell’utilizzo di più JavaScript, non di meno. Confrontando con i risultati dell’anno scorso, alla mediana vediamo un aumento del 13.4% in JavaScript testato su un dispositivo desktop e un 14.4% aumento della quantità di JavaScript inviato a un dispositivo mobile.

Client 2019 2020 Variazione
Desktop 391 444 13.4%
Mobile 359 411 14.4%
Figura 2.3. Variazione anno su anno del numero mediano di kilobyte JavaScript per pagina.

Almeno una parte di questo peso sembra non essere necessaria. Se esaminiamo una ripartizione di quanto di quel JavaScript è inutilizzato su un dato caricamento della pagina, vediamo che la pagina mediana sta inviando 152 KB di JavaScript inutilizzato. Quel numero salta a 334 KB al 75° percentile e 567 KB al 90° percentile.

Figura 2.4. Distribuzione della quantità di byte JavaScript sprecati per pagina mobile.

Come numeri grezzi, quelli possono o meno saltarti fuori a seconda di quanto sei un fanatico delle prestazioni, ma quando lo guardi come percentuale del totale JavaScript utilizzato su ciascuna pagina, diventa un po’ più facile vedere quanto sprechiamo.

37.22%
Figura 2.5. Percentuale di byte JavaScript della pagina per dispositivi mobile mediana non utilizzati.

Quei 153 KB equivalgono a circa il 37% della dimensione totale dello script che inviamo ai dispositivi mobile. C’è sicuramente un margine di miglioramento qui.

module e nomodule

Un meccanismo che abbiamo per ridurre potenzialmente la quantità di codice che inviamo è quello di sfruttare il pattern module/nomodule. Con questo pattern, creiamo due set di bundle: un bundle destinato ai browser moderni e uno destinato ai browser legacy. Il bundle destinato ai browser moderni ottiene un type=module e il bundle destinato ai browser legacy ottiene un type=nomodule.

Questo approccio ci consente di creare bundle più piccoli con una sintassi moderna ottimizzata per i browser che lo supportano, fornendo al contempo polyfill caricati in modo condizionale e sintassi diversa per i browser che non lo supportano.

Il supporto per module e nomodule si sta espandendo, ma ancora relativamente nuovo. Di conseguenza, l’adozione è ancora un po’ bassa. Solo il 3.6% delle pagine mobile utilizza almeno uno script con type=module e solo lo 0.7% delle pagine mobile utilizza almeno uno script con type=nomodule per supportare i browser legacy.

Conteggio richieste

Un altro modo per vedere quanto JavaScript utilizziamo è esplorare quante richieste JavaScript vengono effettuate su ogni pagina. Sebbene la riduzione del numero di richieste fosse fondamentale per mantenere buone prestazioni con HTTP/1.1, con HTTP/2 è il caso opposto: suddividere JavaScript in file singoli più piccoli è in genere migliore per le prestazioni.

Figura 2.6. Distribuzione delle richieste JavaScript per pagina.

Alla mediana, le pagine fanno 20 richieste JavaScript. Questo è solo un piccolo aumento rispetto allo scorso anno, quando la pagina mediana ha effettuato 19 richieste JavaScript.

Figura 2.7. Distribuzione delle richieste JavaScript per pagina nel 2019.

Da dove viene?

Una tendenza che probabilmente contribuisce all’aumento di JavaScript utilizzato sulle nostre pagine è la quantità apparentemente crescente di script di terze parti che vengono aggiunti alle pagine per aiutare con tutto, dai test A/B lato client e analisi, alla pubblicazione di annunci e gestione della personalizzazione.

Analizziamolo un po’ per vedere quanto script di terze parti stiamo servendo.

In media, i siti servono all’incirca lo stesso numero di script di prima parte di quelli di terze parti. Nella mediana, 9 script per pagina sono di prima parte, rispetto ai 10 per pagina di terze parti. Da lì, il divario si allarga un po’: più script un sito serve in totale, più è probabile che la maggior parte di quegli script provenga da terze parti.

Figura 2.8. Distribuzione del numero di richieste JavaScript da host per desktop.
Figura 2.9. Distribuzione del numero di richieste JavaScript da parte dell’host per dispositivi mobile.

Sebbene la quantità di richieste JavaScript sia simile alla mediana, la dimensione effettiva di quegli script è ponderata (gioco di parole) un po’ più pesantemente verso fonti di terze parti. Il sito mediano invia 267 KB di JavaScript da terze parti ai dispositivi desktop, rispetto ai 147 KB delle prime parti. La situazione è molto simile sui dispositivi mobile, dove il sito mediano spedisce 255 KB di script di terze parti rispetto ai 134 KB di script di prima parte.

Figura 2.10. Distribuzione del numero di byte JavaScript per host per desktop.
Figura 2.11. Distribuzione del numero di byte JavaScript per host per dispositivi mobile.

Come cariciamo il nostro JavaScript?

Il modo in cui cariciamo JavaScript ha un impatto significativo sull’esperienza complessiva.

Di default, JavaScript è parser-blocking. In altre parole, quando il browser scopre un elemento script, deve sospendere l’analisi dell’HTML finché lo script non è stato scaricato, analizzato ed eseguito. È un collo di bottiglia significativo e un contributo comune alle pagine che sono lente da visualizzare.

Possiamo iniziare a compensare parte del costo del caricamento di JavaScript caricando gli script in modo asincrono (con l’attributo async), che arresta il parser HTML solo durante le fasi di analisi ed esecuzione e non durante la fase di download, o differito (con il attributo defer), che non arresta affatto il parser HTML. Entrambi gli attributi sono disponibili solo su script esterni: gli script inline non possono essere applicati.

Sui dispositivi mobile, gli script esterni costituiscono il 59,0% di tutti gli elementi di script trovati.

Per inciso, quando abbiamo parlato di quanto JavaScript è stato caricato in una pagina in precedenza, quel totale non ha tenuto conto della dimensione di questi script inline, poiché fanno parte del documento HTML, vengono conteggiati rispetto alla dimensione del markup . Ciò significa che carichiamo ancora più script che mostrano i numeri.

Figura 2.12. Distribuzione del numero di script esterni e inline per pagina mobile.

Di questi script esterni, solo il 12.2% viene caricato con l’attributo async e il 6.0% con l’attributo defer.

Figura 2.13. Distribuzione del numero di script async e defer per pagina mobile.

Considerando che defer ci fornisce le migliori prestazioni di caricamento (assicurando che il download dello script avvenga in parallelo ad altri lavori, e l’esecuzione attende fino a quando la pagina può essere visualizzata), speriamo di vedere quella percentuale un po’ più alta. Infatti, il 6.0% è leggermente gonfiato.

Quando il supporto di IE8 e IE9 era più comune, era relativamente comune usare entrambi gli attributi async e defer. Con entrambi gli attributi posizionati, qualsiasi browser che li supporti entrambi utilizzerà async. IE8 e IE9, che non supportano async, torneranno a differire.

Al giorno d’oggi, il pattern non è necessario per la stragrande maggioranza dei siti e qualsiasi script caricato con il pattern in posizione interromperà il parser HTML quando deve essere eseguito, invece di rimandare fino al caricamento della pagina. Il pattern è ancora utilizzato sorprendentemente spesso, con l’11.4% delle pagine per dispositivi mobile che pubblica almeno uno script con quel pattern in atto. In altre parole, almeno una parte del 6% degli script che usa defer non sta ottenendo tutti i vantaggi dell’attributo defer.

C’è una storia incoraggiante qui, però.

Harry Roberts ha twittato sull’antipattern su Twitter, che è ciò che ci ha spinto a controllare per vedere quanto spesso ciò si verificava in natura. Rick Viscomi ha controllato per vedere chi erano i principali colpevoli, e si è scoperto che “stats.wp.com” era la fonte dei criminali più comuni. @Kraft di Automattic ha risposto e il pattern verrà ora rimosso in futuro.

Una delle grandi cose dell’apertura del web è come un’osservazione può portare a cambiamenti significativi ed è esattamente quello che è successo qui.

Le Resource hints

Un altro strumento che abbiamo a nostra disposizione per compensare alcuni dei costi di rete per il caricamento di JavaScript sono le resource hints, in particolare prefetch e preload.

L’hint prefetch consente agli sviluppatori di indicare che una risorsa verrà utilizzata nella navigazione della pagina successiva, quindi il browser dovrebbe provare a scaricarla quando il browser è inattivo.

L’hint preload significa che una risorsa verrà utilizzata nella pagina corrente e che il browser dovrebbe scaricarla subito con una priorità più alta.

Nel complesso, vediamo che il 16,7% delle pagine per dispositivi mobile utilizza almeno uno delle due resource hints per caricare JavaScript in modo più proattivo.

Di questi, quasi tutto l’utilizzo proviene da preload. Mentre il 16.6% delle pagine mobile utilizza almeno un hint preload per caricare JavaScript, solo lo 0.4% delle pagine mobile usa almeno un hint prefetch.

C’è il rischio, in particolare con preload, di usare troppe hint e di ridurne l’efficacia, quindi vale la pena guardare le pagine che usano questi suggerimenti per vedere quanti ne stanno usando.

Figura 2.14. Distribuzione del numero di hint prefetch per pagina con qualsiasi hint prefetch.
Figura 2.15. Distribuzione del numero di hint preload per pagina con qualsiasi hint preload.

In media, le pagine che usano un hint prefetch per caricare JavaScript ne usano tre, mentre le pagine che usano un hint preload ne usano solo uno. La coda lunga diventa un po’ più interessante, con 12 hint prefetch usati al 90° percentile e 7 hint preload usati anche loro al 90° percentile. Per maggiori dettagli sulle resource hint, consultare il capitolo Resource Hints di quest’anno.

Come serviamo JavaScript?

Come con qualsiasi risorsa di testo sul Web, possiamo salvare un numero significativo di byte tramite la minimizzazione e la compressione. Nessuna di queste sono nuove ottimizzazioni - sono in circolazione da un po’ di tempo - quindi dovremmo aspettarci di vederle applicate nella maggior parte dei casi.

Uno degli audit in Lighthouse controlla JavaScript non minimizzato e fornisce un punteggio (0.00 è il peggiore, 1.00 è il migliore) in base ai risultati.

Figura 2.16. Distribuzione dei punteggi di audit riguardante JavaScript non minimizzato per pagina mobile.

Il grafico sopra mostra che la maggior parte delle pagine testate (77%) ottiene un punteggio di 0.90 o superiore, il che significa che vengono trovati pochi script non minimizzati.

Nel complesso, solo il 4,5% delle richieste JavaScript registrate non è minimizzato.

È interessante notare che, anche se abbiamo scelto un po’ le richieste di terze parti, questa è un’area in cui gli script di terze parti stanno andando meglio degli script di prima parte. L’82% dei byte JavaScript non minimizzati di una pagina mobile media proviene da codice di prima parte.

Figura 2.17. Distribuzione media dei byte JavaScript non minimizzati per host.

Compressione

La minimizzazione è un ottimo modo per ridurre le dimensioni dei file, ma la compressione è ancora più efficace e, quindi, più importante: fornisce la maggior parte dei risparmi di rete il più delle volte.

Figura 2.18. Distribuzione della percentuale di richieste JavaScript per metodo di compressione.

L’85% di tutte le richieste JavaScript ha un certo livello di compressione di rete applicato. Gzip costituisce la maggior parte di ciò, con il 65% degli script a cui è stata applicata la compressione Gzip rispetto al 20% per Brotli (br). Sebbene la percentuale di Brotli (che è più efficace di Gzip) sia bassa rispetto al supporto del browser, sta andando nella giusta direzione, aumentando di 5 punti percentuali nell’ultimo anno.

Ancora una volta, questa sembra essere un’area in cui gli script di terze parti stanno effettivamente facendo meglio degli script di prima parte. Se suddividiamo i metodi di compressione per prime e terze parti, vediamo che il 24% degli script di terze parti ha applicato Brotli, rispetto a solo il 15% degli script di terze parti.

Figura 2.19. Distribuzione della percentuale di richieste JavaScript mobile per metodo di compressione e host.

Anche gli script di terze parti hanno meno probabilità di essere serviti senza alcuna compressione: il 12% degli script di terze parti non ha né Gzip né Brotli applicati, rispetto al 19% degli script di prima parte.

Vale la pena dare un’occhiata più da vicino a quegli script a cui non è stata applicata la compressione. La compressione più diventa efficiente in termini di risparmio, maggiore è il contenuto con cui si deve lavorare. In altre parole, se il file è piccolo, a volte il costo della compressione del file non supera la minima riduzione della dimensione del file.

90.25%
Figura 2.20. Percentuale di richieste JavaScript di terze parti non compresse inferiori a 5 KB.

Per fortuna, è esattamente quello che vediamo, in particolare negli script di terze parti in cui il 90% degli script non compressi ha una dimensione inferiore a 5 KB. D’altra parte, il 49% degli script di prima parte non compressi è inferiore a 5 KB e il 37% degli script di prima parte non compressi è superiore a 10 KB. Quindi, anche se vediamo molti piccoli script di prima parte non compressi, ce ne sono ancora alcuni che trarrebbero vantaggio da una certa compressione.

Cosa usiamo?

Poiché abbiamo utilizzato sempre più JavaScript per potenziare i nostri siti e le nostre applicazioni, c’è stata anche una crescente domanda di librerie e framework open source per aiutare a migliorare la produttività degli sviluppatori e la manutenibilità complessiva del codice. I siti che non utilizzano uno di questi strumenti sono sicuramente la minoranza sul web di oggi: jQuery da solo si trova su quasi l’85% delle pagine mobile monitorate da HTTP Archive.

È importante pensare in modo critico agli strumenti che utilizziamo per costruire il Web e quali sono i compromessi, quindi ha senso esaminare attentamente ciò che vediamo in uso oggi.

Librerie

HTTP Archive utilizza Wappalyzer per rilevare le tecnologie in uso su una determinata pagina. Wappalazyer tiene traccia di entrambe le librerie JavaScript (pensate a queste come una raccolta di frammenti o funzioni di supporto per facilitare lo sviluppo, come jQuery) e framework JavaScript (queste sono più probabili impalcature e forniscono modelli e strutture, come React).

Le librerie popolari in uso sono sostanzialmente invariate rispetto allo scorso anno, con jQuery che continua a dominare l’utilizzo e solo una delle 21 migliori librerie è caduta (lazy.js, sostituita da DataTables). In effetti, anche le percentuali delle migliori librerie sono cambiate appena rispetto allo scorso anno.

Figura 2.21. Adozione dei principali framework e librerie JavaScript come percentuale delle pagine.

L’anno scorso, Houssein ha ipotizzato alcuni motivi per cui il dominio di jQuery continua:

WordPress, che viene utilizzato in oltre il 30% dei siti, include jQuery di default. Il passaggio da jQuery a una nuova libreria lato client può richiedere tempo a seconda delle dimensioni di un’applicazione e molti siti possono essere costituiti da jQuery oltre alle nuove librerie lato client.

Entrambe sono ipotesi molto valide e sembra che la situazione non sia cambiata molto su entrambi i fronti.

In effetti, il predominio di jQuery è ulteriormente supportato se ci si ferma a considerare che, delle 10 migliori librerie, 6 di esse sono jQuery o richiedono jQuery per essere utilizzate: jQuery UI, jQuery Migrate, FancyBox, Lightbox e Slick.

I Framework

Quando guardiamo i framework, non vediamo nemmeno un cambiamento radicale in termini di adozione nei framework principali che sono stati evidenziati lo scorso anno. Vue.js ha visto un aumento significativo e AMP è cresciuto un po’, ma la maggior parte di loro sono più o meno dove erano un anno fa.

Vale la pena notare che il problema di rilevamento rilevato lo scorso anno è ancora valido e ha ancora un impatto sui risultati qui. È possibile che ci sia stato un cambiamento significativo nella popolarità di alcuni di questi strumenti, ma semplicemente non lo vediamo con il modo in cui i dati vengono attualmente raccolti.

Cosa significa tutto

Più interessante per noi della popolarità degli strumenti stessi è l’impatto che hanno sulle cose che costruiamo.

Innanzitutto, vale la pena notare che mentre possiamo pensare all’uso di uno strumento rispetto a un altro, in realtà raramente usiamo solo una singola libreria o framework in produzione. Solo il 21% delle pagine analizzate riporta una sola libreria o framework. Due o tre framework sono abbastanza comuni e la coda lunga diventa molto lunga, molto rapidamente.

Quando guardiamo le combinazioni comuni che vediamo nella produzione, la maggior parte di esse è prevedibile. Conoscendo il predominio di jQuery, non sorprende che la maggior parte delle combinazioni popolari includa jQuery e un numero qualsiasi di plugin relativi a jQuery.

Combinazioni Pagine (%)
jQuery 1,312,601 20.7%
jQuery, jQuery Migrate 658,628 10.4%
jQuery, jQuery UI 289,074 4.6%
Modernizr, jQuery 155,082 2.4%
jQuery, jQuery Migrate, jQuery UI 140,466 2.2%
Modernizr, jQuery, jQuery Migrate 85,296 1.3%
FancyBox, jQuery 84,392 1.3%
Slick, jQuery 72,591 1.1%
GSAP, Lodash, React, RequireJS, Zepto 61,935 1.0%
Modernizr, jQuery, jQuery UI 61,152 1.0%
Lightbox, jQuery 60,395 1.0%
Modernizr, jQuery, jQuery Migrate, jQuery UI 53,924 0.8%
Slick, jQuery, jQuery Migrate 51,686 0.8%
Lightbox, jQuery, jQuery Migrate 50,557 0.8%
FancyBox, jQuery, jQuery UI 44,193 0.7%
Modernizr, YUI 42,489 0.7%
React, jQuery 37,753 0.6%
Moment.js, jQuery 32,793 0.5%
FancyBox, jQuery, jQuery Migrate 31,259 0.5%
MooTools, jQuery, jQuery Migrate 28,795 0.5%
Figura 2.22. Le combinazioni più popolari di librerie e framework su pagine mobile.

Vediamo anche una discreta quantità di framework più “moderni” come React, Vue e Angular abbinati a jQuery, ad esempio come risultato della migrazione o dell’inclusione da parte di terze parti.

Combinazione Senza jQuery Con jQuery
GSAP, Lodash, React, RequireJS, Zepto 1.0%  
React, jQuery   0.6%
React 0.4%  
React, jQuery, jQuery Migrate   0.4%
Vue.js, jQuery   0.3%
Vue.js 0.2%  
AngularJS, jQuery   0.2%
GSAP, Hammer.js, Lodash, React, RequireJS, Zepto 0.2%  
Somma totale 1.7% 1.4%
Figura 2.23. Le combinazioni più popolari di React, Angular e Vue con e senza jQuery.

Ancora più importante, tutti questi strumenti in genere significano più codice e più tempo di elaborazione.

Osservando specificamente i framework in uso, vediamo che i byte JavaScript mediani per le pagine che li utilizzano variano notevolmente a seconda di cosa viene utilizzato.

Il grafico seguente mostra i byte mediani per le pagine in cui è stato trovato uno dei primi 35 framework più comunemente rilevati, suddivisi per client.

Figura 2.24. Il numero mediano di kilobyte JavaScript per pagina dal framework JavaScript.

Su uno dello spettro ci sono framework come React o Angular o Ember, che tendono a fornire molto codice indipendentemente dal client. Dall’altro lato, vediamo framework minimalisti come Alpine.js e Svelte che mostrano risultati molto promettenti. I default sono molto importanti e sembra che, iniziando con default altamente performanti, Svelte e Alpine riescano entrambi (finora… la dimensione del campione è piuttosto piccola) nel creare un insieme di pagine più leggero.

Otteniamo un’immagine molto simile quando guardiamo il tempo del thread principale per le pagine in cui sono stati rilevati questi strumenti.

Figura 2.25. Il tempo mediano del thread principale per pagina dal framework JavaScript.

Il tempo del thread principale mobile di Ember salta fuori e distorce il grafico con il tempo necessario. (Ho passato un po’ più di tempo a esaminare questo aspetto e sembra essere fortemente influenzato da una particolare piattaforma che utilizza questo framework in modo inefficiente, piuttosto che da un problema di fondo con Ember stesso.) Tirare fuori l’immagine dal grafico lo rende più facile da capire.

Figura 2.26. Il tempo mediano del thread principale per pagina per framework JavaScript, escluso Ember.js.

Strumenti come React, GSAP e RequireJS tendono a dedicare molto tempo al thread principale del browser, indipendentemente dal fatto che si tratti di una visualizzazione di pagina desktop o mobile. Gli stessi strumenti che tendono a portare a meno codice in generale, strumenti come Alpine e Svelte, tendono anche a portare a un impatto inferiore sul thread principale.

Vale anche la pena approfondire il divario tra l’esperienza che un framework fornisce per desktop e mobile. Il traffico mobile sta diventando sempre più dominante ed è fondamentale che i nostri strumenti funzionino nel miglior modo possibile per le visualizzazioni di pagina mobili. Maggiore è il divario che vediamo tra le prestazioni desktop e mobile per un framework, maggiore è la bandiera rossa.

Figura 2.27. Differenza tra il tempo mediano del thread principale desktop e mobile per pagina in base al framework JavaScript, escluso Ember.js.

Come ci si aspetterebbe, c’è un divario tra tutti gli strumenti in uso a causa della minore potenza di elaborazione del Moto G4 emulato. Ember e Polymer sembrano saltare fuori come esempi particolarmente eclatanti, mentre strumenti come RxJS e Moustache variano solo leggermente da desktop a mobile.

Qual è l’impatto?

Ora abbiamo un quadro abbastanza buono di quanto JavaScript usiamo, da dove proviene e per cosa lo usiamo. Anche se questo è abbastanza interessante da solo, il vero kicker è il “e allora?” Che impatto ha effettivamente tutto questo script sull’esperienza delle nostre pagine?

La prima cosa che dovremmo considerare è cosa succede con tutto quel JavaScript una volta scaricato. Il download è solo la prima parte del viaggio in JavaScript. Il browser deve ancora analizzare tutto lo script, compilarlo e infine eseguirlo. Mentre i browser sono costantemente alla ricerca di modi per scaricare parte di quel costo su altri thread, gran parte di quel lavoro avviene ancora sul thread principale, impedendo al browser di essere in grado di eseguire lavori relativi al layout o al paint, oltre ad essere in grado di rispondere all’interazione dell’utente.

Se ricordi, c’era solo una differenza di 30 KB tra ciò che viene spedito su un dispositivo mobile e un dispositivo desktop. A seconda del tuo punto di vista, potresti essere perdonato per non esserti arrabbiato troppo per il piccolo divario nella quantità di codice inviato a un browser desktop rispetto a uno mobile, dopotutto, che cosa è un extra di 30 KB circa in media, giusto ?

Il problema più grande arriva quando tutto quel codice viene fornito a un dispositivo di fascia medio-bassa, dove è molto probabile che la maggior parte degli sviluppatori non ha quel tipo di dispositivi e un po’ più verosimile al tipo di dispositivi che vedrai dalla maggior parte delle persone in tutto il mondo. Questo divario relativamente piccolo tra desktop e mobile è molto più drammatico se lo guardiamo in termini di tempo di elaborazione.

Il sito desktop mediano spende 891 ms sul thread principale di un browser che funziona con tutto quel JavaScript. Il sito per dispositivi mobile mediano, tuttavia, impiega 1.897 ms, più del doppio del tempo trascorso sul desktop. È anche peggio per la lunga coda di siti. Al 90° percentile, i siti per dispositivi mobili trascorrono l’incredibile quantità di 8.921 ms del thread principale che si occupa di JavaScript, rispetto ai 3.838 ms dei siti desktop.

Figura 2.28. Distribuzione del tempo del thread principale.

Correlare l’uso di JavaScript al punteggio di Lighthouse

Un modo per vedere come questo si traduce in un impatto sull’esperienza utente è provare a correlare alcune delle metriche JavaScript che abbiamo identificato in precedenza con i punteggi di Lighthouse per metriche e categorie diverse.

Figura 2.29. Correlazioni di JavaScript su vari aspetti dell’esperienza utente.

Il grafico sopra utilizza il coefficiente di correlazione di Pearson. C’è una definizione lunga e un po’ complessa di cosa significhi precisamente, ma il succo è che stiamo cercando la forza della correlazione tra due numeri diversi. Se troviamo un coefficiente di 1,00, avremmo una correlazione positiva diretta. Una correlazione di 0,00 non mostrerebbe alcuna connessione tra due numeri. Qualunque cosa al di sotto di 0,00 indica una correlazione negativa, in altre parole, quando un numero aumenta, l’altro diminuisce.

Innanzitutto, non sembra esserci molta correlazione misurabile tra le nostre metriche JavaScript e il punteggio di accessibilità Lighthouse (“LH A11y” nel grafico) qui. Ciò è in netto contrasto con ciò che è stato trovato altrove, in particolare tramite la ricerca annuale di WebAim.

La spiegazione più probabile è che i test di accessibilità di Lighthouse non sono così completi (ancora!) come ciò che è disponibile attraverso altri strumenti, come WebAIM, che hanno l’accessibilità come obiettivo principale.

Dove vediamo una forte correlazione è tra la quantità di byte JavaScript (“byte”) e sia il punteggio complessivo delle prestazioni di Lighthouse (“LH Perf”) e il tempo di blocco totale (“TBT”).

La correlazione tra i byte JavaScript e i punteggi delle prestazioni di Lighthouse è -0,47. In altre parole, all’aumentare dei byte JS, i punteggi delle prestazioni di Lighthouse diminuiscono. I byte complessivi hanno una correlazione più forte rispetto alla quantità di byte di terze parti (“3P byte”), suggerendo che sebbene abbiano certamente un ruolo, non possiamo attribuire tutta la colpa a terze parti.

La connessione tra il tempo di blocco totale e i byte JavaScript è ancora più significativa (0,55 per i byte complessivi, 0,48 per i byte di terze parti). Non è troppo sorprendente, dato quello che sappiamo su tutti i browser di lavoro che devono fare per far funzionare JavaScript in una pagina: più byte significa più tempo.

Vulnerabilità di sicurezza

Un altro controllo utile eseguito da Lighthouse consiste nel verificare la presenza di vulnerabilità di sicurezza note nelle librerie di terze parti. Lo fa rilevando quali librerie e framework vengono utilizzati in una determinata pagina e quale versione viene utilizzata di ciascuno. Quindi controlla il database delle vulnerabilità open source di Snyk per vedere quali vulnerabilità sono state scoperte negli strumenti identificati.

83.50%
Figura 2.30. La percentuale di pagine per dispositivi mobili contiene almeno una libreria JavaScript vulnerabile.

Secondo l’audit, l’83,5% delle pagine mobile utilizza una libreria o un framework JavaScript con almeno una vulnerabilità di sicurezza nota.

Questo è ciò che chiamiamo effetto jQuery. Ricordi come abbiamo visto che jQuery viene utilizzato su un enorme 83% delle pagine? Diverse versioni precedenti di jQuery contengono vulnerabilità note, che comprendono la stragrande maggioranza delle vulnerabilità controllate da questo audit.

Dei circa 5 milioni di pagine per dispositivi mobile su cui è stato eseguito il test, l’81% di esse contiene una versione vulnerabile di jQuery, un vantaggio considerevole rispetto alla seconda libreria vulnerabile più comunemente trovata, jQuery UI al 15,6%.

Librerie Pagine vulnerabili
jQuery 80.86%
jQuery UI 15.61%
Bootstrap 13.19%
Lodash 4.90%
Moment.js 2.61%
Handlebars 1.38%
AngularJS 1.26%
Mustache 0.77%
Dojo 0.58%
jQuery Mobile 0.53%
Figura 2.31. Le 10 migliori librerie che contribuiscono al maggior numero di pagine mobile vulnerabili secondo Lighthouse.

In altre parole, se riusciamo a convincere la gente a migrare da quelle versioni obsolete e vulnerabili di jQuery, vedremmo precipitare il numero di siti con vulnerabilità note (almeno, finché non inizieremo a trovarne alcuni nei framework più recenti).

La maggior parte delle vulnerabilità rilevate rientra nella categoria di gravità “media”.

Figura 2.32. Distribuzione della percentuale di pagine mobili con vulnerabilità JavaScript per gravità.

Conclusione

JavaScript è in costante aumento in popolarità e tutto questo è positivo. È incredibile considerare ciò che siamo in grado di realizzare sul web di oggi grazie a JavaScript che, anche pochi anni fa, sarebbe stato inimmaginabile.

Ma è chiaro che dobbiamo anche procedere con cautela. La quantità di JavaScript aumenta costantemente ogni anno (se il mercato azionario fosse così prevedibile, saremmo tutti incredibilmente ricchi) e ciò comporta dei compromessi. Più JavaScript è collegato a un aumento del tempo di elaborazione che influisce negativamente sulle metriche chiave come il tempo di blocco totale. E, se lasciamo che quelle librerie languiscano senza tenerle aggiornate, corrono il rischio di esporre gli utenti a vulnerabilità di sicurezza note.

Valutare attentamente il costo degli script che aggiungiamo alle nostre pagine ed essere disposti a porre un occhio critico sui nostri strumenti e chiedere di più sono le nostre migliori scommesse per assicurarci di costruire un Web accessibile, efficiente e sicuro.

Autore