Einführung
Die Entwicklung für das mobile Web ist heutzutage ein wichtiges Thema. In diesem Jahr werden zum ersten Mal Smartphones verkaufte PCs. Immer mehr Nutzer verwenden Mobilgeräte, um im Web zu surfen. Daher wird es für Entwickler immer wichtiger, ihre Websites für mobile Browser zu optimieren.
Das „mobile“ Schlachtfeld ist für viele Entwickler noch Neuland. Viele Unternehmen haben bereits bestehende Websites, die mobile Nutzer völlig vernachlässigen. Stattdessen wurde die Website hauptsächlich für die Desktop-Bedienung entwickelt und funktioniert auf Mobilgeräten nur eingeschränkt. Diese Website (html5rocks.com) ist keine Ausnahme. Bei der Einführung haben wir nur wenig Aufwand in eine mobile Version der Website gesteckt.
Für Mobilgeräte optimierte html5rocks.com-Version erstellen
Als Übung habe ich mir überlegt, html5rocks (eine vorhandene HTML5-Website) um eine für Mobilgeräte optimierte Version zu ergänzen. Ich wollte vor allem wissen, wie wenig Aufwand es erfordert, Anzeigen auf Smartphones auszurichten. Das Ziel meiner Übung war es nicht, eine komplett neue mobile Website zu erstellen und zwei Codebasen zu verwalten. Das hätte ewig gedauert und viel Zeit verschwendet. Wir hatten bereits die Struktur der Website (Markup) definiert. Wir haben uns das Design angesehen (CSS). Die Hauptfunktion (JS) war vorhanden. Viele Websites sind in derselben Situation.
In diesem Artikel wird erläutert, wie wir eine mobile Version von html5rocks erstellt haben, die für Android- und iOS-Geräte optimiert ist. Laden Sie einfach html5rocks.com auf einem Gerät mit einem dieser Betriebssysteme, um den Unterschied zu sehen. Es gibt keine Weiterleitungen auf m.html5rocks.com oder ein anderes Totson dieser Art. Du erhältst html5rocks in der Originalversion – mit dem zusätzlichen Vorteil, dass es auf Mobilgeräten gut aussieht und funktioniert.
CSS-Medienabfragen
HTML4 und CSS2 unterstützen seit einiger Zeit medienabhängige Stylesheets. Beispiel:
<link rel="stylesheet" media="print" href="printer.css">
die auf Drucker ausgerichtet sind und einen bestimmten Stil für den Seiteninhalt bereitstellen, wenn dieser gedruckt wird. CSS3 geht noch einen Schritt weiter und erweitert die Funktionalität von Medientypen mit Medienabfragen. Medienabfragen erweitern die Nützlichkeit von Medientypen, da sie eine präzisere Kennzeichnung von Stylesheets ermöglichen. So kann die Darstellung der Inhalte an einen bestimmten Bereich von Ausgabegeräten angepasst werden, ohne dass die Inhalte selbst geändert werden müssen. Das klingt perfekt für ein vorhandenes Layout, das geändert werden muss.
Sie können Media-Abfragen im media
-Attribut Ihrer externen Stylesheets verwenden, um z. B. auf Bildschirmbreite, Gerätebreite und Ausrichtung abzuzielen. Eine vollständige Liste finden Sie in der W3C-Media-Abfragespezifikation.
Targeting auf Bildschirmgrößen
Im folgenden Beispiel würde phone.css
auf Geräte angewendet, die vom Browser als „Handheld“ oder Geräte mit einem Display mit einer Breite von maximal 320 Pixeln eingestuft werden.
<link rel='stylesheet'
media='handheld, only screen and (max-device-width: 320px)' href='phone.css'>
Wenn Sie Medienabfragen das Schlüsselwort „only
“ voranstellen, wird die Regel von nicht CSS3-kompatiblen Browsern ignoriert.
Mit folgendem Code wird auf Bildschirmgrößen zwischen 641 und 800 Pixeln ausgerichtet:
<link rel='stylesheet'
media='only screen and (min-width: 641px) and (max-width: 800px)' href='ipad.css'>
Medienabfragen können auch in Inline-<style>
-Tags verwendet werden. Die folgenden Targeting-Optionen sind auf all
-Medientypen in Hochformat ausgerichtet:
<style>
@media only all and (orientation: portrait) { ... }
</style>
media="handheld"
Wir müssen einen Moment innehalten und media="handheld"
besprechen.
Tatsächlich wird media="handheld"
von Android und iOS ignoriert. Es wird behauptet, dass Nutzer die hochwertigen Inhalte vermissen werden, die durch Stylesheets für media="screen"
bereitgestellt werden, und dass Entwickler mit geringerer Wahrscheinlichkeit eine media="handheld"
-Version mit niedrigerer Qualität pflegen. Daher ignorieren die meisten modernen Smartphone-Browser im Rahmen ihres Mottos „Full Web“ einfach Handheld-Stylesheets.
Diese Funktion eignet sich ideal für die Ausrichtung auf Mobilgeräte. Die verschiedenen Browser haben sie jedoch unterschiedlich implementiert:
- Einige lesen nur das Stylesheet für Handhelds.
- Einige lesen nur das Stylesheet für Handhelds, falls vorhanden, andernfalls das Stylesheet für Bildschirme.
- Manche lesen sowohl das Handheld-Stylesheet als auch das Screen-Style Sheet.
- Einige lesen nur das Bildschirm-Stylesheet.
In Opera Mini wird media="handheld"
nicht ignoriert. Damit Windows Mobile media="handheld"
erkennt, müssen Sie den Wert des Attributs „media“ für das Bildschirm-Stylesheet großschreiben:
<!-- media="handheld" trick for Windows Mobile -->
<link rel="stylesheet" href="screen.css" media="Screen">
<link rel="stylesheet" href="mobile.css" media="handheld">
Verwendung von Media Queries auf html5rocks
Mediaabfragen werden in mobilen html5rocks-Versionen häufig verwendet. So konnten wir das Layout optimieren, ohne größere Änderungen an unserem Django-Template-Markup vornehmen zu müssen. Das war wirklich ein Segen! Außerdem ist der Support für die verschiedenen Browser ziemlich gut.
Im <head>
jeder Seite findest du die folgenden Stylesheets:
<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
hat schon immer das zentrale Erscheinungsbild von html5rocks.com definiert, aber jetzt werden neue Stile (mobile.css
) für Bildschirmbreiten unter 800 Pixeln angewendet. Die Mediaabfrage deckt Smartphones (~320 px) und das iPad (~768 px) ab.
Die Auswirkungen: Wir überschreiben die Stile in base.css
schrittweise (nur bei Bedarf), um die Darstellung auf Mobilgeräten zu verbessern.
Einige der Stiländerungen, die mobile.css
erzwingt:
- Reduziert überflüssige Leerzeichen/Padding auf der gesamten Website. Auf kleinen Bildschirmen ist Platz ein knappes Gut.
:hover
Status werden entfernt. Auf Touchbildschirmen werden sie nie angezeigt.- Das Layout wird so angepasst, dass es einspaltig ist. Mehr dazu später.
- Entfernt den
box-shadow
um den Hauptcontainer-Div der Website. Große Schatten reduzieren die Seitenleistung. - Ich habe das CSS-Flexbox-Modell
box-ordinal-group
verwendet, um die Reihenfolge der einzelnen Abschnitte auf der Startseite zu ändern. Auf der Startseite steht „LEARN BY MAJOR HTML5 FEATURE GROUPS“ vor dem Abschnitt „TUTORIALS“, in der mobilen Version dagegen danach. Diese Reihenfolge macht auf Mobilgeräten mehr Sinn und erfordert keine Änderungen am Markup. CSS-Flexbox ist der Hit! - Entfernt
opacity
-Änderungen. Das Ändern von Alphawerten wirkt sich negativ auf die Leistung auf Mobilgeräten aus.
Meta-Tags für Mobilgeräte
Mobile WebKit unterstützt einige Funktionen, die Nutzern auf bestimmten Geräten ein besseres Surferlebnis bieten.
Darstellungsbereichseinstellungen
Die erste Metaeinstellung, die Sie am häufigsten verwenden werden, ist die Viewport-Eigenschaft. Wenn Sie einen Darstellungsbereich festlegen, wird dem Browser mitgeteilt, wie die Inhalte auf dem Bildschirm des Geräts dargestellt werden sollen. Außerdem wird der Browser darüber informiert, dass die Website für Mobilgeräte optimiert ist. Beispiel:
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
weist den Browser an, den Darstellungsbereich auf die Breite des Geräts mit einer anfänglichen Skalierung von 1 einzustellen. In diesem Beispiel ist auch das Zoomen möglich, was für eine Website zwar wünschenswert, für eine Webanwendung aber nicht unbedingt erforderlich ist. Wir könnten das Zoomen mit user-scalable=no
verhindern oder die Skalierung auf ein bestimmtes Niveau begrenzen:
<meta name=viewport
content="width=device-width, initial-scale=1.0, minimum-scale=0.5 maximum-scale=1.0">
Android erweitert das Meta-Tag „viewport“ und ermöglicht es Entwicklern, anzugeben, für welche Bildschirmauflösung die Website entwickelt wurde:
<meta name="viewport" content="target-densitydpi=device-dpi">
Mögliche Werte für target-densitydpi
sind device-dpi
, high-dpi
, medium-dpi
und low-dpi
.
Wenn du deine Webseite an verschiedene Bildschirmdichten anpassen möchtest, verwende die CSS-Medienabfrage -webkit-device-pixel-ratio
und/oder das Attribut window.devicePixelRatio
in JavaScript und setze dann das Metaattribut target-densitydpi
auf device-dpi
. Dadurch verhindert Android, dass Ihre Webseite skaliert wird, und Sie können die erforderlichen Anpassungen für jede Dichte über CSS und JavaScript vornehmen.
Weitere Informationen zum Targeting auf Geräteauflösungen finden Sie in der WebView-Dokumentation von Android.
Surfen im Vollbildmodus
Es gibt zwei weitere Metawerte, die iOS-sfic sind. Mit apple-mobile-web-app-capable
und apple-mobile-web-app-status-bar-style
werden Seiteninhalte im app-ähnlichen Vollbildmodus gerendert und die Statusleiste wird durchsichtig:
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
Weitere Informationen zu allen verfügbaren Metaoptionen finden Sie in der Referenzdokumentation zu Safari.
Symbole auf dem Startbildschirm
Auf iOS- und Android-Geräten werden auch rel="apple-touch-icon"
(iOS) und rel="apple-touch-icon-precomposed"
(Android) für Links akzeptiert. Dadurch wird ein auffälliges App-ähnliches Symbol auf dem Startbildschirm des Nutzers angezeigt, wenn er Ihre Website als Lesezeichen speichert:
<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" />
So verwendet html5rocks mobile Meta-Tags
Hier ist ein Ausschnitt aus dem <head>
-Abschnitt von 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>
Vertikales Layout
Auf kleineren Bildschirmen ist es viel einfacher, vertikal als horizontal zu scrollen. Für Mobilgeräte wird ein einspaltiges, vertikales Layout empfohlen. Für html5rocks haben wir CSS3-Mediaanfragen verwendet, um ein solches Layout zu erstellen. Auch ohne das Markup.
Optimierungen für Mobilgeräte
Die meisten Optimierungen, die wir vorgenommen haben, sind Dinge, die von vornherein hätten erledigt werden müssen. Dazu gehören beispielsweise die Reduzierung der Anzahl der Netzwerkanfragen, die Komprimierung von JS/CSS, das GZIP-Verfahren (in der App Engine kostenlos) und die Minimierung von DOM-Manipulationen. Diese Techniken sind allgemeine Best Practices, werden aber gelegentlich übersehen, wenn eine Website schnell fertiggestellt werden soll.
Adressleiste automatisch ausblenden
Mobile Browser haben nicht so viel Bildschirmfläche wie ihre Desktop-Pendants. Auf verschiedenen Plattformen wird am Ende manchmal eine große Adressleiste oben auf dem Bildschirm angezeigt, selbst wenn die Seite fertig geladen ist.
Eine einfache Möglichkeit, damit umzugehen, ist das Scrollen der Seite mit JavaScript.
Auch wenn Sie die Adressleiste nur um einen Pixel verschieben, ist sie nicht mehr zu sehen.
Um die Adressleiste auf html5rocks zu verbergen, habe ich dem window
-Objekt einen onload
-Ereignis-Handler hinzugefügt und die Seite vertikal um ein Pixel gescrollt:
// Hides mobile browser's address bar when page is done loading.
window.addEventListener('load', function(e) {
setTimeout(function() { window.scrollTo(0, 1); }, 1);
}, false);
Außerdem haben wir diesen Listener in unserer Vorlagenvariablen is_mobile
verpackt, da er auf dem Computer nicht benötigt wird.
Netzwerkanfragen reduzieren, Bandbreite sparen
Es ist bekannt, dass sich die Leistung durch eine geringere Anzahl von HTTP-Anfragen erheblich verbessern lässt. Auf Mobilgeräten ist die Anzahl der gleichzeitigen Verbindungen, die der Browser herstellen kann, noch weiter eingeschränkt. Daher profitieren mobile Websites noch stärker von der Reduzierung dieser überflüssigen Anfragen. Außerdem ist es wichtig, jedes Byte zu sparen, da die Bandbreite auf Smartphones oft begrenzt ist. Dadurch entstehen den Nutzern möglicherweise Kosten.
Im Folgenden finden Sie einige Ansätze, die wir zum Minimieren von Netzwerkanfragen und zum Reduzieren der Bandbreite auf html5rocks eingeschlagen haben:
Entfernen Sie iFrames. Sie sind langsam. Ein Großteil der Latenz wurde durch Freigabe-Widgets von Drittanbietern (Buzz, Google Friend Connect, Twitter, Facebook) auf Anleitungsseiten verursacht. Diese APIs wurden über
<script>
-Tags eingebunden und erstellten iFrames, die die Geschwindigkeit der Seite verringern. Die Widgets wurden für Mobilgeräte entfernt.display:none
: In bestimmten Fällen wurde Markup ausgeblendet, wenn es nicht in das mobile Profil gepasst hat. Ein gutes Beispiel waren die vier abgerundeten Felder oben auf der Startseite:
Sie fehlen auf der mobilen Website. Der Browser sendet weiterhin eine Anfrage für jedes Symbol, auch wenn der Container mit display:none
ausgeblendet ist. Daher reicht es nicht aus, diese Schaltflächen einfach auszublenden. Das würde nicht nur die Bandbreite verschwenden, sondern der Nutzer würde auch nicht die Vorteile dieser verschwendete Bandbreite sehen. Die Lösung bestand darin, in unserer Django-Vorlage den booleschen Wert "is_mobile" zu erstellen, um HTML-Abschnitte bedingt auszulassen.
Wenn der Nutzer die Website auf einem Smart-Device aufruft, werden die Schaltflächen nicht angezeigt.
Anwendungscache: Dadurch wird nicht nur die Offlineunterstützung ermöglicht, sondern auch ein schnelleres Starten.
CSS/JS-Komprimierung: Wir verwenden das YUI-Komprimierungsprogramm anstelle des Closure-Compilers, weil es sowohl CSS als auch JS verarbeitet. Ein Problem bestand darin, dass Inline-Medienabfragen (Medienabfragen, die in einem Stylesheet erscheinen) im YUI Compressor 2.4.2 nicht ausgeführt wurden (siehe dieses Problem). Mit YUI Compressor 2.4.4 konnte das Problem behoben werden.
Nach Möglichkeit CSS-Bild-Sprites verwenden
PNGcrush wurde für die Bildkomprimierung verwendet.
Daten-URIs wurden für kleine Bilder verwendet. Die Base64-Codierung erhöht die Größe des Bildes um etwa 30 %, spart aber die Netzwerkanfrage.
Die Google-Suche wurde automatisch über ein einzelnes Script-Tag geladen, anstatt sie dynamisch mit
google.load()
zu laden. Letzteres führt zu einer zusätzlichen Anfrage.
<script src="//www.google.com/jsapi?autoload={"modules":[{"name":"search","version":"1"}]}"> </script>
- Unser Code-Pretty-Printer und Modernizr wurden auf jeder Seite eingefügt, auch wenn sie nie verwendet wurden. Modernizr ist großartig, führt aber bei jeder Ladung eine Reihe von Tests durch. Einige dieser Tests erfordern aufwendige Änderungen am DOM und verlangsamen das Laden der Seite. Jetzt werden diese Bibliotheken nur noch auf Seiten eingefügt, auf denen sie tatsächlich benötigt werden. -2 Anfragen :)
Weitere Leistungsoptimierungen:
- Alle JS-Dateien wurden nach Möglichkeit ans Ende der Seite verschoben.
- Inline-
<style>
-Tags wurden entfernt. - Gecachte DOM-Suchanfragen und minimierte DOM-Manipulationen: Jedes Mal, wenn Sie das DOM ändern, führt der Browser einen Neuaufbau durch. Auf Mobilgeräten sind sie noch kostspieliger.
- Überflüssiger clientseitiger Code wurde auf den Server ausgelagert. Die Prüfung zum Festlegen des Navigationsstils der aktuellen Seite:
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'; } }
- Elemente mit fester Breite wurden durch
width:100%
oderwidth:auto
ersetzt.
Anwendungscache
Die mobile Version von html5rocks verwendet den Application Cache, um das erste Laden zu beschleunigen und Nutzern das Lesen von Inhalten offline zu ermöglichen.
Wenn Sie AppCache auf Ihrer Website implementieren, darf die Manifestdatei nicht im Cache gespeichert werden – weder explizit in der Manifestdatei selbst noch implizit mit Cache-Kontroll-Headern. Wenn Ihr Manifest vom Browser im Cache gespeichert wird, ist die Fehlerbehebung ein Albtraum. iOS und Android speichern diese Datei besonders gut im Cache, bieten aber keine praktische Möglichkeit, den Cache wie bei Desktop-Browsern zu leeren.
Um dieses Caching für unsere Website zu verhindern, haben wir zuerst die App Engine so konfiguriert, dass Manifestdateien nie im Cache gespeichert werden:
- url: /(.*\.(appcache|manifest))
static_files: \1
mime_type: text/cache-manifest
upload: (.*\.(appcache|manifest))
expiration: "0s"
Zweitens haben wir die JS API verwendet, um den Nutzer zu informieren, wenn der Download eines neuen Manifests abgeschlossen ist. Sie werden aufgefordert, die Seite zu aktualisieren:
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);
Halten Sie Ihr Manifest einfach, um den Netzwerkverkehr zu reduzieren. Das heißt, Sie sollten nicht jede Seite Ihrer Website erwähnen. Geben Sie nur die wichtigen Bilder, CSS- und JavaScript-Dateien an. Als Letztes möchten Sie den mobilen Browser dazu zwingen, bei jeder AppCache-Aktualisierung eine große Anzahl von Assets herunterzuladen. Denken Sie stattdessen daran, dass der Browser beim Besuch des Nutzers eine HTML-Seite implizit zwischenspeichert und ein <html manifest="...">
-Attribut enthält.