Ho usato il Web per un giorno su Internet Explorer 8
Pubblicato: 2022-03-10Questo articolo fa parte di una serie in cui tento di utilizzare il Web con vari vincoli, rappresentando un determinato gruppo demografico di utenti. Spero di elevare il profilo delle difficoltà incontrate dalle persone reali, che sono evitabili se progettiamo e sviluppiamo in un modo che sia comprensivo ai loro bisogni.
L'ultima volta, ho navigato sul Web per un giorno utilizzando uno screen reader. Questa volta, ho trascorso la giornata utilizzando Internet Explorer 8, che è stato rilasciato dieci anni fa oggi, il 19 marzo 2009.
Chi nel mondo usa IE8?
Prima di iniziare; un disclaimer: non sto per dirti che devi iniziare a supportare IE8.
Ci sono tutte le ragioni per non supportare IE8. Microsoft ha ufficialmente smesso di supportare IE8, IE9 e IE10 più di tre anni fa e i dirigenti Microsoft ti stanno persino dicendo di smettere di usare Internet Explorer 11.
Ma per quanto noi sviluppatori speriamo che scompaia, è semplicemente così. Non lo farà. Muori . IE8 continua a comparire nelle statistiche dei browser, soprattutto al di fuori della bolla del mondo occidentale.
Le statistiche del browser devono essere prese con un pizzico di sale, ma le stime attuali per l'utilizzo di IE8 in tutto il mondo sono comprese tra lo 0,3% e lo 0,4% della quota di mercato dei desktop. L'estremità inferiore della stima proviene da w3counter:
La stima più alta proviene da StatCounter (lo stesso feed di dati utilizzato dalla tabella di utilizzo "Posso utilizzare"). Si stima che la proporzione globale del browser desktop IE8 sia di circa lo 0,37%.
Sospettavo che potremmo vedere un maggiore utilizzo di IE8 in alcune regioni geografiche, quindi approfondito i dati per continente.
Utilizzo di IE8 per regione
Ecco la proporzione desktop IE8 per continente (dati da febbraio 2018 a gennaio 2019):
1. | Oceania | 0,09% |
2. | Europa | 0,25% |
3. | Sud America | 0,30% |
4. | Nord America | 0,35% |
5. | Africa | 0,48% |
6. | Asia | 0,50% |
Qualcuno in Asia ha cinque volte più probabilità di utilizzare IE8 rispetto a qualcuno in Oceania.
Ho esaminato più da vicino le statistiche asiatiche, notando la proporzione di utilizzo di IE8 per ciascun paese. C'è un chiaro primo sei paesi per l'utilizzo di IE8, dopo di che le cifre scendono per essere comparabili con la media mondiale:
1. | Iran | 3,99% |
2. | Cina | 1,99% |
3. | Corea del nord | 1,38% |
4. | Turkmenistan | 1,31% |
5. | Afghanistan | 1,27% |
6. | Cambogia | 1,05% |
7. | Yemen | 0,63% |
8. | Taiwan | 0,62% |
9. | Pakistan | 0,57% |
10. | Bangladesh | 0,54% |
Questi dati sono riassunti nella mappa sottostante:
Incredibilmente, IE8 rappresenta circa il 4% degli utenti desktop in Iran, quaranta volte la proporzione degli utenti IE8 in Oceania.
Successivamente, ho esaminato le statistiche del paese per l'Africa, poiché aveva all'incirca lo stesso utilizzo complessivo di IE8 dell'Asia. C'è stato un chiaro vincitore (Eritrea), seguito da un certo numero di paesi al di sopra o intorno al segno di utilizzo dell'1%:
1. | Eritrea | 3,24% |
2. | Botswana | 1,37% |
3. | Sudan e Sud Sudan | 1,33% |
4. | Niger | 1,29% |
5. | Mozambico | 1,19% |
6. | Mauritania | 1,18% |
7. | Guinea | 1,12% |
8. | Repubblica Democratica del Congo | 1,07% |
9. | Zambia | 0,94% |
Questo è riassunto nella mappa qui sotto:
Mentre i paesi in Asia che hanno un utilizzo di IE8 superiore al normale sono geograficamente raggruppati insieme, non sembra esserci uno schema in Africa. L'unico modello che posso vedere, a meno che non sia una coincidenza, è che alcuni dei più grandi paesi che utilizzano IE8 del mondo censurano notoriamente l'accesso a Internet e quindi probabilmente non incoraggiano o consentono l'aggiornamento a browser più sicuri.
Se il tuo sito è rivolto a un pubblico puramente occidentale, è improbabile che ti importi molto di IE8. Se, tuttavia, hai un fiorente mercato asiatico o africano, e in particolare se ti interessano gli utenti in Cina, Iran o Eritrea, potresti benissimo preoccuparti dell'esperienza IE8 del tuo sito web. Sì, anche nel 2019!
Chi sta ancora usando IE?
Allora, chi sono queste persone? Camminano davvero in mezzo a noi?!
Chiunque siano, puoi scommettere che non stanno usando un vecchio browser solo per infastidirti. Nessuno sceglie deliberatamente un'esperienza di navigazione peggiore.
Qualcuno potrebbe utilizzare un vecchio browser per i seguenti motivi:
- Mancanza di consapevolezza
Semplicemente non sono consapevoli di utilizzare una tecnologia obsoleta. - Mancanza di istruzione
Non conoscono le opzioni di aggiornamento e i browser alternativi a loro aperti. - Mancanza di pianificazione
Ignorare le richieste di aggiornamento perché sono occupate, ma non avere la lungimiranza di aggiornare durante i periodi più tranquilli. - Avversione al cambiamento
L'ultima volta che hanno aggiornato il loro software, hanno dovuto imparare una nuova interfaccia utente. "Se non è rotto, non aggiustarlo." - Avversione al rischio
L'ultima volta che hanno eseguito l'aggiornamento, la loro macchina ha rallentato fino a rallentare o hanno perso la loro funzione preferita. - Limitazione del software
Il loro sistema operativo è troppo vecchio per consentire loro l'aggiornamento o i loro privilegi di amministratore potrebbero essere bloccati. - Limitazione hardware
I browser più recenti richiedono generalmente più spazio su disco rigido, memoria e CPU. - Limitazione della rete
Un limite di dati consentito o una connessione lenta significano che non vogliono scaricare 75 MB di software. - Limitazione legale
Potrebbero trovarsi su una macchina aziendale che condona solo l'uso di un browser specifico.
È davvero una tale sorpresa che ci siano ancora persone in tutto il mondo che si aggrappano a IE8?
Ho deciso di mettermi nei panni di una di queste anime anonime e di navigare per un giorno sul web usando IE8. Puoi giocare a casa! Scarica una macchina virtuale "IE8 su Windows 7" dal sito Web di Microsoft, quindi eseguila in un virtualizzatore come VirtualBox.
IE8 VM: inizio male
Ho avviato la mia VM IE8, ho fatto clic sul programma Internet Explorer in anticipo, e questo è quello che ho visto:
Hmm, va bene. Sembra che la pagina Web predefinita richiamata da IE8 non esista più. Bene, questo è il numero. Microsoft ha ufficialmente smesso di supportare IE8, quindi perché dovrebbe assicurarsi che la pagina di destinazione di IE8 funzioni ancora?
Ho deciso di passare al sito più utilizzato al mondo.
È un sito semplice, quindi è difficile sbagliare, ma ad essere onesti, ha un bell'aspetto! Ho provato a cercare qualcosa:
La ricerca ha funzionato bene, anche se il layout è leggermente diverso da quello a cui sono abituato. Poi mi sono ricordato: avevo visto lo stesso layout dei risultati di ricerca quando ho usato Internet per un giorno con JavaScript disattivato.
Per riferimento, ecco come appaiono i risultati della ricerca in un browser moderno con JavaScript abilitato:
Quindi, sembra che IE8 ottenga la versione senza JS della ricerca di Google. Non penso che questa sia stata necessariamente una decisione di progettazione deliberata: potrebbe semplicemente essere che JavaScript ha sbagliato:
Tuttavia, il risultato finale per me va bene: ho ottenuto i risultati della mia ricerca, che è tutto ciò che volevo.
Ho cliccato per guardare un video di YouTube.
Youtube
C'è un bel po' di problemi in questa pagina. Tutto a che fare con piccole stranezze in IE.
Il logo, ad esempio, viene ingrandito e ritagliato. Questo è dovuto al fatto che IE8 non supporta SVG e ciò che stiamo effettivamente vedendo è l'opzione di fallback fornita da YouTube. Hanno applicato una proprietà CSS background-image
in modo che, in caso di mancato supporto SVG, tu possa provare a visualizzare il logo. Solo che sembrano non aver impostato correttamente la background-size
, quindi è un po' troppo ingrandito.
Per riferimento, ecco la stessa pagina in Chrome (guarda come Chrome esegue invece il rendering di un SVG):
E che dire di quell'interruttore di riproduzione automatica? È reso come una casella di controllo dall'aspetto strano:
Questo sembra essere dovuto all'uso di un elemento personalizzato (un pulsante di attivazione/disattivazione della carta, che è un elemento di Material Design), che IE non comprende:
Non sono sorpreso che questo non sia stato reso correttamente; IE8 non riesce nemmeno a far fronte al markup semantico di base che usiamo in questi giorni. Prova a usare un <aside>
o <main>
e sostanzialmente li renderà come div, ma ignorando lo stile che applichi loro.
Per abilitare il markup HTML5, devi dire esplicitamente al browser che questi elementi esistono. Possono quindi essere stilizzati come di consueto:
<!--[if lt IE 9]> <script> document.createElement('header'); document.createElement('nav'); document.createElement('section'); document.createElement('article'); document.createElement('aside'); document.createElement('footer'); </script> <![endif]-->
Questo è racchiuso in un condizionale IE, tra l'altro. <!--[if lt IE 9]>
è un commento HTML per la maggior parte dei browser - e quindi viene saltato - ma in IE è un condizionale che passa solo "se inferiore a IE 9", dove esegue/renderizza i nodi DOM al suo interno.
Quindi, la pagina del video è stata un fallimento. Visitare direttamente YouTube.com non è andato molto meglio:
Imperterrito, ho ignorato l'avviso e ho provato a cercare un video nella barra di ricerca di YouTube.
Il traffico di IE8 è chiaramente abbastanza sospetto che YouTube non si è fidato del fatto che sono un utente reale e ha deciso di non elaborare la mia richiesta di ricerca!
Iscrizione a Gmail
Se ho intenzione di passare la giornata su IE8, avrò bisogno di un indirizzo email. Quindi provo a crearne uno nuovo.
Prima di tutto, ho provato Gmail.
C'è qualcosa di strano nell'immagine e nel testo qui. Penso che dipenda dal fatto che IE8 non supporta le query multimediali, quindi sta cercando di mostrarmi un'immagine mobile sul desktop.
Un modo per aggirare questo problema è usare Sass per generare due fogli di stile; uno per i browser moderni e uno per IE legacy. Puoi ottenere CSS mobile-first IE-friendly (vedi tutorial di Jake Archibald) usando un mixin per le tue media query. Il mixin "appiattisce" il tuo legacy IE CSS per trattare IE come se fosse sempre una larghezza predefinita specifica (ad esempio 65em), fornendo solo il CSS pertinente per quella larghezza. In questo caso, avrei visto l' background-image
corretta per le dimensioni dello schermo presunte e avrei avuto un'esperienza migliore.
Ad ogni modo, non mi ha impedito di fare clic su "Crea un account". C'erano alcune differenze tra l'aspetto in IE8 e un browser moderno:
Anche se a prima vista promettente, il modulo era piuttosto buggato da compilare. L '"etichetta" non si toglie di mezzo quando inizi a compilare i campi, quindi il testo di input è offuscato:
Il markup per questa etichetta è in realtà un <div>
, e alcuni JS intelligenti spostano il testo fuori mano quando l'input è focalizzato. Il JS non funziona su IE8, quindi il testo rimane ostinatamente al suo posto.
Dopo aver inserito tutti i miei dettagli, ho premuto "Avanti" e ho aspettato. Non è successo niente.
Poi ho notato il piccolo simbolo di avviso giallo in basso a sinistra della mia finestra di IE. L'ho cliccato e ho visto che si lamentava di un errore JS:
Ho rinunciato a Gmail e mi sono rivolto a MSN.
Iscriversi a Hotmail
Cominciavo a preoccuparmi che la posta elettronica potesse essere off-limits per un browser vecchio di dieci anni. Ma quando sono andato su Hotmail, il modulo di iscrizione sembrava OK, finora tutto bene:
Poi ho notato un CAPTCHA. Ho pensato: "Non ce la farò a superare questo..."
Con mia sorpresa, il CAPTCHA ha funzionato!
L'unica cosa bizzarra sul modulo era il posizionamento dell'etichetta leggermente buggato, ma per il resto la registrazione è stata fluida:
Quello screenshot ti sembra OK? Riesci a individuare l'errore deliberato?
L'input più a sinistra avrebbe dovuto essere il mio nome , non il mio cognome. Quando sono tornato e ho controllato questa pagina in seguito, ho fatto clic sull'etichetta "Nome" e ha applicato lo stato attivo all'input più a sinistra, ed è così che avrei potuto verificare che stavo compilando la casella corretta in primo luogo. Questo mostra l'importanza del markup accessibile : anche senza CSS e associazione visiva, potrei determinare esattamente quale casella di input applicata a quale etichetta (anche se la seconda volta!).
Ad ogni modo, sono stato in grado di completare il processo di registrazione e sono stato reindirizzato alla home page di MSN, il che è stato fantastico.
Potrei persino leggere articoli e dimenticare che stavo usando IE8:
Con la mia email registrata, ero pronto per andare a controllare il resto di Internet!
Ho visitato il sito Facebook e sono stato subito reindirizzato al sito mobile:
Questa è una tattica di ripiego intelligente, poiché Facebook deve supportare un vasto pubblico globale su dispositivi mobili di fascia bassa, quindi deve comunque fornire una versione base di Facebook. Perché non offrire la stessa base di esperienza ai browser desktop più vecchi?
Ho provato a registrarmi e sono riuscito a creare un account. Grande! Ma quando ho effettuato l'accesso a quell'account, sono stato trattato con sospetto, proprio come quando ho cercato cose su YouTube, e ho dovuto affrontare un CAPTCHA.
Solo che questa volta non è stato così facile.
Ho provato a richiedere nuovi codici e ad aggiornare la pagina più volte, ma l'immagine CAPTCHA non è mai stata caricata, quindi sono stato effettivamente bloccato fuori dal mio account.
Oh bene. Proviamo qualche altro social media.
Ho visitato il sito di Twitter e ho avuto esattamente la stessa esperienza di reindirizzamento mobile.
Ma questa volta non sono nemmeno riuscito ad arrivare a registrare un account:
Stranamente, Twitter è felice che tu acceda, ma non che tu ti registri in primo luogo. Non sono sicuro del perché, forse ha uno scenario CAPTCHA simile nelle sue pagine di registrazione che non funzionerà su browser meno recenti. In ogni caso, non sarò in grado di creare un nuovo account.
Mi sentivo a disagio ad accedere con il mio account Twitter esistente. Chiamami paranoico, ma vulnerabilità come il CFR Watering Hole Attack del 2013, in cui il semplice atto di visitare un URL specifico in IE8 installerebbe malware sul tuo computer, mi rendeva nervoso all'idea di poter compromettere il mio account.
Ma, nell'interesse dell'istruzione, ho perseverato (con una nuova password temporanea):
Potrei anche twittare, anche se usando il molto semplice <textarea>
:
In conclusione, Twitter va bene in IE8, purché tu abbia già un account!
Ho finito con i social media per la giornata. Andiamo a dare un'occhiata ad alcune novità.
notizie della BBC
La home page delle notizie sembra molto semplice e goffa, ma in pratica funziona, anche se con avvisi di sicurezza dei contenuti misti.
Dai un'occhiata al logo. Come abbiamo già visto su YouTube, IE8 non supporta SVG, quindi è necessario un fallback PNG.
La BBC utilizza la tecnica di fallback <image>
per eseguire il rendering di un PNG su IE:
...e per ignorare il PNG quando SVG è disponibile:
Questa tecnica sfrutta il fatto che i browser più vecchi erano soliti obbedire ai <image>
e <img>
, quindi ignoreranno il tag sconosciuto <svg>
e renderanno il fallback, mentre i browser moderni ignorano il rendering <image>
all'interno di un SVG. Chris Coyier spiega la tecnica in modo più dettagliato.
Ho provato a visualizzare un articolo:
È leggibile. Riesco a vedere il titolo, la navigazione, l'immagine in primo piano. Ma mancano le immagini del resto dell'articolo:
Questo è prevedibile ed è dovuto al caricamento lento delle immagini della BBC. IE8 non essendo un "browser supportato" significa che non ottiene il JavaScript che consente il caricamento lento, quindi le immagini non vengono mai caricate.
Per interesse, ho pensato di vedere cosa succede se provo ad accedere a BBC iPlayer:
E questo mi ha fatto pensare a un altro servizio di streaming.
Netflix
Mi aspettavo per metà una pagina bianca vuota quando ho caricato Netflix in IE8. Sono rimasto piacevolmente sorpreso quando ho visto una pagina di destinazione decente:
L'ho confrontato con la moderna versione di Chrome:
C'è un invito all'azione leggermente diverso (testo del pulsante), probabilmente dovuto a test multivariati piuttosto che al browser in cui mi trovo.
La differenza del rendering è il testo centralizzato e la sovrapposizione nera semitrasparente.
La mancanza di testo centralizzato è dovuta all'uso di Flexbox da parte di Netflix per l'allineamento degli elementi:
Un text-align: center
su questa classe probabilmente risolverebbe il centraggio per IE8 (e in effetti tutti i vecchi browser). Per il massimo supporto del browser, puoi seguire un approccio di fallback CSS con il vecchio CSS "sicuro", quindi rafforzare i layout con CSS più moderni per i browser che lo supportano.
La mancanza di sfondo è dovuta all'uso di rgba()
, che non è supportato in IE8 e precedenti.
Tradizionalmente è bene fornire dei CSS di riserva in questo modo, che mostrano uno sfondo nero per i vecchi browser ma mostrano uno sfondo semitrasparente per i browser moderni:
rgb(0, 0, 0); /* IE8 fallback */ rgba(0, 0, 0, 0.8);
Questa è una correzione molto specifica per IE, tuttavia, praticamente tutti gli altri browser supportano rgba
. Inoltre, in questo caso, perderesti del tutto i fantasiosi riquadri Netflix, quindi sarebbe meglio non avere alcun filtro di sfondo! Il modo infallibile per garantire il supporto cross-browser sarebbe inserire il filtro nell'immagine di sfondo stessa. Semplice ma efficace.
Comunque, finora, tutto bene: IE8 ha effettivamente reso la homepage abbastanza bene! Oggi guarderò davvero Breaking Bad su IE8?
Il mio già timido ottimismo è stato immediatamente abbattuto quando ho visualizzato la pagina di accesso:
Tuttavia, sono stato in grado di accedere e ho visto una dashboard ridotta (nessun trailer a espansione automatica di fantasia):
Ho cliccato su un programma con una vaga anticipazione, ma ovviamente ho visto solo una schermata nera.
Amazon
Ok, i social media e i video sono fuori. Non resta che andare a fare la spesa.
Ho controllato Amazon e sono rimasto sbalordito: è quasi indistinguibile dall'esperienza che avresti all'interno di un browser moderno:
Sono stato attratto da una buona homepage prima. Quindi facciamo clic sulla pagina di un prodotto e vediamo se questo è solo un colpo di fortuna.
No! Anche la pagina del prodotto sembrava buona!
Amazon non è stato l'unico sito che mi ha sorpreso per la sua compatibilità con le versioni precedenti. Wikipedia sembrava fantastico, così come il sito web del governo Gov.UK. Non è facile avere un sito che non sembri un vero incidente d'auto in IE8. La maggior parte delle mie esperienze sono state decisamente meno curate...!
Ma un avviso di avviso deprecato o un layout originale non è stata la cosa peggiore che ho visto oggi.
Siti completamente rotti
Alcuni siti erano così danneggiati che non riuscivo nemmeno a connettermi a loro!
Mi chiedevo se potesse essere un problema di rete VM temporaneo, ma succedeva ogni volta che aggiornavo la pagina, anche quando tornavo sullo stesso sito nel corso della giornata.
Ciò è accaduto su alcuni siti diversi durante il giorno e alla fine ho concluso che ciò non ha mai influenzato i siti su HTTP, solo su HTTPS (ma non su tutti i siti HTTPS). Allora, qual è il problema?
Utilizzando Wireshark per analizzare il traffico di rete, ho provato a connettermi di nuovo a GitHub. Possiamo vedere che la connessione non è riuscita a stabilire a causa di un errore irreversibile, "Descrizione: versione protocollo".
Osservando le impostazioni predefinite in IE8, è abilitato solo TLS 1.0, ma GitHub ha abbandonato il supporto per TLSv1 e TLSv1.1 a febbraio 2018.
Ho selezionato le caselle per TLS 1.1 e TLS 1.2, ho ricaricato la pagina e — voilà! — Sono stato in grado di visualizzare GitHub!
Molte grazie al mio amico estremamente talentuoso Aidan Fewster per avermi aiutato a risolvere il problema.
Sono tutto per la compatibilità con le versioni precedenti, ma questo presenta un dilemma interessante. Secondo il PCI Security Standards Council, TLS 1.0 non è sicuro e non dovrebbe più essere utilizzato. Ma forzando TLS 1.1 o versioni successive, alcuni utenti verranno invariabilmente bloccati (e non tutti probabilmente saranno abbastanza esperti di tecnologia da abilitare TLS 1.2 nelle loro impostazioni avanzate).
Consentendo standard più vecchi e insicuri e consentendo agli utenti di continuare a connettersi ai nostri siti, non li stiamo aiutando: li stiamo danneggiando, non dando loro un motivo per passare a tecnologie più sicure. Quindi fino a che punto dovresti spingerti nel supportare i browser più vecchi?
Come posso iniziare a supportare i browser meno recenti?
Quando alcune persone pensano al "supporto dei browser più vecchi", potrebbero pensare a quei vecchi hack proprietari per IE, come quella volta che la BBC ha dovuto fare alcune cose incredibilmente nodose per supportare i contenuti iframe in IE7.
Oppure potrebbero pensare di far funzionare le cose nella "modalità stranezze" di Internet Explorer; una modalità operativa specifica di IE che rende le cose molto diverse dagli standard.
Ma "supportare browser più vecchi" è molto diverso da "hackerarlo per IE". Non sostengo il secondo, ma dovremmo pragmaticamente provare a fare il primo. Il mantra che cerco di vivere come sviluppatore web è questo:
"Ottimizza per la maggioranza, fai uno sforzo per la minoranza e non sacrificare mai la sicurezza".
Ora mi allontanerò dal mondo di IE8 e parlerò di soluzioni generali e sostenibili per il supporto dei browser legacy.
Esistono due strategie generali per supportare i browser meno recenti, entrambe che iniziano con P:
- Poliriempimento
Cerca di ottenere la parità di funzionalità per tutti compilando la funzionalità del browser mancante. - Miglioramento progressivo
Inizia da un'esperienza di base, quindi utilizza il rilevamento delle funzionalità per aggiungere funzionalità.
Queste strategie non si escludono a vicenda; possono essere usati in tandem. Ci sono una serie di decisioni di implementazione da prendere in entrambi gli approcci, ognuna con le proprie sfumature, che tratterò più dettagliatamente di seguito.
Poliriempimento
Per alcuni siti Web o pagine Web, JavaScript è molto importante per la funzionalità e desideri semplicemente fornire JavaScript funzionante al maggior numero possibile di browser.
Ci sono diversi modi per farlo, ma prima una lezione di storia.
Una breve storia di ECMAScript
ECMAScript è uno standard e JavaScript è un'implementazione di tale standard. Ciò significa che ES5 è "ECMAScript versione 5" e ES6 è "ECMAScript versione 6". In modo confuso, ES2015 è lo stesso di ES6.
ES6 era il nome diffuso di quella versione prima del suo rilascio, ma ES2015 è il nome ufficiale e le successive versioni di ECMAScript sono tutte associate all'anno di rilascio.
Nota : tutto questo è stato spiegato in modo utile da Brandon Morelli in un ottimo post sul blog che spiega la storia completa delle versioni JavaScript.
Al momento della stesura, l'ultimo standard è ES2018 (ES9). La maggior parte dei browser moderni supporta almeno ES2015. Quasi tutti i browser supportano ES5.
Tecnicamente IE8 non è ES5. Non è nemmeno ES4 (che non esiste — il progetto è stato abbandonato). IE8 utilizza l'implementazione Microsoft di ECMAScript 3, denominata JScript. IE8 ha un supporto per ES5 ma è stato rilasciato pochi mesi prima della pubblicazione degli standard ES5, quindi ha una mancata corrispondenza del supporto.
Transpiling vs Polyfilling
Puoi scrivere JavaScript ES5 e verrà eseguito in quasi tutti i browser antichi:
var foo = function () { return 'this is ES5!'; };
Puoi anche continuare a scrivere tutto il tuo JavaScript in questo modo, per abilitare la compatibilità con le versioni precedenti per sempre. Ma ti perderesti le nuove funzionalità e lo zucchero sintattico che è diventato disponibile nelle versioni in evoluzione di JavaScript, permettendoti di scrivere cose come:
const foo = () => { return 'this is ES6!'; };
Prova a eseguire quel JavaScript in un browser più vecchio e si verificherà un errore. Abbiamo bisogno di transpilare il codice in una versione precedente di JavaScript che il browser capirà (ovvero convertire il nostro codice ES6 in ES5, usando strumenti automatizzati).
Ora supponiamo che il nostro codice utilizzi un metodo ES5 standard, come Array.indexOf
. La maggior parte dei browser ha un'implementazione nativa di questo e funzionerà bene, ma IE8 si romperà. Ricordi che IE8 è stato rilasciato pochi mesi prima della pubblicazione degli standard ES5, quindi c'è una mancata corrispondenza del supporto? Un esempio è la funzione indexOf
, che è stata implementata per String
ma non per Array
.
Se proviamo a eseguire il metodo Array.indexOf
in IE8, fallirà. Ma se stiamo già scrivendo in ES5, cos'altro possiamo fare?
Possiamo polyfill il comportamento del metodo mancante. Gli sviluppatori tradizionalmente compilano in polyfill ogni funzionalità di cui hanno bisogno copiando e incollando il codice o inserendo librerie di polyfill esterne di terze parti. Molte funzionalità JavaScript hanno buone implementazioni di polyfill nella rispettiva pagina MDN di Mozilla, ma vale la pena sottolineare che esistono diversi modi per eseguire il polyfill della stessa funzione.
Ad esempio, per assicurarti di poter utilizzare il metodo Array.indexOf
in IE8, devi copiare e incollare un polyfill come questo:
if (!Array.prototype.indexOf) { Array.prototype.indexOf = (function (Object, max, min) { // big chunk of code that replicates the behaviour in JavaScript goes here! // for full implementation, visit: // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexof#Polyfill })(Object, Math.max, Math.min); }
Finché chiami polyfill prima di inserire uno qualsiasi dei tuoi JS e a condizione che non utilizzi alcuna funzionalità JavaScript ES5 diversa da Array.indexOf
, la tua pagina funzionerebbe in IE8.
I Polyfill possono essere utilizzati per collegare tutti i tipi di funzionalità mancanti. Ad esempio, ci sono polyfill per abilitare i selettori CSS3 come :last-child
(non supportato in IE8) o l'attributo placeholder
(non supportato in IE9).
I polyfill variano per dimensioni ed efficacia e talvolta hanno dipendenze da librerie esterne come jQuery.
Potresti anche sentire parlare di "spessori" piuttosto che di "poliriempimenti". Non rimanere troppo attaccato alla denominazione: le persone usano i due termini in modo intercambiabile. Ma tecnicamente parlando, uno shim è un codice che intercetta una chiamata API e fornisce un livello di astrazione. Un polyfill è un tipo di shim , nel browser . Utilizza specificamente JavaScript per adattare le nuove funzionalità HTML/CSS/JS nei browser meno recenti.
Riepilogo della strategia "importazione manuale dei polyfill":
- Controllo completo sulla scelta dei polyfill;
- Adatto per siti Web di base;
- ️ Senza strumenti aggiuntivi, sei costretto a scrivere in JavaScript nativo ES5;
- ️ Difficile microgestire tutti i tuoi polyfill;
- ️ Immediatamente, tutti i tuoi utenti riceveranno i polyfill, indipendentemente dal fatto che ne abbiano bisogno o meno.
Babele Polyfill
Ho parlato del trasferimento del codice ES6 fino a ES5. Lo fai usando un transpiler , il più popolare dei quali è Babel.
Babel è configurabile tramite un file .babelrc
nella radice del tuo progetto. In esso, indichi vari plug-in e preset di Babel. In genere ce n'è uno per ogni trasformazione della sintassi e polyfill del browser di cui avrai bisogno.
La microgestione di questi e tenerli sincronizzati con l'elenco di supporto del browser può essere una seccatura, quindi l'impostazione standard al giorno d'oggi è delegare quella microgestione al modulo @babel/preset-env. Con questa configurazione, fornisci semplicemente a Babel un elenco di versioni del browser che desideri supportare e fa il duro lavoro per te:
{ "presets": [ [ "@babel/preset-env", { "useBuiltIns": "usage", "targets": { "chrome": "58", "ie": "11" } } ] ] }
L'opzione di configurazione useBuiltIns
di @babel/preset-env
è dove avviene la magia, in combinazione con import "@babel/polyfill"
(un altro modulo) nel punto di ingresso della tua applicazione.
- Se omesso,
useBuiltIns
non fa nulla. L'intero@babel/polyfill
è incluso nella tua app, che è piuttosto pesante. - Quando è impostato su
"entry"
, converte l'importazione@babel/polyfill
in più importazioni più piccole, importando i polyfill minimi richiesti per il polyfill dei browser target che hai elencato nel tuo.babelrc
(in questo esempio, Chrome 58 e IE 11) . - L'impostazione su
"usage"
fa un ulteriore passo avanti eseguendo l'analisi del codice e importando solo i polyfill per le funzionalità che vengono effettivamente utilizzate . È classificato come "sperimentale" ma pecca per "polifill troppo" piuttosto che "troppo poco". In ogni caso, non vedo come sia possibile che crei un pacchetto più grande di"entry"
ofalse
, quindi è una buona opzione da scegliere (ed è il modo in cui stiamo andando alla BBC).
Usando Babel, puoi transpilare e compilare il tuo JavaScript prima di distribuirlo alla produzione e indirizzare il supporto in una specifica linea di base minima di browser. NB, un altro strumento popolare è TypeScript, che ha un proprio transpiler che esegue la transpilazione in ES3, in teoria supporta IE8 pronto all'uso.
Riepilogo dell'utilizzo di @babel/preset-env
per il polyfilling:
- Delegare la microgestione dei polyfill a uno strumento;
- Lo strumento automatizzato aiuta a prevenire l'inclusione di polyfill non necessari;
- Scala a siti più grandi e complessi;
- ️ Fuori dagli schemi, tutti i tuoi utenti riceveranno i polyfill, indipendentemente dal fatto che ne abbiano bisogno o meno;
- ️ Difficile tenere d'occhio esattamente ciò che viene inserito nel pacchetto dell'applicazione.
Polyfill a caricamento lento con Webpack e importazioni dinamiche
È possibile sfruttare la nuova proposta import()
per rilevare le funzionalità e scaricare dinamicamente i polyfill prima di inizializzare l'applicazione. In pratica assomiglia a questo:
import app from './app.js'; const polyfills = []; if (!window.fetch) { polyfills.push(import(/* webpackChunkName: "polyfill-fetch" */ 'whatwg-fetch')); } Promise.all(polyfills) .then(app) .catch((error) => { console.error('Failed fetching polyfills', error); });
Questo codice di esempio è stato copiato spudoratamente dall'ottimo articolo "Lazy Loading Polyfills With Webpack And Dynamic Imports" che approfondisce la tecnica in modo più dettagliato.
Sommario:
- Non gonfia i browser moderni con polyfill non necessari;
- ️ Richiede la gestione manuale di ogni polyfill.
polifill.io
polyfill.io è polyfilling as a service, creato dal Financial Times. Funziona in base alla tua pagina effettuando una singola richiesta di script a polyfill.io, elencando facoltativamente le funzionalità specifiche di cui hai bisogno per polyfill. Il loro server analizza quindi la stringa dell'agente utente e popola lo script di conseguenza. Ciò ti evita di dover fornire manualmente le tue soluzioni di polyfill.
Ecco il JavaScript che polyfill.io restituisce per una richiesta effettuata da IE8:
Ecco la stessa richiesta di polyfill.io, ma dove la richiesta proveniva dal moderno Chrome:
Tutto ciò che è richiesto dal tuo sito è una singola chiamata allo script.
Sommario:
- Facilità di inclusione nella tua app web;
- Delega la responsabilità della conoscenza di polyfill a terzi;
- ️ D'altra parte, ora fai affidamento su un servizio di terze parti;
- ️ Effettua una chiamata
<script>
di blocco, anche per i browser moderni che non necessitano di polyfill.
Miglioramento progressivo
Il polyfilling è una tecnica incredibilmente utile per supportare i browser meno recenti, ma può essere un problema per le pagine Web ed ha una portata limitata.
La tecnica del miglioramento progressivo, d'altra parte, è un ottimo modo per garantire un'esperienza di base per tutti i browser, pur mantenendo la piena funzionalità per i tuoi utenti sui browser moderni. Dovrebbe essere realizzabile sulla maggior parte dei siti.
Il principio è questo: partire da una linea di base di HTML (e stile, facoltativo) e "migliorare progressivamente" la pagina con la funzionalità JavaScript. Il vantaggio è che se il browser è legacy o se il JavaScript viene interrotto in qualsiasi momento della sua consegna, il tuo sito dovrebbe essere ancora funzionante.
Il termine "miglioramento progressivo" è spesso usato in modo intercambiabile con "JavaScript discreto". Significano essenzialmente la stessa cosa, ma quest'ultimo si spinge un po' oltre in quanto non dovresti sporcare il tuo HTML con molti attributi, ID e classi che vengono utilizzati solo dal tuo JavaScript.
Taglia-la-senape
La tecnica BBC di "taglio della senape" (CTM) è un'implementazione collaudata di miglioramento progressivo. Il principio è che si scrive una solida esperienza di base dell'HTML e, prima di scaricare qualsiasi JavaScript migliorato, si verifica un livello minimo di supporto. L'implementazione originale ha verificato la presenza di funzionalità HTML5 standard:
if ('querySelector' in document && 'localStorage' in window && 'addEventListener' in window) { // Enhance for HTML5 browsers }
Man mano che escono nuove funzionalità e browser più vecchi diventano sempre più antiquati, i nostri tagli alla linea di base della senape cambieranno. Ad esempio, la nuova sintassi JavaScript come le funzioni della freccia ES6 significherebbe che questo controllo CTM in linea non riesce nemmeno ad analizzare nei browser legacy, nemmeno l'esecuzione in sicurezza e il fallimento del controllo CTM, quindi potrebbe avere effetti collaterali imprevisti come la rottura di altri JavaScript di terze parti (es. Google Analytics).
Per evitare anche di tentare di analizzare il JS moderno non tradotto, possiamo applicare questa "interpretazione moderna" della tecnica CTM, tratta dal blog di @snugug, in cui sfruttiamo il fatto che i browser più vecchi non capiscono il type="module"
dichiarazione e la salterà in sicurezza. Al contrario, i browser moderni ignoreranno le dichiarazioni <script nomodule>
.
<script type="module" src="./mustard.js"></script> <script nomodule src="./no-mustard.js"></script> <!-- Can be done inline too --> <script type="module"> import mustard from './mustard.js'; </script> <script nomodule type="text/javascript"> console.log('No Mustard!'); </script>
Questo approccio è buono, a condizione che tu sia felice di trattare i browser ES6 come la tua nuova linea di base minima per la funzionalità (~ 92% dei browser globali al momento della scrittura).
Tuttavia, proprio come il mondo di JavaScript si sta evolvendo, così è il mondo dei CSS. Ora che abbiamo Grid, Flexbox, variabili CSS e simili (ciascuna con una diversa efficacia di fallback), non si può dire quale combinazione di supporto CSS potrebbe avere un vecchio browser che potrebbe portare a un miscuglio di "moderno" e "legacy" styling, il cui risultato sembra rotto. Pertanto, i siti scelgono sempre più di CTM il loro stile , quindi ora l'HTML è la linea di base principale e sia CSS che JS sono trattati come miglioramenti.
Le tecniche CTM basate su JavaScript che abbiamo visto finora presentano un paio di aspetti negativi se si utilizza la presenza di JavaScript per applicare CSS in qualsiasi modo:
- JavaScript in linea sta bloccando. I browser devono scaricare, analizzare ed eseguire JavaScript prima di ottenere qualsiasi stile. Pertanto, gli utenti potrebbero vedere un lampo di testo senza stile.
- Alcuni utenti potrebbero avere browser moderni, ma scelgono di disabilitare JavaScript. Un CTM basato su JavaScript impedisce loro di ottenere un sito con uno stile anche quando sono perfettamente in grado di ottenerlo.
L'approccio "definitivo" consiste nell'utilizzare le query multimediali CSS come test al tornasole della senape. Questa tecnica "CSSCTM" è attivamente utilizzata su siti come Springer Nature.
<head> <!-- CSS-based cuts-the-mustard --> <!-- IMPORTANT: the JS depends on having this rule somewhere in the CSS: `body { clear: both }` --> <link rel="stylesheet" href="mq-test.css" media="only screen and (min-resolution: 0.1dpcm), only screen and (-webkit-min-device-pixel-ratio:0) and (min-color-index:0)"> </head> <body> <!-- content here... --> <script> (function () { // wrap in an IIFE to prevent global scope pollution function isSupported () { var val = ''; if (window.getComputedStyle) { val = window.getComputedStyle(document.body, null).getPropertyValue('clear'); } else if (document.body.currentStyle) { val = document.body.currentStyle.clear; } if (val === 'both') { // references the `body { clear: both; }` in the CSS return true; } return false; } if (isSupported()) { // Load or run JavaScript for supported browsers here. } })(); </script> </body>
Questo approccio è piuttosto fragile: sovrascrivere accidentalmente la proprietà clear
sul selettore del body
potrebbe "rompere" il tuo sito, ma offre le migliori prestazioni. Questa particolare implementazione utilizza media query che sono supportate solo in almeno IE 9, iOS 7 e Android 4.4, che è una linea di base moderna abbastanza ragionevole.
“Taglia la senape”, in tutte le sue diverse declinazioni, assolve due principi fondamentali:
- Supporto utenti diffuso;
- Sforzo di sviluppo applicato in modo efficiente.
Semplicemente non è possibile per i siti ospitare ogni singola combinazione di browser/sistema operativo/connessione di rete/configurazione utente. Tecniche come il cut-the-mostard aiutano a razionalizzare i browser in browser di grado C e A, secondo il modello Graded Browser Support di Yahoo! .
Cuts-The-Mustard: un anti-modello?
C'è un argomento secondo cui applicare una decisione binaria globale di "core" vs "avanzato" non è la migliore esperienza possibile per i nostri utenti. Fornisce sanità mentale a un problema tecnico altrimenti scoraggiante, ma cosa succede se un browser supporta il 90% delle funzionalità nel test CTM globale e questa pagina specifica non utilizza nemmeno il 10% delle funzionalità su cui non riesce? In questo caso, l'utente otterrebbe l'esperienza di base, poiché il controllo del marchio comunitario sarebbe fallito. Ma avremmo potuto dare loro l'esperienza completa.
E che dire dei casi in cui una determinata pagina utilizza una funzionalità che il browser non supporta? Bene, nel passaggio alla componentizzazione, potremmo avere un fallback specifico per la funzionalità (o limite di errore), piuttosto che un fallback a livello di pagina.
Lo facciamo ogni giorno nel nostro sviluppo web. Pensa a inserire un font web; browser diversi hanno diversi livelli di supporto dei caratteri. Cosa facciamo? Forniamo alcune varianti di file di font e lasciamo che sia il browser a decidere quale scaricare:
@font-face { font-family: FontName; src: url('path/filename.eot'); src: url('path/filename.eot?#iefix') format('embedded-opentype'), url('path/filename.woff2') format('woff2'), url('path/filename.woff') format('woff'), url('path/filename.ttf') format('truetype'); }
Abbiamo un fallback simile con il video HTML5. I browser moderni sceglieranno il formato video che desiderano utilizzare, mentre i browser legacy che non capiscono cosa sia un elemento <video>
renderanno semplicemente il testo di fallback:
<video width="400" controls> <source src="mov_bbb.mp4" type="video/mp4"> <source src="mov_bbb.ogg" type="video/ogg"> Your browser does not support HTML5 video. </video>
L'approccio di nidificazione che abbiamo visto in precedenza utilizzato dalla BBC per i fallback PNG per SVG è la base per l'elemento dell'immagine reattiva <picture>
. I browser moderni renderanno l'immagine più adatta in base all'attributo media
fornito, mentre i browser legacy che non comprendono cosa sia un elemento <picture>
renderanno il fallback <img>
.
<picture> <source media="(min-width: 650px)"> <source media="(min-width: 465px)"> <img src="img_orange_flowers.jpg" alt="Flowers"> </picture>
Le specifiche HTML si sono evolute con attenzione nel corso degli anni per fornire un meccanismo di fallback di base per tutti i browser, consentendo allo stesso tempo funzionalità e ottimizzazioni per i browser moderni che le comprendono.
Potremmo applicare un principio simile al nostro codice JavaScript. Immagina una funzionalità del genere, in cui il metodo foo
contiene alcuni JS complessi:
class Feature { browserSupported() { return ('querySelector' in document); // internal cuts-the-mustard goes here } foo() { // etc } } export default new Feature();
Prima di chiamare foo
, controlliamo se la funzionalità è supportata in questo browser chiamando il relativo metodo browserSupported
. Se non è supportato, non tentiamo nemmeno di chiamare il codice che altrimenti avrebbe sbagliato la nostra pagina.
import Feature from './feature'; if (Feature.browserSupported()) { Feature.foo(); }
Questa tecnica significa che possiamo evitare di inserire i polyfill e andare semplicemente con ciò che è supportato nativamente da ogni singolo browser, degradando con grazia le singole funzionalità se non supportate.
Si noti che nell'esempio sopra, presumo che il codice venga transpilato in ES5 in modo che la sintassi sia compresa da tutti i browser, ma non presumo che il codice sia polyfilled . Se volessimo evitare di transpilare il codice, potremmo applicare lo stesso principio ma usando il type="module"
per tagliare la senape, ma viene fornito con l'avvertenza che ha già un requisito minimo del browser ES6, quindi è solo probabilmente comincerà ad essere una buona soluzione tra un paio d'anni:
<script type="module"> import Feature from './feature.js'; if (Feature.browserSupported()) { Feature.foo(); } </script>
Abbiamo coperto HTML e abbiamo coperto JavaScript. Possiamo applicare fallback localizzati anche nei CSS; c'è una parola chiave @supports
nei CSS, che ti permette di applicare condizionalmente CSS in base alla presenza o assenza di supporto per una funzione CSS. Tuttavia, è ironicamente ammonito dal fatto che non è universalmente supportato. Ha solo bisogno di un'applicazione attenta; c'è un ottimo post sul blog di Mozilla su come utilizzare le query di funzionalità nei CSS.
In un mondo ideale, non dovremmo aver bisogno di un controllo globale per tagliare la senape. Invece, ogni singola funzione HTML, JS o CSS dovrebbe essere autonoma e avere i propri limiti di errore. In un mondo di componenti web, DOM ombra ed elementi personalizzati, mi aspetto che vedremo più di un passaggio a questo tipo di approccio. Ma rende molto più difficile prevedere e testare il tuo sito nel suo insieme e potrebbero esserci effetti collaterali indesiderati se, ad esempio, lo stile di un componente influisce sul layout di un altro.
Due principali strategie di compatibilità con le versioni precedenti
Una sintesi del polyfilling come strategia :
- Può fornire funzionalità JS lato client alla maggior parte degli utenti.
- Può essere più semplice codificare quando si delega il problema della compatibilità con le versioni precedenti a un polyfill.
- ️ A seconda dell'implementazione, potrebbe essere dannoso per le prestazioni degli utenti che non necessitano di polyfill.
- ️ A seconda della complessità dell'applicazione e dell'età del browser, potrebbe richiedere molti polyfill e quindi funzionare molto male. Rischiamo di spedire megabyte di polyfill ai browser meno preparati ad accettarlo.
Una sintesi del miglioramento progressivo come strategia :
- Il marchio tradizionale cinese semplifica la segmentazione del codice e il test manuale.
- Base di esperienza garantita per tutti gli utenti.
- ️ Potrebbe fornire inutilmente l'esperienza di base agli utenti che potrebbero gestire l'esperienza avanzata.
- ️ Non adatto a siti che richiedono JS lato client per la funzionalità.
- ️ A volte difficile bilanciare una solida strategia di miglioramento progressivo con un primo rendering performante. C'è il rischio di dare priorità eccessiva all'esperienza "core" a scapito del 90% dei tuoi utenti che ottengono l'esperienza "completa" (ad es. fornendo piccole immagini per noJS e quindi sostituendo con immagini ad alta risoluzione su lazy-load hanno sprecato molta capacità di download su risorse che non sono mai state nemmeno visualizzate).
Conclusione
IE8 una volta era un browser all'avanguardia. (No, sul serio.) Lo stesso si potrebbe dire per Chrome e Firefox oggi.
Se i siti Web di oggi sono totalmente inutilizzabili in IE8, è probabile che i siti Web tra dieci anni saranno inutilizzabili nei browser moderni di oggi, nonostante siano basati sulle tecnologie aperte di HTML, CSS e JavaScript.
Fermati e pensaci un momento. Non è un po' spaventoso? (Detto questo, se non puoi abbandonare i browser dopo dieci anni e dopo che l'azienda che lo ha costruito lo ha deprecato, quando puoi?)
IE8 è il capro espiatorio di oggi. Domani sarà IE9, l'anno prossimo sarà Safari, un anno dopo potrebbe essere Chrome. Puoi sostituire IE8 con il "vecchio browser preferito". Il punto è che ci sarà sempre una certa divisione tra i browser per i quali gli sviluppatori costruiscono e i browser utilizzati dalle persone. Dovremmo smettere di deriderlo e iniziare a investire in soluzioni ingegneristiche solide e inclusive . Gli effetti collaterali di queste strategie tendono a pagare dividendi in termini di accessibilità, prestazioni e resilienza della rete, quindi c'è un quadro più ampio in gioco qui.
Tendiamo a non pensare ai numeri degli screen reader. Diamo semplicemente per scontato che sia moralmente giusto fare del nostro meglio per supportare gli utenti che non hanno altro modo di consumare i nostri contenuti, non per colpa nostra. Lo stesso principio si applica alle persone che utilizzano browser meno recenti.
Abbiamo trattato alcune strategie di alto livello per la creazione di siti robusti che dovrebbero continuare a funzionare, in una certa misura, su un ampio spettro di browser legacy e moderni.
Ancora una volta, un disclaimer: non hackerare le cose per IE. Questo mancherebbe il punto. Ma tieni presente che tutti i tipi di persone usano tutti i tipi di browser per tutti i tipi di motivi e che ci sono alcuni solidi approcci ingegneristici che possiamo adottare per rendere il Web accessibile a tutti.
Ottimizza per la maggioranza, fai uno sforzo per la minoranza e non sacrificare mai la sicurezza.
Ulteriori letture su SmashingMag:
- Standard Web: cosa, perché e come
- Smart Bundling: come fornire codice legacy solo a browser legacy
- Non utilizzare l'attributo segnaposto
- Progettare per un Web senza browser