Modifica del sito HTML5

Eric Bidelman

introduzione

Lo sviluppo per il Web mobile è un argomento attuale in questi giorni. Quest'anno, per la prima volta in assoluto, gli smartphone hanno venduto i PC. Sempre più utenti utilizzano un dispositivo mobile per navigare sul Web e questo significa che per gli sviluppatori è fondamentale ottimizzare i propri siti per i browser mobile.

Il campo di battaglia "mobile" è ancora inesplorato per un gran numero di sviluppatori. Molte persone dispongono già di siti legacy che trascurano del tutto gli utenti di dispositivi mobili. Il sito, invece, è stato progettato principalmente per la navigazione su desktop e si riduce in modo scarso nei browser mobile. Questo sito (html5rocks.com) non fa eccezione. Al momento del lancio ci siamo impegnati a creare una versione del sito per dispositivi mobili.

Creazione di un sito html5rocks.com ottimizzato per i dispositivi mobili

Come esercizio, ho pensato che sarebbe stato interessante prendere html5rocks (un sito HTML5 esistente) e incrementarlo con una versione ottimizzata per dispositivi mobili. Mi preoccupava principalmente la quantità minima di lavoro richiesta per il targeting degli smartphone. L'obiettivo del mio esercizio non era creare un sito mobile completamente nuovo e mantenere due codebase. Ci sarebbe voluto una vita e sarebbe stata una grande perdita di tempo. Abbiamo già definito la struttura del sito (markup). Avevamo un look and feel (CSS). Era presente la funzionalità di base (JS). Il punto è che molti siti sono su questa stessa barca.

Questo articolo esamina come abbiamo creato una versione di HTML5rocks per dispositivi mobili ottimizzata per dispositivi Android e iOS. Carica html5rocks.com su un dispositivo che supporta uno di questi sistemi operativi per vedere la differenza. Non sono previsti reindirizzamenti a un sito m.html5rocks.com o ad altra stupidità di questo tipo. Ottieni gli elementi HTML5 così come sono... con l'ulteriore vantaggio di essere un elemento che ha un aspetto fantastico e funziona bene sui dispositivi mobili.

html5rocks.com desktop html5rocks.com per cellulari
html5rocks.com su computer (sinistra) e dispositivi mobili (destra)

Query supporti CSS

HTML4 e CSS2 hanno supportato i fogli di stile dipendenti dai contenuti multimediali da un po' di tempo. Ad esempio:

<link rel="stylesheet" media="print" href="printer.css">

ha come target i dispositivi di stampa e fornisce uno stile specifico per i contenuti della pagina quando vengono stampati. CSS3 fa un passo in più rispetto all'idea dei tipi di contenuti multimediali e ne migliora le funzionalità mediante query supporti. Le query supporti aumentano l'utilità dei tipi multimediali consentendo un'etichettatura più precisa dei fogli di stile. Ciò consente di personalizzare la presentazione dei contenuti per una specifica gamma di dispositivi di output senza dover modificare i contenuti stessi. Sembra perfetto per un layout esistente che deve essere modificato.

Puoi utilizzare le query supporti nell'attributo media dei fogli di stile esterni per scegliere come target la larghezza dello schermo, la larghezza del dispositivo, l'orientamento e così via. Per l'elenco completo, consulta la specifica di W3C Media Query.

Dimensioni schermo di targeting

Nell'esempio seguente, phone.css si applica ai dispositivi che il browser considera "portatili" o con schermi <= 320 px di larghezza.

 <link rel='stylesheet'
  media='handheld, only screen and (max-device-width: 320px)' href='phone.css'>

Se inserisci il prefisso "only" da una query supporti, i browser non conformi a CSS3 ignoreranno la regola.

Quanto segue dovrebbe scegliere come target dimensioni dello schermo comprese tra 641 px e 800 px:

 <link rel='stylesheet'
  media='only screen and (min-width: 641px) and (max-width: 800px)' href='ipad.css'>

Le query supporti possono essere visualizzate anche all'interno di tag <style> incorporati. Quanto segue ha come target all tipi di contenuti multimediali quando l'orientamento è verticale:

 <style>
  @media only all and (orientation: portrait) { ... }
 </style>

media="handheld"

Dobbiamo fermarci un minuto per parlare di media="handheld". Il fatto è che Android e iOS ignorano media="handheld". L'affermazione è che gli utenti perderanno i contenuti di fascia alta forniti dai fogli di stile che hanno come target media="screen" e che gli sviluppatori sono meno propensi a mantenere una versione media="handheld" di qualità inferiore. Pertanto, come parte del motto "full web", la maggior parte dei moderni browser per smartphone ignora semplicemente i fogli di stile portatili.

Sarebbe ideale per utilizzare questa funzionalità per i dispositivi mobili, ma vari browser l'hanno implementata in modi diversi:

  • Alcuni leggono solo il foglio di stile del dispositivo portatile.
  • Alcuni leggono soltanto il foglio di stile del palmare, se presente, mentre in caso contrario viene usato per impostazione predefinita il foglio di stile dello schermo.
  • Alcuni leggono sia il foglio di stile del palmare sia il foglio di stile dello schermo.
  • Alcuni leggono solo il foglio di stile dello schermo.

Opera Mini non ignora media="handheld". Il trucco per far riconoscere a Windows Mobile media="handheld" consiste nell'utilizzare le maiuscole nel valore dell'attributo multimediale per il foglio di stile dello schermo:

 <!-- media="handheld" trick for Windows Mobile -->
 <link rel="stylesheet" href="screen.css" media="Screen">
 <link rel="stylesheet" href="mobile.css" media="handheld">

In che modo html5rocks utilizza le query supporti

Le query supporti sono utilizzate massicciamente in HTML5rock per dispositivi mobili. Ci hanno consentito di modificare il layout senza dover apportare modifiche significative al nostro markup del modello Django... un vero salvatore! Inoltre, il loro supporto nei vari browser è piuttosto buono.

Nel <head> di ogni pagina vedrai i seguenti fogli di stile:

 <link rel='stylesheet'
  media='all' href='/static/css/base.min.css' />
 <link rel='stylesheet'
  media='only screen and (max-width: 800px)' href='/static/css/mobile.min.css' />

base.css ha sempre definito l'aspetto principale di html5rocks.com, ma ora stiamo applicando nuovi stili (mobile.css) per larghezze dello schermo inferiori a 800 px. La sua query supporti riguarda gli smartphone (~320 px) e l'iPad (~768 px). Di conseguenza, eseguiamo l'override incrementale degli stili in base.css (solo se necessario) per migliorare l'aspetto dei dispositivi mobili.

Alcune delle modifiche di stile applicate da mobile.css:

  • Riduce spazio vuoto/spaziatura interna extra sul sito. Piccoli schermi per schermi di piccole dimensioni.
  • Rimuove :hover stati. Non saranno mai visibili sui dispositivi touch.
  • Regola il layout in modo che sia a colonna singola. Ne parleremo più avanti.
  • Rimuove il box-shadow intorno al contenitore div del contenitore principale del sito. Le ombre della casella di grandi dimensioni riducono le prestazioni della pagina.
  • È stato utilizzato il modello flex box CSS box-ordinal-group per modificare l'ordine di ogni sezione sulla home page. Noterai che l'opzione "APPRENDIMENTO DEI PRINCIPALI GRUPPI DI FUNZIONALITÀ HTML5" è davanti alla sezione "TUTORIAL" della home page e successiva nella versione per dispositivi mobili. Questo ordine era più logico per i dispositivi mobili e non richiedeva modifiche al markup. FTW di CSS Flexbox
  • Rimuove opacity modifiche. La modifica dei valori alfa è un hit da rendimento sui dispositivi mobili.

Meta tag per dispositivi mobili

Mobile WebKit supporta alcuni componenti aggiuntivi che offrono agli utenti una migliore esperienza di navigazione su determinati dispositivi.

Impostazioni area visibile

La prima meta-impostazione (che utilizzerai più spesso) è la proprietà viewport. L'impostazione di un'area visibile indica al browser come devono adattarsi i contenuti allo schermo del dispositivo e informa il browser che il sito è ottimizzato per i dispositivi mobili. Ad esempio:

 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">

indica al browser di impostare l'area visibile sulla larghezza del dispositivo con una scala iniziale pari a 1. Questo esempio consente anche di eseguire lo zoom, una funzionalità auspicabile per un sito web, ma non per un'app web. Potremmo impedire lo zoom con user-scalable=no o ridurre il ridimensionamento a un determinato livello:

 <meta name=viewport
  content="width=device-width, initial-scale=1.0, minimum-scale=0.5 maximum-scale=1.0">

Android estende il meta tag viewport consentendo agli sviluppatori di specificare per quale risoluzione dello schermo è stato sviluppato il sito:

 <meta name="viewport" content="target-densitydpi=device-dpi">

I valori possibili per target-densitydpi sono device-dpi, high-dpi, medium-dpi, low-dpi.

Se vuoi modificare la tua pagina web per diverse densità dello schermo, utilizza la query multimediale CSS -webkit-device-pixel-ratio e/o la proprietà window.devicePixelRatio in JavaScript, quindi imposta la proprietà del meta target-densitydpi su device-dpi. Questo impedisce ad Android di scalare la pagina web e ti consente di apportare le modifiche necessarie per ogni densità tramite CSS e JavaScript.

Consulta la documentazione di WebView per Android per ulteriori informazioni sul targeting delle risoluzioni dei dispositivi.

Navigazione a schermo intero

Esistono altri due metavalori che sono specifici per iOS. apple-mobile-web-app-capable e apple-mobile-web-app-status-bar-style mostreranno i contenuti della pagina in modalità a schermo intero, simile a quella di un'app, e renderanno traslucida la barra di stato:

 <meta name="apple-mobile-web-app-capable" content="yes">
 <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">

Per ulteriori informazioni su tutte le opzioni di metadati disponibili, consulta la documentazione di riferimento di Safari.

Icone nella schermata Home

I dispositivi iOS e Android accettano anche rel="apple-touch-icon" (iOS) e rel="apple-touch-icon-precomposed" (Android) per i link. che creano un'icona appariscente simile a un'app nella schermata Home dell'utente quando aggiunge il tuo sito ai preferiti:

 <link rel="apple-touch-icon"
      href="/static/images/identity/HTML5_Badge_64.png" />
 <link rel="apple-touch-icon-precomposed"
      href="/static/images/identity/HTML5_Badge_64.png" />

In che modo html5rocks utilizza i meta tag per dispositivi mobili

Per riassumere, ecco uno snippet della sezione <head> di html5rocks:

 <head>
  ...
   <meta name="viewport"
        content="width=device-width, initial-scale=1.0, minimum-scale=1.0" />

   <link rel="apple-touch-icon"
        href="/static/images/identity/HTML5_Badge_64.png" />
   <link rel="apple-touch-icon-precomposed"
        href="/static/images/identity/HTML5_Badge_64.png" />
  ...
 </head>

Layout verticale

Su schermi più piccoli, è molto più pratico scorrere in verticale che in orizzontale. Per i dispositivi mobili è preferibile mantenere i contenuti in un layout verticale a una colonna. Per gli asset HTML5rocks, abbiamo utilizzato query supporti CSS3 per creare un layout di questo tipo. Anche in questo caso, senza modificare il markup.

Indice dei tutorial. Tutorial. pagina delle funzioni HTML5. Pagina dei profili degli autori.
Layout verticale a una colonna in tutto il sito.

Ottimizzazioni mobile

La maggior parte delle ottimizzazioni che abbiamo apportato sono azioni che avrebbero dovuto essere fatte inizialmente. Operazioni come la riduzione del numero di richieste di rete, la compressione JS/CSS, la compressione con gzip (senza costi su App Engine) e la riduzione al minimo delle manipolazioni del DOM. Queste tecniche sono best practice comuni, ma a volte vengono trascurate quando si spinge a correre contro un sito.

Nascondi automaticamente barra degli indirizzi

I browser per dispositivi mobili non hanno lo spazio sullo schermo di quello desktop. A peggiorare le cose, su diverse piattaforme a volte potresti visualizzare una grande barra degli indirizzi nella parte superiore dello schermo... anche dopo aver caricato la pagina.

Un modo semplice per gestirlo è scorrere la pagina utilizzando JavaScript. Anche in questo caso di un pixel la fastidiosa barra degli indirizzi verrà mantenuta. Per forzare l'occultamento della barra degli indirizzi su html5rocks, ho collegato un gestore di eventi onload all'oggetto window e ho fatto scorrere la pagina in verticale di un pixel:

Barra degli indirizzi.
La brutta barra degli indirizzi occupa lo spazio dello schermo.
  // Hides mobile browser's address bar when page is done loading.
  window.addEventListener('load', function(e) {
    setTimeout(function() { window.scrollTo(0, 1); }, 1);
  }, false);

Abbiamo anche aggregato questo listener che è la nostra variabile di modello is_mobile, poiché non è necessaria sul desktop.

Riduci le richieste di rete e risparmia larghezza di banda

È risaputo che ridurre il numero di richieste HTTP può migliorare notevolmente le prestazioni. I dispositivi mobili limitano ulteriormente il numero di connessioni simultanee che il browser può effettuare, pertanto i siti per dispositivi mobili trarranno ancora più vantaggio dalla riduzione di queste richieste non pertinenti. Inoltre, eliminare ogni byte è fondamentale perché la larghezza di banda è spesso limitata sui telefoni. Gli utenti potrebbero essere a pagamento.

Di seguito sono riportati alcuni degli approcci che abbiamo adottato per ridurre al minimo le richieste di rete e la larghezza di banda su HTML5rock:

  • Rimuovi iframe - gli iframe sono lenti. Una gran parte della nostra latenza proveniva da widget di condivisione di terze parti (Buzz, Google Friend Connect, Twitter, Facebook) nelle pagine dei tutorial. Queste API sono state incluse tramite i tag <script> e creano iframe che riducono la velocità della pagina. I widget sono stati rimossi per i dispositivi mobili.

  • display:none - In alcuni casi, nascondevamo il markup se non rientrava nel profilo per dispositivi mobili. Un buon esempio sono stati i quattro riquadri arrotondati nella parte superiore della home page:

Pulsanti a forma di riquadro nella home page.
Pulsanti Box nella home page.

Non sono presenti sul sito mobile. È importante ricordare che il browser effettua comunque una richiesta per ogni icona, nonostante il contenitore sia nascosto con display:none. Pertanto, non era sufficiente nascondere questi pulsanti. Ciò significherebbe non solo sprecare larghezza di banda, ma l'utente non ne vedrebbe nemmeno i frutti. La soluzione consisteva nel creare un valore booleano "is_mobile" nel nostro modello Django per omettere in modo condizionale delle sezioni di HTML. Quando l'utente visualizza il sito su uno smart device, i pulsanti non vengono visualizzati.

  • Cache dell'applicazione - Non solo ci offre supporto offline, ma velocizza anche l'avvio.

  • Compressione CSS/JS: stiamo utilizzando il compressore YUI anziché il compilatore Closure, principalmente perché gestisce sia CSS che JS. Un problema che abbiamo riscontrato è stato quello delle query supporti in linea (query supporti che appaiono all'interno di un foglio di stile) inserite in YUI Compressore 2.4.2 (vedi questo problema). L'utilizzo di YUI Compressor 2.4.4 o versioni successive ha risolto il problema.

  • Vengono utilizzati sprite di immagini CSS quando possibile.

  • È stato utilizzato pngcrush per la compressione delle immagini.

  • Utilizzati dataURI per immagini piccole. La codifica Base64 aggiunge circa il 30%delle dimensioni all'immagine, ma salva la richiesta di rete.

  • Hai caricato automaticamente Google Ricerca personalizzata utilizzando un singolo tag script invece di caricarlo dinamicamente con google.load(). Quest'ultimo effettua una richiesta aggiuntiva.

<script src="//www.google.com/jsapi?autoload={"modules":[{"name":"search","version":"1"}]}"> </script>
  • La nostra graziosa stampante di codice e Modernizr venivano inclusi in ogni pagina, anche se non sono mai stati utilizzati. Modernizr è eccezionale, ma esegue diversi test a ogni caricamento. Alcuni di questi test apportano modifiche costose al DOM e rallentano il caricamento della pagina. Ora includiamo queste librerie solo nelle pagine in cui sono effettivamente necessarie. -2 richieste :)

Ulteriori ritocchi al rendimento:

  • Spostato tutto il codice JS in fondo alla pagina (ove possibile).
  • Tag <style> incorporati rimossi.
  • Ricerche del DOM memorizzato nella cache e manipolazioni del DOM ridotte al minimo: ogni volta che toccate il DOM, il browser esegue una ripetizione del flusso. Gli scorrimenti sono ancora più costosi su un dispositivo mobile.
  • Eseguito l'offload di codice lato client in eccesso sul server. In particolare, il controllo per visualizzare l'impostazione dello stile di navigazione della pagina corrente: js var lis = document.querySelectorAll('header nav li'); var i = lis.length; while (i--) { var a = lis[i].querySelector('a'); var section = a.getAttribute("data-section"); if (new RegExp(section).test(document.location.href)) { a.className = 'current'; } }
  • Gli elementi con larghezze fisse sono stati sostituiti con il fluido width:100% o width:auto.

Cache applicazione

La versione per dispositivi mobili di html5rocks utilizza la cache dell'applicazione per velocizzare il caricamento iniziale e consente agli utenti di leggere i contenuti offline.

Quando implementi AppCache sul tuo sito, è molto importante non memorizzare nella cache il file manifest (esplicitamente nel file manifest stesso o implicitamente con intestazioni complesse di controllo della cache). Se il file manifest viene memorizzato nella cache del browser, eseguire il debug è un incubo. iOS e Android svolgono un ottimo lavoro nel memorizzare questo file nella cache, ma non offrono un metodo pratico per svuotare la cache come i browser desktop.

Per evitare tale memorizzazione nella cache per il nostro sito, impostiamo innanzitutto App Engine in modo che non memorizzi mai nella cache i file manifest:

- url: /(.*\.(appcache|manifest))
  static_files: \1
  mime_type: text/cache-manifest
  upload: (.*\.(appcache|manifest))
  expiration: "0s"

In secondo luogo, abbiamo utilizzato l'API JS per informare l'utente quando il download di un nuovo manifest è terminato. Verrà chiesto di aggiornare la pagina:

window.applicationCache.addEventListener('updateready', function(e) {
  if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
    window.applicationCache.swapCache();
    if (confirm('A new version of this site is available. Load it?')) {
      window.location.reload();
    }
  }
}, false);

Per risparmiare traffico di rete, utilizza un manifest semplice. Vale a dire: non richiamare ogni pagina del sito. Elenca solo i file immagine, CSS e JavaScript importanti. L'ultima cosa da fare è forzare il browser mobile a scaricare un gran numero di risorse a ogni aggiornamento dell'appcache. Invece, ricorda che il browser memorizza implicitamente nella cache una pagina HTML quando l'utente la visita (e include un attributo <html manifest="...">).