Distribuire applicazioni veloci e leggere con il risparmio di dati

Dave Gash
Dave Gash
Ilya Grigorik
Ilya Grigorik

L'Save-Data client hint request header disponibile nei browser Chrome, Opera e Yandex consente agli sviluppatori di offrire applicazioni più leggere e rapide agli utenti che attivano la modalità di risparmio dati nel browser.

La necessità di pagine leggere

Statistiche di Weblight

Tutti sono d'accordo sul fatto che pagine web più veloci e leggere offrono un'esperienza utente più soddisfacente, consentono una migliore comprensione e memorizzazione dei contenuti e generano un aumento delle conversioni e delle entrate. La ricerca di Google ha dimostrato che "…le pagine ottimizzate vengono caricate quattro volte più velocemente rispetto alla pagina originale e utilizzano l'80% in meno di byte. Dato che il caricamento avviene molto più velocemente, abbiamo riscontrato il 50% in più di traffico verso queste pagine".

Inoltre, anche se il numero di connessioni 2G è finalmente in declino, nel 2015 il 2G era ancora la tecnologia di rete dominante. La penetrazione e la disponibilità delle reti 3G e 4G sono in rapida crescita, ma i costi di proprietà associati e i vincoli della rete sono ancora un fattore significativo per centinaia di milioni di utenti.

Si tratta di argomenti validi a favore dell'ottimizzazione delle pagine.

Esistono metodi alternativi per migliorare la velocità del sito senza il coinvolgimento diretto degli sviluppatori, come i browser proxy e i servizi di transcodifica. Sebbene questi servizi siano molto apprezzati, presentano notevoli svantaggi: compressione semplice (e a volte inaccettabile) di immagini e testo, impossibilità di elaborare pagine sicure (HTTPS), ottimizzazione solo delle pagine visitate tramite un risultato di ricerca e altro ancora. La popolarità stessa di questi servizi è un indicatore del fatto che gli sviluppatori web non stanno rispondendo adeguatamente all'elevata domanda degli utenti di pagine e applicazioni rapide e leggere. Tuttavia, raggiungere questo obiettivo è un percorso complesso e a volte difficile.

L'intestazione della richiesta Save-Data

Una tecnica abbastanza semplice è lasciare che sia il browser ad aiutarti, utilizzando l'intestazione della richiesta Save-Data. Identificando questo intestazione, una pagina web può personalizzare e offrire un'esperienza utente ottimizzata agli utenti con vincoli di costi e prestazioni.

I browser supportati (di seguito) consentono all'utente di attivare una modalità di risparmio dati che consente al browser di applicare un insieme di ottimizzazioni per ridurre la quantità di dati richiesti per il rendering della pagina. Quando questa funzionalità è esposta o pubblicizzata, il browser potrebbe richiedere immagini a risoluzione inferiore, posticipare il caricamento di alcune risorse o inoltrare le richieste tramite un servizio che applica altre ottimizzazioni specifiche dei contenuti, come la compressione delle risorse di testo e immagine.

Supporto browser

  • Chrome 49 e versioni successive pubblicizza Save-Data quando l'utente attiva l'opzione "Risparmio dati" su dispositivi mobili o l'estensione "Risparmio dati" sui browser desktop.
  • Opera 35 e versioni successive pubblicizza Save-Data quando l'utente attiva la modalità "Opera Turbo" su computer o l'opzione "Risparmio dati" sui browser Android.
  • Yandex 16.2 e versioni successive pubblicizza Save-Data quando la modalità Turbo è attivata su browser desktop o dispositivi mobili.

Rilevamento dell'impostazione Save-Data

Per determinare quando offrire l'esperienza "light" agli utenti, la tua applicazione può verificare l'intestazione della richiesta di suggerimento client Save-Data. Questa intestazione della richiesta indica la preferenza del cliente per un utilizzo ridotto dei dati a causa di costi di trasferimento elevati, velocità di connessione lente o altri motivi.

Quando l'utente attiva la modalità di risparmio dati nel browser, quest'ultimo aggiunge l'intestazione della richiesta Save-Data a tutte le richieste in uscita (sia HTTP che HTTPS). Al momento della stesura di questo articolo, il browser pubblicizza un solo token *on nell'intestazione (Save-Data: on), ma in futuro questo potrebbe essere esteso per indicare altre preferenze dell'utente.

Inoltre, è possibile rilevare se Save-Data è attivato in JavaScript:

if ('connection' in navigator) {
  if (navigator.connection.saveData === true) {
    // Implement data saving operations here.
  }
}

È fondamentale verificare la presenza dell'oggetto connection all'interno dell'oggetto navigator, in quanto rappresenta l'API Network Information, che è implementata solo nei browser Chrome, Chrome per Android e Samsung Internet. Da lì, devi solo controllare se navigator.connection.saveData è uguale a true e puoi implementare qualsiasi operazione di salvataggio dei dati in quella condizione.

L'intestazione Save-Data visualizzata negli Strumenti per sviluppatori di Chrome, insieme all'estensione Risparmio dati.
Attivare l'estensione Risparmio dati in Chrome per computer.

Se la tua applicazione utilizza un worker di servizio, può esaminare le intestazioni delle richieste e applicare la logica pertinente per ottimizzare l'esperienza. In alternativa, il server può cercare le preferenze pubblicizzate nell'Save-Data header della richiesta e restituire una risposta alternativa, ad esempio markup diverso, immagini e video più piccoli e così via.

Suggerimenti e best practice per l'implementazione

  1. Quando utilizzi Save-Data, fornisci alcuni dispositivi di interfaccia utente che lo supportano e consenti agli utenti di passare facilmente da un'esperienza all'altra. Ad esempio:
    • Comunica agli utenti che Save-Data è supportato e incoraggiali a utilizzarlo.
    • Consenti agli utenti di identificare e scegliere la modalità con prompt appropriati e pulsanti di attivazione/disattivazione o caselle di controllo intuitive.
    • Quando è selezionata la modalità di risparmio dati, annuncia e fornisci un modo semplice e intuitivo per disattivarla e ripristinare l'esperienza completa, se vuoi.
  2. Ricorda che le applicazioni leggere non sono applicazioni di qualità inferiore. Non omettono funzionalità o dati importanti, ma sono più consapevoli dei costi e dell'esperienza utente. Ad esempio:
    • Un'applicazione di galleria fotografica potrebbe fornire anteprime a risoluzione inferiore o utilizzare un meccanismo di carosello meno complesso.
    • Un'applicazione di ricerca potrebbe restituire meno risultati alla volta, limitare il numero di risultati con contenuti multimediali o ridurre il numero di dipendenze necessarie per visualizzare la pagina.
    • Un sito di notizie potrebbe mostrare meno notizie, omettere categorie meno popolari o fornire anteprime dei contenuti multimediali più piccole.
  3. Fornisci la logica del server per verificare l'intestazione della richiesta Save-Data e valuta la possibilità di fornire una risposta di pagina alternativa e più leggera quando è attivata, ad esempio ridurre il numero di risorse e dipendenze richieste, applicare una compressione delle risorse più aggressiva e così via.
    • Se pubblichi una risposta alternativa in base all'intestazione Save-Data, ricordati di aggiungerla all'elenco Vary (Vary: Save-Data) per indicare alle cache a monte di memorizzare nella cache e pubblicare questa versione solo se è presente l'intestazione della richiesta Save-Data. Per maggiori dettagli, consulta le best practice per l'interazione con le cache.
  4. Se utilizzi un worker di servizio, la tua applicazione può rilevare quando l'opzione di salvataggio dei dati è attivata controllando la presenza dell'intestazione della richiesta Save-Data o il valore della proprietà navigator.connection.saveData. Se è attivata, valuta se puoi riscrivere la richiesta per recuperare meno byte o utilizzare una risposta già recuperata.
  5. Valuta la possibilità di integrare Save-Data con altri indicatori, ad esempio informazioni sul tipo di connessione e sulla tecnologia dell'utente (vedi API NetInfo). Ad esempio, potresti voler offrire l'esperienza leggera a qualsiasi utente su una connessione 2G anche se Save-Data non è abilitato. Al contrario, il fatto che l'utente utilizzi una connessione 4G "veloce" non significa che non sia interessato a risparmiare dati, ad esempio in roaming. Inoltre, puoi aumentare la presenza di Save-Data con l'indicazione del client Device-Memory per adattarti ulteriormente agli utenti su dispositivi con memoria limitata. La memoria del dispositivo dell'utente viene pubblicizzata anche nel navigator.deviceMemory client hint.

Ricette

Ciò che puoi ottenere tramite Save-Data è limitato solo alla tua immaginazione. Per farti un'idea di cosa è possibile fare, diamo un'occhiata a un paio di casi d'uso. Mentre leggi, potresti trovare altri casi d'uso, quindi non esitare a fare esperimenti e scoprire cosa è possibile.

Verifica della presenza di Save-Data nel codice lato server

Sebbene lo stato Save-Data sia qualcosa che puoi rilevare in JavaScript tramite la proprietà navigator.connection.saveData, a volte è preferibile rilevarlo lato server. In alcuni casi, l'esecuzione di JavaScript può non riuscire. Inoltre, il rilevamento lato server è l'unico modo per modificare il markup prima che venga inviato al client, che è coinvolto in alcuni dei casi d'uso più vantaggiosi di Save-Data.

La sintassi specifica per rilevare l'intestazione Save-Data nel codice lato server dipende dal linguaggio utilizzato, ma l'idea di base dovrebbe essere la stessa per qualsiasi back-end dell'applicazione. In PHP, ad esempio, le intestazioni delle richieste vengono archiviate nell'array superglobale $_SERVER agli indici che iniziano con HTTP_. Ciò significa che puoi rilevare l'intestazione Save-Data controllando l'esistenza e il valore della variabile $_SERVER["HTTP_SAVE_DATA"] nel seguente modo:

// false by default.
$saveData = false;

// Check if the `Save-Data` header exists and is set to a value of "on".
if (isset($_SERVER["HTTP_SAVE_DATA"]) && strtolower($_SERVER["HTTP_SAVE_DATA"]) === "on") {
  // `Save-Data` detected!
  $saveData = true;
}

Se inserisci questo controllo prima che qualsiasi markup venga inviato al client, la variabile $saveData conterrà lo stato Save-Data e sarà disponibile ovunque per l'utilizzo nella pagina. Dopo aver illustrato questo meccanismo, diamo un'occhiata ad alcuni esempi di come possiamo utilizzarlo per limitare la quantità di dati inviati all'utente.

Pubblicare immagini a bassa risoluzione per schermi ad alta risoluzione

Un caso d'uso comune per le immagini sul web prevede la pubblicazione di immagini in insiemi di due: un'immagine per schermi "standard" (1x) e un'altra immagine di dimensioni doppie (2x) per schermi ad alta risoluzione (ad es. Display Retina). Questa classe di schermi ad alta risoluzione non è necessariamente limitata ai dispositivi di fascia alta e sta diventando sempre più comune. Se si preferisce un'esperienza di utilizzo più leggera, potrebbe essere opportuno inviare a questi schermi immagini a risoluzione inferiore (1x) anziché le varianti più grandi (2x). Per farlo, quando è presente l'intestazione Save-Data , modifichiamo semplicemente il markup inviato al cliente:

if ($saveData === true) {
  // Send a low-resolution version of the image for clients specifying `Save-Data`.
  ?><img src="butterfly-1x.jpg" alt="A butterfly perched on a flower."><?php
}
else {
  // Send the usual assets for everyone else.
  ?><img src="butterfly-1x.jpg" srcset="butterfly-2x.jpg 2x, butterfly-1x.jpg 1x" alt="A butterfly perched on a flower."><?php
}

Questo caso d'uso è un esempio perfetto di quanto sia poco impegnativo soddisfare una richiesta specifica di invio di meno dati. Se non ti piace modificare il markup sul back-end, puoi ottenere lo stesso risultato anche utilizzando un modulo di riscrittura dell'URL come mod_rewrite di Apache. Esistono esempi di come ottenere questo risultato con una configurazione relativamente ridotta.

Puoi anche estendere questo concetto alle proprietà background-image CSS semplicemente aggiungendo una classe all'elemento <html>:

<html class="<?php if ($saveData === true): ?>save-data<?php endif; ?>">

Da qui, puoi scegliere come target la classe save-data nell'elemento <html> nel CSS per modificare il modo in cui le immagini vengono pubblicate. Puoi inviare immagini di sfondo a bassa risoluzione su schermi ad alta risoluzione, come mostrato nell'esempio HTML riportato sopra, oppure omettere del tutto determinate risorse.

Ometti le immagini non essenziali

Alcuni contenuti delle immagini sul web non sono semplicemente essenziali. Sebbene queste immagini possano essere un piacevole diversivo per i contenuti, potrebbero non essere desiderabili per chi cerca di ottenere il massimo dai piani di dati con misurazione. In quello che è forse il caso d'uso più semplice di Save-Data, possiamo utilizzare il codice di rilevamento PHP precedente e omettere del tutto il markup delle immagini non essenziali:

<p>This paragraph is essential content. The image below may be humorous, but it's not critical to the content.</p>
<?php
if ($saveData === false) {
  // Only send this image if `Save-Data` hasn't been detected.
  ?><img src="meme.jpg" alt="One does not simply consume data."><?php
}

Questa tecnica può avere un effetto marcato, come puoi vedere nella figura riportata di seguito:

Un confronto tra le immagini non critiche caricate quando Save-Data non è presente e le stesse immagini omesse quando Save-Data è presente.
Un confronto tra le immagini non critiche caricate quando il parametro Save-Data non è presente e le stesse immagini omesse quando il parametro Save-Data è presente.

Naturalmente, l'omissione delle immagini non è l'unica possibilità. Puoi anche intervenire su Save-Data per rinunciare all'invio di altre risorse non critiche, come determinati caratteri.

Ometti i caratteri web non essenziali

Sebbene i caratteri web non costituiscano in genere la maggior parte del payload totale di una determinata pagina come spesso accade per le immagini, sono comunque molto apprezzati. Non consumano nemmeno una quantità significativa di dati. Inoltre, il modo in cui i browser recuperano e visualizzano i caratteri è più complicato di quanto si possa pensare, con concetti come FOIT, FOUT ed euristiche del browser che rendono il rendering un'operazione complessa.

È quindi logico che tu voglia escludere i caratteri web non essenziali per gli utenti che vogliono esperienze più snelle. Save-Data semplifica notevolmente questa operazione.

Ad esempio, supponiamo che tu abbia incluso Fira Sans di Google Fonts sul tuo sito. Fira Sans è un carattere eccellente per il corpo del testo, ma forse non è così importante per gli utenti che cercano di salvare i dati. Aggiungendo una classe save-data all'elemento <html> quando è presente l'intestazione Save-Data, possiamo scrivere stili che richiamano inizialmente il carattere non essenziale, ma poi lo disattivano quando è presente l'intestazione Save-Data:

/* Opt into web fonts by default. */
p,
li {
  font-family: 'Fira Sans', 'Arial', sans-serif;
}

/* Opt out of web fonts if the `save-Data` class is present. */
.save-data p,
.save-data li {
  font-family: 'Arial', sans-serif;
}

Con questo approccio, puoi lasciare invariato lo snippet <link> di Google Fonts, perché il browser carica in modo speculativo le risorse CSS (inclusi i caratteri web) applicando prima gli stili al DOM e poi controllando se gli elementi HTML richiamano una delle risorse nello stile foglio. Se qualcuno capita con Save-Data attivo, Fira Sans non verrà mai caricato perché il DOM con stile non lo invoca mai. Verrà invece attivata Arial. Non è bella come Fira Sans, ma potrebbe essere preferibile per gli utenti che cercano di risparmiare sui propri piani dati.

Riepilogo

L'intestazione Save-Data non ha molte sfumature: è attiva o disattivata e l'applicazione ha il compito di fornire esperienze appropriate in base alla sua impostazione, indipendentemente dal motivo.

Ad esempio, alcuni utenti potrebbero non consentire la modalità di risparmio dati se sospettano che si verifichi una perdita di contenuti o funzionalità dell'app, anche in caso di scarsa connettività. Al contrario, alcuni utenti potrebbero attivarla per impostazione predefinita per mantenere le pagine il più piccole e semplici possibile, anche in caso di buona connettività. È meglio che la tua app preveda che l'utente voglia un'esperienza completa e illimitata finché non hai un'indicazione chiara in merito tramite un'azione esplicita dell'utente.

In qualità di proprietari di siti e sviluppatori web, assumiamoci la responsabilità di gestire i nostri contenuti per migliorare l'esperienza utente per gli utenti con limitazioni di dati e costi.

Per maggiori dettagli su Save-Data ed eccellenti esempi pratici, consulta la sezione Aiutare gli utenti Save Data.