Introduzione
Lo sviluppo per il web mobile è un tema caldo di questi tempi. Quest'anno, per la prima volta in assoluto, gli smartphone hanno superato i PC in termini di vendite. Sempre più utenti utilizzano un dispositivo mobile per navigare sul web, il che significa che per gli sviluppatori è diventato fondamentale ottimizzare i propri siti per i browser mobile.
Il campo di battaglia "mobile" è ancora un territorio inesplorato per un gran numero di sviluppatori. Molte persone hanno siti legacy esistenti che trascurano completamente gli utenti di dispositivi mobili. Il sito è stato progettato principalmente per la navigazione da computer e ha un degrado scarso nei browser mobile. Questo sito (html5rocks.com) non fa eccezione. Al momento del lancio, abbiamo dedicato poco impegno alla realizzazione di una versione mobile del sito.
Creazione di un sito html5rocks.com ottimizzato per il mobile
Come esercizio, ho pensato che sarebbe stato interessante prendere html5rocks (un sito HTML5 esistente) e incrementarlo con una versione ottimizzata per i dispositivi mobili. La mia preoccupazione principale riguardava la quantità minima di lavoro necessaria per scegliere come target gli smartphone. L'obiettivo del mio esercizio non era creare un sito mobile completamente nuovo e gestire due basi di codice. Ci sarebbe voluto un'eternità e sarebbe stato un enorme spreco di tempo. Avevamo già definito la struttura del sito (markup). Abbiamo dato un'occhiata al CSS. La funzionalità di base (JS) era presente. Molti siti si trovano nella stessa barca.
Questo articolo esamina come abbiamo creato una versione mobile di HTML5rocks ottimizzata per i dispositivi Android e iOS. Basta caricare html5rocks.com su un dispositivo che supporta uno di questi sistemi operativi per vedere la differenza. Non ci sono reindirizzamenti a m.html5rocks.com o altre sciocchezze di questo tipo. Puoi utilizzare html5rocks così com'è, con il vantaggio aggiuntivo di un'esperienza visiva e di utilizzo ottimali su un dispositivo mobile.
Query supporti CSS
HTML4 e CSS2 supportano i stylesheet dipendenti dai media 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 avanti rispetto all'idea dei tipi di media e ne migliora la funzionalità con le query sui media. Le query sui media estendono l'utilità dei tipi di media consentendo un'etichettatura più precisa degli stili. In questo modo, la presentazione dei contenuti può essere personalizzata in base a un determinato intervallo di dispositivi di output senza dover modificare i contenuti stessi. Sembra perfetto per un layout esistente che deve essere modificato.
Puoi utilizzare le query sui media 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 delle query sui media del W3C.
Dimensioni schermo target
Nell'esempio seguente, phone.css
viene applicato ai dispositivi che il browser considera "portatili" o ai dispositivi con schermi di <= 320 px di larghezza.
<link rel='stylesheet'
media='handheld, only screen and (max-device-width: 320px)' href='phone.css'>
L'aggiunta di un prefisso alla parola chiave "only
" a una query multimediale fa sì che
i browser non conformi a CSS3 ignorino la regola.
Di seguito è riportato un esempio di targeting per dimensioni dello schermo comprese tra 641 e 800 pixel:
<link rel='stylesheet'
media='only screen and (min-width: 641px) and (max-width: 800px)' href='ipad.css'>
Le query sui contenuti multimediali possono essere visualizzate anche all'interno dei tag <style>
in linea. Di seguito sono riportati i tipi di media all
scelti come target in caso di orientamento verticale:
<style>
@media only all and (orientation: portrait) { ... }
</style>
media="handheld"
Dobbiamo fermarci un attimo a parlare di media="handheld"
.
Il fatto è che Android e iOS ignorano media="handheld"
. L'affermazione è che gli utenti perderanno i contenuti di alta qualità forniti dagli stili CSS che hanno come target media="screen"
e che gli sviluppatori sono meno propensi a mantenere una versione media="handheld"
di qualità inferiore. Come parte del motto "full web", la maggior parte dei moderni browser per smartphone
ignora semplicemente i fogli di stile portatili.
Sarebbe ideale utilizzare questa funzionalità per scegliere come target i dispositivi mobili, ma i vari browser l'hanno implementata in modi diversi:
- Alcuni leggono solo il foglio di stile del palmare.
- Alcuni leggono solo il foglio di stile per il palmare, se presente, ma per impostazione predefinita utilizzano il foglio di stile per lo schermo.
- Alcuni leggono sia il foglio di stile per il dispositivo portatile sia il foglio di stile per lo schermo.
- Alcuni leggono solo il foglio di stile dello schermo.
Opera Mini non ignora media="handheld"
. Il trucco per fare in modo che Windows Mobile riconosca media="handheld"
è usare le lettere maiuscole per il valore dell'attributo media per lo stile foglio di stile della schermata:
<!-- 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 sui media
Le query sui media vengono utilizzate ampiamente in html5rocks mobile. Ci hanno consentito di perfezionare il layout senza dover apportare modifiche significative al markup del nostro template Django… un vero toccasana! Inoltre, il supporto su vari browser è abbastanza 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 il look and feel principale di
html5rocks.com, ma ora stiamo applicando nuovi stili (mobile.css
)
per larghezze dello schermo inferiori a 800 pixel. La query sui media copre gli smartphone (~320 px) e l'iPad (~768 px).
L'effetto: stiamo sostituendo gradualmente gli stili in base.css
(solo se necessario) per migliorare l'aspetto dei contenuti sui dispositivi mobili.
Alcune delle modifiche allo stile applicate da mobile.css
:
- Riduci gli spazi vuoti/la spaziatura interna aggiuntivi nel sito. Piccoli schermi significa che lo spazio è prezioso!
- Rimuove
:hover
stati. Non verranno mai visualizzati sui dispositivi touch. - Regola il layout in modo che sia a colonna singola. Ne riparleremo più avanti.
- Rimuove l'elemento
box-shadow
attorno al tag div del contenitore principale del sito. Le ombreggiature dei riquadri di grandi dimensioni riducono le prestazioni della pagina. - È stato utilizzato il modello di contenitore flessibile CSS
box-ordinal-group
per modificare l'ordine di ogni sezione nella home page. Noterai che "IMPARA DAI PRINCIPALI GRUPPI DI FUNZIONALITÀ HTML5" prima della sezione "TUTORIAL" sulla home page e dopo nella versione per dispositivi mobili. Questo ordinamento era più adatto ai dispositivi mobili e non richiedeva modifiche al markup. Flexbox CSS! - Rimuove le modifiche
opacity
. La modifica dei valori alfa influisce negativamente sul rendimento sui dispositivi mobili.
Meta tag mobile
Mobile WebKit supporta alcune funzionalità che offrono agli utenti un'esperienza di navigazione migliore su determinati dispositivi.
Impostazioni dell'area visibile
La prima impostazione meta (e quella 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 lo informa che il sito è ottimizzato per il mobile. Ad esempio:
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
indica al browser di impostare l'area visibile in base alla larghezza del dispositivo con un'escursione iniziale di 1. Questo esempio consente anche di eseguire lo zoom, operazione che potrebbe essere preferibile
per un sito web, ma non per un'app web. Potremmo impedire di eseguire lo zoom con user-scalable=no
o limitare 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 pagina web per densità dello schermo diverse, utilizza la query supporti CSS -webkit-device-pixel-ratio
e/o la proprietà window.devicePixelRatio
in JavaScript, quindi imposta la proprietà meta target-densitydpi
su device-dpi
. In questo modo, Android non esegue la scalabilità nella pagina web e ti consente di apportare le modifiche necessarie per ogni densità tramite CSS e JavaScript.
Per ulteriori informazioni sul targeting delle risoluzioni dei dispositivi, consulta la documentazione di WebView di Android.
Navigazione a schermo intero
Esistono altri due valori meta che sono iOS-sfic. 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 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 meta disponibili, vedi la documentazione di riferimento di Safari.
Icone della schermata Home
I dispositivi iOS e Android accettano anche rel="apple-touch-icon"
(iOS) e rel="apple-touch-icon-precomposed"
(Android) per i link. Quando un utente aggiunge il tuo sito ai preferiti, viene creata un'icona simile a un'app nella schermata Home:
<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 mobile
Mettendo tutto insieme, 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ù comodo scorrere verticalmente rispetto a orizzontalmente. Per i dispositivi mobili è preferibile mantenere i contenuti in un layout verticale a colonna singola. Per html5rocks, abbiamo utilizzato query supporti CSS3 per creare questo layout. Ancora una volta, senza modificare il markup.
Ottimizzazioni per il mobile
La maggior parte delle ottimizzazioni che abbiamo apportato sono cose che avrebbero dovuto essere fatte in primo luogo. come la riduzione del numero di richieste di rete, la compressione JS/CSS, la compressione gzip (senza costi su App Engine) e la minimizzazione delle manipolazioni del DOM. Queste tecniche sono best practice comuni ma a volte vengono trascurate quando si porta di fretta un sito fuori dal sito.
Nascondi automaticamente barra degli indirizzi
I browser mobile non dispongono dell'area di visualizzazione della controparte desktop. Sulle piattaforme diverse, a volte capita di trovare una grande barra degli indirizzi nella parte superiore dello schermo... anche al termine del caricamento della pagina.
Un modo semplice per risolvere il problema è scorrere la pagina utilizzando JavaScript.
Anche se lo fai di un solo pixel, la fastidiosa barra degli indirizzi scompare.
Per nascondere forzatamente la barra degli indirizzi su html5rocks, ho collegato un gestore di eventi onload
all'oggetto window
e ho fatto scorrere la pagina verticalmente
di un pixel:
// Hides mobile browser's address bar when page is done loading.
window.addEventListener('load', function(e) {
setTimeout(function() { window.scrollTo(0, 1); }, 1);
}, false);
Inoltre, abbiamo aggregato questo listener per la variabile del modello is_mobile
poiché non è necessaria sul desktop.
Riduci le richieste di rete e risparmia larghezza di banda
È noto 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, quindi i siti per dispositivi mobili trarranno ancora più vantaggio dalla riduzione di queste richieste estranee. Inoltre, è fondamentale risparmiare ogni byte perché la larghezza di banda è spesso limitata sugli smartphone. Potresti far pagare gli utenti.
Di seguito sono riportati alcuni degli approcci che abbiamo adottato per ridurre al minimo le richieste di rete e la larghezza di banda su html5rocks:
Rimuovi gli iframe, che sono lenti. Gran parte della latenza è stata causata da widget di condivisione di terze parti (Buzz, Google Friend Connect, Twitter, Facebook) nelle pagine dei tutorial. Queste API sono state incluse tramite 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, il markup veniva nascosto se non era adatto al profilo mobile. Un buon esempio sono le quattro caselle arrotondate nella parte superiore della home page:
Non sono presenti sul sito mobile. È importante ricordare che il browser invia comunque una richiesta per ogni icona, nonostante il relativo contenitore sia nascosto con display:none
. Pertanto, non è stato sufficiente nascondere questi pulsanti. Non solo sprecherebbe larghezza di banda, ma l'utente
non vede i frutti di questa sprecata. La soluzione è stata creare un valore booleano "is_mobile" nel nostro modello Django per omettere selettivamente sezioni di HTML.
Quando l'utente visualizza il sito su uno smart device, i pulsanti non vengono visualizzati.
Cache applicazione - Non solo questo ci fornisce assistenza offline, ma crea anche un avvio più rapido.
Compressione CSS/JS: utilizziamo YUI Compressor anziché Closure Compiler principalmente perché gestisce sia CSS che JS. Abbiamo riscontrato un problema con le query sui media in linea (query sui media visualizzate all'interno di un foglio di stile) in YUI compressor 2.4.2 (vedi questo problema). Utilizzando YUI Compressor 2.4.4+ ha risolto il problema.
Se possibile, utilizza gli sprite di immagini CSS.
È stato utilizzato pngcrush per la compressione delle immagini.
Sono stati utilizzati dataURI per le immagini di piccole dimensioni. La codifica Base64 aggiunge circa il 30%o più delle dimensioni all'immagine, ma salva la richiesta di rete.
Carica automaticamente la ricerca personalizzata di Google utilizzando un singolo tag script anziché caricarla dinamicamente con
google.load()
. Quest'ultimo invia una richiesta aggiuntiva.
<script src="//www.google.com/jsapi?autoload={"modules":[{"name":"search","version":"1"}]}"> </script>
- Il nostro codice di stampa in formato leggibile e Modernizr erano inclusi in ogni pagina, anche se non sono mai stati utilizzati. Modernizr è fantastico, ma esegue una serie di 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 ottimizzazioni delle prestazioni:
- Tutti gli elementi JS sono stati spostati in fondo alla pagina (se possibile).
- Tag
<style>
incorporati rimossi. - Ricerche DOM memorizzate nella cache e manipolazioni DOM ridotte al minimo: ogni volta che tocchi il DOM, il browser esegue una ripetizione del flusso. I ricollegamenti sono ancora più costosi su un dispositivo mobile.
- È stato trasferito al server il codice lato client inutilizzato. In particolare, il controllo
per impostare lo 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
width:100%
owidth:auto
fluidi.
Cache applicazione
La versione mobile 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 di controllo della cache pesanti). Se il manifest viene memorizzato nella cache dal browser, il debug è un incubo. iOS e Android gestiscono particolarmente bene la memorizzazione nella cache di questo file, ma non forniscono un modo pratico per svuotare la cache come fanno i browser desktop.
Per evitare questa memorizzazione nella cache per il nostro sito, abbiamo prima impostato App Engine in modo da non memorizzare 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 al termine del download di un nuovo manifest. Viene 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, mantieni il manifest semplice. Vale a dire di non richiamare
ogni pagina del tuo sito. Elenca solo le immagini, i file CSS e JavaScript importanti. L'ultima cosa che vuoi fare è forzare il browser mobile a scaricare un numero elevato di asset a ogni aggiornamento dell'appcache. Ricorda invece che il browser memorizza nella cache una pagina HTML in modo implicito quando l'utente la visita (e include un attributo <html manifest="...">
).