Distribuire applicazioni veloci e leggere con il risparmio di dati

Dave Gash
Dave Gash
Ignazio Barbieri
Ilya Grigorik

L'intestazione della richiesta di suggerimento client Save-Data disponibile nei browser Chrome, Opera e Yandex consente agli sviluppatori di offrire applicazioni più leggere e veloci agli utenti che attivano la modalità di risparmio dati nel browser.

La necessità di pagine leggere

Statistiche Weblight

Tutti concordano che pagine web più veloci e leggere offrono un'esperienza utente più soddisfacente, consentono una migliore comprensione e fidelizzazione dei contenuti e generano più conversioni ed entrate. Da ricerche di Google è emerso che "...le pagine ottimizzate si caricano quattro volte più velocemente della pagina originale e utilizzano l'80% in meno di byte. Poiché queste pagine si caricano molto più velocemente, abbiamo anche registrato un aumento del 50% del traffico verso queste pagine."

Inoltre, sebbene il numero di connessioni 2G sia finalmente in calo, il 2G è stata ancora la tecnologia di rete dominante nel 2015. La penetrazione e la disponibilità delle reti 3G e 4G stanno crescendo rapidamente, ma i costi di proprietà e i vincoli di rete associati sono ancora un fattore significativo per centinaia di milioni di utenti.

Questi sono argomenti validi per l'ottimizzazione della pagina.

Esistono metodi alternativi per migliorare la velocità del sito senza il coinvolgimento diretto dello sviluppatore, come i browser proxy e i servizi di transcodifica. Sebbene questi servizi siano molto diffusi, presentano svantaggi sostanziali: semplice (e talvolta inaccettabile) compressione di immagini e testo, impossibilità di elaborare pagine sicure (HTTPS), l'ottimizzazione solo delle pagine visitate tramite un risultato di ricerca e altro ancora. La stessa popolarità di questi servizi indica di per sé che gli sviluppatori web non stanno rispondendo correttamente all'elevata domanda da parte degli utenti di pagine e applicazioni veloci e leggere. Ma raggiungere questo obiettivo è un percorso complesso e a volte difficile.

Intestazione della richiesta Save-Data

Una tecnica abbastanza semplice è lasciare che il browser sia d'aiuto, utilizzando l'intestazione della richiesta Save-Data. Se identifichi questa intestazione, una pagina web può personalizzare e offrire un'esperienza utente ottimizzata a utenti con limiti di prestazioni e costi.

I browser supportati (di seguito) consentono all'utente di attivare una modalità *risparmio dati-che concede al browser l'autorizzazione ad applicare un insieme di ottimizzazioni per ridurre la quantità di dati necessari per visualizzare la pagina. Quando questa funzionalità viene esposta o pubblicizzata, il browser potrebbe richiedere immagini a risoluzione più bassa, posticipare il caricamento di alcune risorse o indirizzare le richieste tramite un servizio che applica altre ottimizzazioni specifiche per i contenuti, come la compressione di immagini e testo.

Supporto del browser

  • Chrome 49 e versioni successive pubblicizza Save-Data quando l'utente attiva l'opzione "Risparmio dati" sui dispositivi mobili o l'estensione "Risparmio dati" sui browser desktop.
  • Opera 35+ 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 sui computer o sui browser mobile.

Rilevamento dell'impostazione Save-Data in corso...

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

Quando l'utente attiva la modalità di salvataggio dei 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 solo un token *on nell'intestazione (Save-Data: on), ma in futuro questo potrebbe essere esteso per indicare le preferenze di altri utenti.

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

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

Verificare la presenza dell'oggetto connection all'interno dell'oggetto navigator è fondamentale, poiché rappresenta l'API Network Information, che viene implementata solo nei browser internet Chrome, Chrome per Android e Samsung. Da qui, devi solo verificare se navigator.connection.saveData è uguale a true e puoi implementare qualsiasi operazione di salvataggio dei dati in questa condizione.

L'intestazione Salva dati mostrata negli Strumenti per sviluppatori di Chrome mostrata insieme all'estensione Risparmio dati.
Attivazione dell'estensione Risparmio dati nella versione desktop di Chrome.

Se l'applicazione utilizza un service worker, 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'intestazione della richiesta Save-Data e restituire una risposta alternativa, con markup diverso, immagini e video più piccoli e così via.

Suggerimenti per l'implementazione e best practice

  1. Quando utilizzi Save-Data, fornisci alcuni dispositivi UI che lo supportano e consentano 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 intuitivi.
    • Quando è selezionata la modalità Risparmio dati, annuncia e fornisci un modo facile e chiaro per disattivarla e, se vuoi, ripristinare l'esperienza completa.
  2. Ricorda che le applicazioni leggere non sono applicazioni minori. Non omettono funzionalità o dati importanti, sono solo più consapevoli dei costi coinvolti e dell'esperienza utente. Ad esempio:
    • Un'applicazione di galleria fotografica potrebbe offrire anteprime a risoluzione più bassa o utilizzare un meccanismo di carosello meno ricco di codice.
    • Un'applicazione di ricerca potrebbe restituire meno risultati alla volta, limitare il numero di risultati con un utilizzo intensivo dei contenuti multimediali o ridurre il numero di dipendenze necessarie per il rendering della pagina.
    • Un sito orientato alle notizie potrebbe mostrare meno notizie, omettere le categorie meno popolari o fornire anteprime 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 è abilitata, ad esempio per ridurre il numero di risorse e dipendenze richieste, applicare una compressione delle risorse più aggressiva e così via.
    • Se fornisci una risposta alternativa basata sull'intestazione Save-Data, ricorda di aggiungerla all'elenco Vary - Vary: Save-Data per comunicare alle cache upstream che devono memorizzare questa versione 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 service worker, l'applicazione può rilevare quando è attivata l'opzione di salvataggio dei dati controllando la presenza dell'intestazione della richiesta Save-Data o controllando il valore della proprietà navigator.connection.saveData. Se l'opzione è abilitata, valuta se puoi riscrivere la richiesta per recuperare meno byte o utilizzare una risposta già recuperata.
  5. Ti consigliamo di arricchire Save-Data con altri indicatori, ad esempio informazioni sul tipo di connessione e sulla tecnologia di connessione dell'utente (consulta l'API NetInfo). Ad esempio, potresti voler offrire l'esperienza leggera a qualsiasi utente con una connessione 2G anche se Save-Data non è abilitato. Al contrario, il semplice fatto che l'utente utilizzi una connessione 4G "veloce" non significa che non sia interessato a salvare i dati, ad esempio durante il roaming. Inoltre, puoi aumentare la presenza di Save-Data con il suggerimento del client Device-Memory per adattarti ulteriormente agli utenti che utilizzano dispositivi con memoria limitata. La memoria del dispositivo dell'utente è pubblicizzata anche nel suggerimento del client navigator.deviceMemory.

Ricette

Quello che puoi ottenere tramite Save-Data è limitato solo alle informazioni che ti vengono in mente. Per darti un'idea di cosa è possibile, esaminiamo un paio di casi d'uso. Potresti inventare altri casi d'uso mentre leggi questo articolo, quindi non esitare a sperimentare e vedere le possibilità.

Verifica di Save-Data nel codice lato server in corso...

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

La sintassi specifica per il rilevamento dell'intestazione Save-Data nel codice lato server dipende dal linguaggio utilizzato, ma l'idea di base dovrebbe essere la stessa per qualsiasi backend dell'applicazione. In PHP, ad esempio, le intestazioni delle richieste sono archiviate nell'array superglobale $_SERVER in indici che iniziano con HTTP_. Ciò significa che puoi rilevare l'intestazione Save-Data verificando l'esistenza e il valore della variabile $_SERVER["HTTP_SAVE_DATA"] in questo 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 esegui questo controllo prima che qualsiasi markup venga inviato al client, la variabile $saveData conterrà lo stato Save-Data e sarà disponibile ovunque per essere utilizzata nella pagina. Con questo meccanismo illustrato, vediamo alcuni esempi di come utilizzarlo per limitare la quantità di dati che inviamo all'utente.

Pubblica 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 gli schermi "standard" (1x) e un'altra immagine due volte più grande (2x) per gli 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. Nei casi in cui è preferibile un'esperienza di applicazione più leggera, potrebbe essere prudente inviare a questi schermi immagini con risoluzione inferiore (1x), anziché varianti più grandi (2x). Per ottenere questo risultato quando è presente l'intestazione Save-Data, è sufficiente modificare il markup che inviamo al client:

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 poco impegno sia necessario per soddisfare chi richiede specificatamente l'invio di meno dati. Se non ti piace modificare il markup nel backend, potresti ottenere lo stesso risultato utilizzando un modulo di riscrittura degli URL come mod_rewrite di Apache. Esistono esempi di come raggiungere questo obiettivo con una configurazione relativamente poca.

Potresti 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 sull'elemento <html> nel tuo CSS per modificare il modo in cui vengono pubblicate le immagini. Potresti inviare immagini di sfondo a bassa risoluzione a schermi ad alta risoluzione, come mostrato nell'esempio HTML precedente, oppure omettere del tutto determinate risorse.

Ometti immagini non essenziali

Alcuni contenuti di immagini sul web non sono semplicemente essenziali. Anche se queste immagini possono essere utili per migliorare i contenuti, potrebbero non essere appetibili per chi cerca di sfruttare al massimo i piani dati a consumo. Nel caso d'uso forse più semplice di Save-Data, possiamo utilizzare il codice di rilevamento PHP della versione precedente e omettere del tutto il markup delle immagini non essenziale:

<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ò certamente avere un effetto pronunciato, come puoi vedere nella figura seguente:

Un confronto tra immagini non critiche caricate
quando l&#39;opzione Salva dati è assente, rispetto a immagini omesse quando è presente l&#39;opzione Salva dati.
Un confronto tra le immagini non critiche caricate quando il salvataggio dei dati è assente e le stesse immagini omesse quando è presente il pulsante Salva dati.

Naturalmente, l'omissione di immagini non è l'unica possibilità. Puoi anche agire su Save-Data per evitare l'invio di altre risorse non critiche, come determinati caratteri tipografici.

Ometti caratteri web non essenziali

Sebbene i caratteri web di solito non rappresentino la stessa misura del payload totale di una determinata pagina come spesso accade con le immagini, sono comunque molto popolari. Inoltre, non consumano una quantità di dati insignificante. Inoltre, il modo in cui i browser recuperano e visualizzano i caratteri è più complicato di quanto pensi, con concetti quali FOIT, FOUT ed euristica del browser che rendono il rendering un'operazione complessa.

Potrebbe venirti in mente l'idea di escludere i caratteri web non essenziali per gli utenti che desiderano un'esperienza utente più snella. Save-Data rende questa operazione ragionevolmente indolore.

Ad esempio, supponiamo che tu abbia incluso sul tuo sito Fira Sans di Google Fonts. Fira Sans è un ottimo carattere, 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 il carattere non essenziale all'inizio, 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 in posizione lo snippet <link> di Google Fonts, in quanto il browser carica in modo speculativo le risorse CSS (inclusi i caratteri web) applicando prima gli stili al DOM, quindi controllando se eventuali elementi HTML richiamano una qualsiasi delle risorse nel foglio di stile. Se si verifica un utente con Save-Data attivo, Fira Sans non verrà mai caricato perché il DOM con stile non lo richiede mai. Al loro posto verrà attivato il formato braille. Non è così bello come Fira Sans, ma potrebbe essere preferibile agli utenti che cercano di estendere i loro piani dati.

Riepilogo

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

Ad esempio, alcuni utenti potrebbero non consentire la modalità Risparmio dati se sospettano che si verifichi una perdita di contenuti o funzionalità dell'app, anche in una situazione di connettività scadente. Al contrario, alcuni utenti potrebbero abilitarlo ovviamente per mantenere le pagine il più piccole e semplici possibile, anche in una buona situazione di connettività. È meglio che l'app presupponga che l'utente voglia un'esperienza completa e illimitata finché non avrai ricevuto un'indicazione chiara del contrario tramite un'azione esplicita dell'utente.

In qualità di proprietari di siti e sviluppatori web, assumiamoci la responsabilità della gestione dei nostri contenuti per migliorare l'esperienza utente degli utenti con limiti di dati e costi.

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