Distribuire applicazioni veloci e leggere con il risparmio di dati

Dave Gash
Dave Gash
Ilya Grigorik
Ilya Grigorik

L'intestazione della richiesta hint del 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 creare pagine leggere

Statistiche Weblight

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

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

Questi sono degli argomenti convincenti 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 abbastanza popolari, presentano svantaggi significativi: compressione di immagini e testo semplice (e talvolta inaccettabile), impossibilità di elaborare pagine sicure (HTTPS), ottimizzazione solo delle pagine visitate tramite un risultato di ricerca e altro ancora. La popolarità di questi servizi di per sé indica che gli sviluppatori web non stanno rispondendo in modo adeguato all'elevata domanda degli utenti di applicazioni e pagine veloci e leggere. Ma raggiungere questo obiettivo è un percorso complesso e a volte difficile.

Intestazione della richiesta Save-Data

Una tecnica abbastanza semplice è consentire al browser di aiutarti utilizzando l'intestazione della richiesta Save-Data. Identificando questa intestazione, una pagina web può personalizzare e offrire un'esperienza utente ottimizzata agli utenti con limiti di costi e prestazioni.

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

Supporto del browser

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

Per determinare quando offrire agli utenti un'esperienza "leggera", la tua applicazione può controllare l'intestazione della richiesta di suggerimento del client Save-Data. Questa intestazione della richiesta indica la preferenza del client per l'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 risparmio dei dati nel browser, il browser aggiunge l'intestazione della richiesta Save-Data a tutte le richieste in uscita (sia HTTP che HTTPS). Al momento della stesura di questo documento, il browser pubblicizza solo un token *on- nell'intestazione (Save-Data: on), ma questo potrebbe essere esteso in futuro 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.
  }
}

La verifica della presenza dell'oggetto connection all'interno dell'oggetto navigator è fondamentale perché rappresenta l'API Network Information, 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 la tua 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 annunciate nell'intestazione della richiesta Save-Data e restituire una risposta alternativa: 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 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 intuitivi pulsanti di attivazione/disattivazione o caselle di controllo.
    • Quando è selezionata la modalità Risparmio dati, annuncia e fornisci un modo semplice e ovvio per disattivarla e, se vuoi, tornare all'esperienza completa.
  2. Ricorda che le applicazioni leggere non sono applicazioni di dimensioni inferiori. Non omettono funzionalità o dati importanti, ma sono solo più consapevoli dei costi coinvolti e dell'esperienza utente. Ad esempio:
    • Un'applicazione galleria fotografica potrebbe pubblicare anteprime a risoluzione più bassa o utilizzare un meccanismo carosello che richiede meno codice.
    • Un'applicazione di ricerca potrebbe restituire meno risultati alla volta, limitare il numero di risultati che utilizzano molti contenuti multimediali o ridurre il numero di dipendenze necessarie per il rendering della pagina.
    • Un sito orientato alle notizie potrebbe mostrare meno notizie, omettere 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 leggera quando è abilitata, ad esempio riducendo il numero di risorse e dipendenze richieste, applica 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 indicare alle cache upstream che devono memorizzare nella cache e pubblicare questa versione solo se è presente l'intestazione della richiesta Save-Data. Per ulteriori dettagli, consulta le best practice per l'interazione con le cache.
  4. Se utilizzi un service worker, l'applicazione può rilevare quando l'opzione di salvataggio dei dati viene attivata 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 se utilizzare una risposta già recuperata.
  5. Valuta la possibilità di aumentare Save-Data con altri indicatori, come informazioni sul tipo di connessione e sulla tecnologia dell'utente (vedi API NetInfo). Ad esempio, potresti voler offrire un'esperienza leggera a tutti gli utenti che utilizzano una connessione 2G, anche se Save-Data non è attivo. 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 hint del client Device-Memory per adattarti ulteriormente agli utenti sui dispositivi con memoria limitata. La memoria del dispositivo dell'utente è pubblicizzata anche nel hint client navigator.deviceMemory.

Ricette

I risultati che puoi ottenere tramite Save-Data sono limitati solo ai risultati che riesci a trovare. Per darti un'idea di cosa è possibile fare, vediamo un paio di casi d'uso. Mentre leggi queste informazioni, potresti pensare ad altri casi d'uso, quindi prova a sperimentare e scopri le possibilità.

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

Anche se lo stato Save-Data è un valore che puoi rilevare in JavaScript tramite la proprietà navigator.connection.saveData, in alcuni casi è preferibile rilevarlo sul lato server. In alcuni casi, JavaScript può non essere eseguito. Inoltre, il rilevamento lato server è l'unico modo per modificare il markup prima che venga inviato al client, cosa che riguarda 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 deve essere la stessa per qualsiasi backend dell'applicazione. In PHP, ad esempio, le intestazioni delle richieste vengono archiviate nell'array superglobale $_SERVER in 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"] 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 di inviare qualsiasi markup al client, la variabile $saveData conterrà lo stato Save-Data e sarà disponibile ovunque per l'utilizzo sulla pagina. Dopo aver illustrato questo meccanismo, vediamo alcuni esempi di come utilizzarlo per limitare la quantità di dati che inviamo 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 gruppi di due: un'immagine per schermi "standard" (1x) e un'altra immagine di dimensioni due volte (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. Nei casi in cui si preferisce un'esperienza dell'applicazione più leggera, potrebbe essere prudente inviare a queste schermate immagini con risoluzione inferiore (1x) e non varianti più grandi (2x). Per ottenere questo risultato, quando è presente l'intestazione Save-Data, è sufficiente modificare il markup inviato 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 una persona che ti chiede in modo specifico di inviare meno dati. Se non ti piace modificare il markup sul backend, puoi ottenere lo stesso risultato anche utilizzando un modulo di riscrittura degli URL come Apache mod_rewrite. Esistono esempi di come raggiungere questo obiettivo con una configurazione relativamente piccola.

Puoi anche estendere questo concetto alle proprietà background-image del CSS aggiungendo semplicemente 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 la modalità di pubblicazione delle immagini. Potresti inviare immagini di sfondo a bassa risoluzione a schermi ad alta risoluzione, come mostrato nell'esempio HTML riportato sopra, oppure omettere del tutto alcune risorse.

Ometti immagini non essenziali

Alcuni contenuti di immagini sul web sono semplicemente non essenziali. Anche se queste immagini possono rappresentare dei piacevoli infuori ai contenuti, potrebbero non essere auspicabili per chi cerca di spremere tutto il possibile dai piani di dati a consumo. In quello che forse è il caso d'uso più semplice di Save-Data, possiamo utilizzare il codice di rilevamento PHP di una versione 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ò sicuramente avere un effetto pronunciato, come puoi vedere nella figura seguente:

Confronto tra immagini non critiche caricate quando i dati di salvataggio non sono presenti e le stesse immagini che vengono omesse in presenza dei dati di salvataggio.
Un confronto tra le immagini non critiche caricate quando è assente il file Save-Data e le stesse immagini che vengono omesse quando sono presenti i dati di salvataggio.

Naturalmente, l'omissione di immagini non è l'unica possibilità. Puoi anche intervenire su Save-Data per evitare di inviare altre risorse non critiche, ad esempio alcuni caratteri tipografici.

Ometti caratteri web non essenziali

Sebbene i caratteri web di solito non rappresentino una parte del payload totale totale di una determinata pagina quanto spesso le immagini, sono comunque molto popolari. Non consumano una quantità insignificante 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 euristica del browser che rendono il rendering un'operazione articolata.

Pertanto, potrebbe essere opportuno escludere caratteri web non essenziali per gli utenti che desiderano esperienze più snelle. Save-Data rende questo passaggio ragionevolmente indolore.

Ad esempio, supponiamo che tu abbia incluso Fira Sans di Google Fonts sul tuo sito. Fira Sans è un eccellente font per il corpo del testo, ma forse non è così importante per gli utenti che cercano di risparmiare dati. Aggiungendo una classe save-data all'elemento <html> quando è presente l'intestazione Save-Data, possiamo scrivere stili che richiamano inizialmente il carattere tipografico non essenziale, per poi disattivarlo 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 stili al DOM, quindi controllando se gli elementi HTML richiamano una qualsiasi delle risorse nel foglio di stile. Se un utente è con Save-Data attivo, Fira Sans non verrà mai caricato perché il DOM con stile non lo richiama mai. Arial, invece, interverrà. Non è bello come Fira Sans, ma potrebbe essere preferibile a quegli utenti che cercano di ampliare i loro piani dati.

Riepilogo

L'intestazione Save-Data non ha molte sfumature; può essere attivata o disattivata e l'applicazione ha l'onere di fornire esperienze appropriate in base alle sue impostazioni, indipendentemente dal motivo.

Ad esempio, alcuni utenti potrebbero non consentire la modalità Risparmio dati se sospettano che si verifichi una perdita di contenuti o funzioni dell'app, anche in una situazione di scarsa connettività. Viceversa, alcuni utenti potrebbero abilitarla ovviamente per ridurre al minimo le dimensioni delle pagine e renderle il più semplici possibile, anche in una buona situazione di connettività. È preferibile che l'app presuma che l'utente voglia l'esperienza completa e illimitata finché non ricevi indicazioni chiare altrimenti tramite un'azione esplicita dell'utente.

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

Per ulteriori dettagli su Save-Data ed esempi pratici utili, consulta Aiutare i tuoi utenti Save Data.