Ihre HTML5-Website für Mobilgeräte optimieren

Einführung

Die Entwicklung für das mobile Web ist heutzutage ein wichtiges Thema. In diesem Jahr wurden zum ersten Mal mehr Smartphones als PCs verkauft. Immer mehr Nutzer verwenden ein Mobilgerät, 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 Nutzer haben bestehende Legacy-Websites, die mobile Nutzer überhaupt nicht berücksichtigen. Stattdessen wurde die Website hauptsächlich für Desktop-Browser entwickelt und wird in mobilen Browsern schlecht dargestellt. Diese Website (html5rocks.com) ist da keine Ausnahme. Bei der Markteinführung haben wir uns kaum um eine mobile Version der Website gekümmert.

Für Mobilgeräte optimierte Version von html5rocks.com erstellen

Als Übung dachte ich, es wäre interessant, html5rocks (eine bestehende HTML5-Website) zu nehmen und um eine für Mobilgeräte optimierte Version zu erweitern. Ich habe mich hauptsächlich mit dem Mindestaufwand beschäftigt, der für die Ausrichtung auf Smartphones erforderlich ist. Das Ziel meiner Übung war nicht, eine völlig neue mobile Website zu erstellen und zwei Codebasen zu pflegen. Das hätte ewig gedauert und wäre eine enorme Zeitverschwendung gewesen. Wir hatten die Struktur (Markup) der Website bereits definiert. Wir hatten ein Look-and-Feel (CSS). Die Hauptfunktion (JS) war vorhanden. Viele Websites sind in derselben Situation.

In diesem Artikel wird beschrieben, 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, das eines dieser Betriebssysteme unterstützt, um den Unterschied zu sehen. Es gibt keine Weiterleitungen zu m.html5rocks.com oder ähnliche Tricks. Sie erhalten html5rocks wie gewohnt, aber mit dem zusätzlichen Vorteil, dass es auf einem Mobilgerät gut aussieht und funktioniert.

Desktop html5rocks.com Mobile html5rocks.com
html5rocks.com auf dem Computer (links) und auf einem Mobilgerät (rechts)

CSS-Medienabfragen

HTML4 und CSS2 unterstützen schon seit einiger Zeit medienabhängige Stylesheets. Beispiel:

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

würde auf Druckgeräte abzielen und ein spezifisches Styling für den Seiteninhalt beim Drucken bereitstellen. CSS3 geht einen Schritt weiter und erweitert die Funktionalität von Medientypen durch Medienabfragen. Medienabfragen erweitern die Nützlichkeit von Medientypen, da sie eine präzisere Kennzeichnung von Stylesheets ermöglichen. So kann die Darstellung des Inhalts für eine bestimmte Reihe von Ausgabegeräten angepasst werden, ohne dass der Inhalt selbst geändert werden muss. Das klingt perfekt für ein vorhandenes Layout, das geändert werden muss.

Sie können Medienabfragen im Attribut media Ihrer externen Stylesheets verwenden, um die Bildschirmbreite, die Gerätebreite, die Ausrichtung usw. anzugeben. Eine vollständige Liste finden Sie in der W3C-Spezifikation für Medienabfragen.

Targeting auf Bildschirmgrößen

Im folgenden Beispiel gilt phone.css für Geräte, die der Browser als „Handheld“ einstuft, oder für Geräte mit Bildschirmen mit einer Breite von maximal 320 Pixeln.

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

Wenn Sie einer Medienabfrage das Keyword „only“ voranstellen, ignorieren Browser, die nicht CSS3-konform sind, die Regel.

Mit dem folgenden Code werden Bildschirmgrößen zwischen 641 px und 800 px angesprochen:

 <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 enthalten sein. Mit dem folgenden Code werden Medientypen vom Typ all im Hochformat angesprochen:

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

media="handheld"

Wir müssen kurz innehalten und über media="handheld" sprechen. Tatsächlich ignorieren Android und iOS media="handheld". Es wird behauptet, dass Nutzer die hochwertigen Inhalte vermissen werden, die durch Stylesheets für media="screen" bereitgestellt werden, und dass Entwickler weniger wahrscheinlich eine Version mit geringerer Qualität für media="handheld" pflegen werden. Im Rahmen ihres Mottos „Full Web“ ignorieren die meisten modernen Smartphone-Browser Handheld-Stylesheets einfach.

Es wäre ideal, diese Funktion für Mobilgeräte zu verwenden, aber verschiedene Browser haben sie auf unterschiedliche Weise implementiert:

  • Einige haben nur Lesezugriff auf das Stylesheet für Mobilgeräte.
  • Einige lesen nur das Handheld-Stylesheet, falls vorhanden, verwenden aber ansonsten standardmäßig das Bildschirm-Stylesheet.
  • Einige lesen sowohl das Handheld-Stylesheet als auch das Bildschirm-Stylesheet.
  • Einige lesen nur das Stylesheet für den Bildschirm.

Opera Mini ignoriert media="handheld" nicht. Damit Windows Mobile media="handheld" erkennt, muss der Attributwert des Media-Attributs für das Stylesheet „screen“ großgeschrieben werden:

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

Verwendung von Medienabfragen durch html5rocks

Medienabfragen werden auf html5rocks für Mobilgeräte häufig verwendet. Wir konnten das Layout anpassen, ohne größere Änderungen am Django-Vorlagen-Markup vornehmen zu müssen – ein echter Lebensretter! Außerdem ist die Unterstützung in den verschiedenen Browsern ziemlich gut.

Im <head>-Element jeder Seite sehen Sie 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 grundlegende Design von html5rocks.com bestimmt, aber jetzt wenden wir neue Stile (mobile.css) für Bildschirmbreiten unter 800 Pixel an. Die Medienabfrage deckt Smartphones (~320 px) und das iPad (~768 px) ab. Der Effekt: Wir überschreiben die Stile in base.css schrittweise (nur bei Bedarf), damit die Darstellung auf Mobilgeräten besser aussieht.

Einige der Stiländerungen, die mobile.css erzwingt:

  • Reduziert zusätzliche Leerzeichen/Padding auf der gesamten Website. Auf kleinen Bildschirmen ist der Platz begrenzt.
  • Entfernt :hover Zustände. Sie werden auf Touch-Geräten nie angezeigt.
  • Passt das Layout so an, dass es einspaltig ist. Weitere Informationen zu diesem Thema folgen später.
  • Entfernt den box-shadow um das Hauptcontainer-div der Website. Große Box-Shadows beeinträchtigen die Seitenleistung.
  • Das CSS-Flexbox-Modell box-ordinal-group wurde verwendet, um die Reihenfolge der einzelnen Abschnitte auf der Startseite zu ändern. Sie werden feststellen, dass der Abschnitt „LEARN BY MAJOR HTML5 FEATURE GROUPS“ auf der Startseite vor dem Abschnitt „TUTORIALS“ steht, in der mobilen Version jedoch danach. Diese Reihenfolge war für Mobilgeräte sinnvoller und erforderte keine Änderungen am Markup. CSS-Flexbox FTW!
  • Entfernt opacity Änderungen. Das Ändern von Alphawerten beeinträchtigt die Leistung auf Mobilgeräten.

Mobile Meta-Tags

Mobile WebKit unterstützt einige Funktionen, die Nutzern auf bestimmten Geräten ein besseres Surferlebnis bieten.

Einstellungen für den Darstellungsbereich

Die erste Meta-Einstellung (und die, die Sie am häufigsten verwenden werden) ist die Viewport-Eigenschaft. Durch das Festlegen eines Darstellungsbereichs wird dem Browser mitgeteilt, wie Inhalte auf dem Bildschirm des Geräts dargestellt werden sollen und 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 festzulegen. In diesem Beispiel ist auch das Zoomen möglich, was für eine Website wünschenswert sein kann, für eine Web-App jedoch nicht. Mit user-scalable=no können wir das Zoomen verhindern oder die Skalierung auf ein bestimmtes Maß beschränken:

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

Android erweitert das Darstellungsbereich-Meta-Tag, indem Entwickler angeben können, 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, low-dpi.

Wenn du deine Webseite für verschiedene Pixeldichten anpassen möchtest, verwende die CSS-Medienabfrage -webkit-device-pixel-ratio und/oder das Attribut window.devicePixelRatio in JavaScript und setze dann das Meta-Attribut target-densitydpi auf device-dpi. Dadurch wird verhindert, dass Android die Skalierung auf deiner Webseite vornimmt, und du kannst die erforderlichen Anpassungen für jede Pixeldichte über CSS und JavaScript vornehmen.

Weitere Informationen zum Targeting auf Geräteauflösungen finden Sie in der WebView-Dokumentation von Android.

Vollbildmodus

Es gibt zwei weitere Metawerte, die iOS-spezifisch sind. apple-mobile-web-app-capable und apple-mobile-web-app-status-bar-style rendern Seiteninhalte im Vollbildmodus, ähnlich wie bei einer App, und machen die Statusleiste durchscheinend:

 <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 Meta-Optionen finden Sie in der Safari-Referenzdokumentation.

Symbole auf dem Startbildschirm

iOS- und Android-Geräte akzeptieren auch rel="apple-touch-icon" (iOS) und rel="apple-touch-icon-precomposed" (Android) für Links. Dadurch wird ein auffälliges, App-ähnliches Symbol auf dem Startbildschirm des Nutzers erstellt, wenn er ein Lesezeichen für deine Website setzt:

 <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" />

Verwendung von Meta-Tags für Mobilgeräte durch html5rocks

Hier ist ein Snippet 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 bequemer, vertikal als horizontal zu scrollen. Für Mobilgeräte wird ein einspaltiges, vertikales Layout bevorzugt. Für html5rocks haben wir CSS3-Mediaanfragen verwendet, um ein solches Layout zu erstellen. Auch hier ohne Änderung des Markups.

Tutorial-Index. Anleitung. HTML5-Funktionsseite Seite „Autorenprofile“
Einspaltiges vertikales Layout auf der gesamten Website.

Optimierungen für Mobilgeräte

Die meisten der von uns vorgenommenen Optimierungen hätten eigentlich von Anfang an durchgeführt werden sollen. Dazu gehören die Reduzierung der Anzahl der Netzwerkanfragen, die JS/CSS-Komprimierung, die Gzip-Komprimierung (in App Engine kostenlos) und die Minimierung von DOM-Manipulationen. Diese Techniken sind gängige Best Practices, werden aber gelegentlich übersehen, wenn eine Website schnell veröffentlicht werden soll.

Adressleiste automatisch ausblenden

Mobile Browser haben nicht so viel Platz auf dem Bildschirm wie Desktop-Browser. Zu allem Überfluss wird auf verschiedenen Plattformen manchmal eine große Adressleiste am oberen Bildschirmrand angezeigt, selbst nachdem die Seite geladen wurde.

Eine einfache Möglichkeit, damit umzugehen, besteht darin, die Seite mit JavaScript zu scrollen. Selbst wenn Sie nur um ein Pixel scrollen, wird die lästige Adressleiste ausgeblendet. Um die Adressleiste auf html5rocks auszublenden, habe ich einen onload-Event-Handler an das window-Objekt angehängt und die Seite vertikal um ein Pixel gescrollt:

Adressleiste.
Die unschöne Adressleiste nimmt Platz auf dem Bildschirm ein.
  // Hides mobile browser's address bar when page is done loading.
  window.addEventListener('load', function(e) {
    setTimeout(function() { window.scrollTo(0, 1); }, 1);
  }, false);

Wir haben diesen Listener auch in die Vorlagenvariable is_mobile eingebunden, da er auf dem Computer nicht benötigt wird.

Netzwerkanfragen reduzieren, Bandbreite sparen

Es ist bekannt, dass die Reduzierung der Anzahl von HTTP-Anfragen die Leistung erheblich verbessern kann. Auf Mobilgeräten ist die Anzahl der gleichzeitigen Verbindungen, die der Browser herstellen kann, noch stärker eingeschränkt. Daher profitieren mobile Websites noch mehr von der Reduzierung dieser zusätzlichen Anfragen. Außerdem ist es wichtig, jedes Byte einzusparen, da die Bandbreite auf Smartphones oft begrenzt ist. Das kann Nutzer Geld kosten.

Im Folgenden finden Sie einige der Ansätze, die wir verfolgt haben, um Netzwerkanfragen zu minimieren und die Bandbreite auf html5rocks zu reduzieren:

  • Entfernen Sie iFrames – iFrames sind langsam! Ein großer Teil unserer Latenz wurde durch Widgets von Drittanbietern (Buzz, Google Friend Connect, Twitter, Facebook) auf Tutorial-Seiten verursacht. Diese APIs wurden über <script>-Tags eingebunden und erstellen iFrames, die die Geschwindigkeit der Seite verringern. Die Widgets wurden für Mobilgeräte entfernt.

  • display:none: In bestimmten Fällen haben wir Markup ausgeblendet, wenn es nicht zum Profil für Mobilgeräte passte. Ein gutes Beispiel waren die vier abgerundeten Felder oben auf der Startseite:

Schaltflächen auf der Startseite.
Box buttons on homepage.

Sie fehlen auf der mobilen Website. Der Browser stellt trotz des mit display:none ausgeblendeten Containers für jedes Symbol eine Anfrage. Daher reichte es nicht aus, diese Schaltflächen einfach auszublenden. Das würde nicht nur Bandbreite verschwenden, sondern der Nutzer würde nicht einmal die Früchte dieser verschwendeten Bandbreite sehen! Die Lösung bestand darin, in unserer Django-Vorlage einen booleschen Wert „is_mobile“ zu erstellen, um Abschnitte des HTML-Codes bedingt wegzulassen. Wenn der Nutzer die Website auf einem Smart-Gerät aufruft, werden die Schaltflächen weggelassen.

  • Anwendungs-Cache: Dadurch wird nicht nur die Offlinenutzung unterstützt, sondern auch der Start beschleunigt.

  • CSS/JS-Komprimierung: Wir verwenden den YUI-Kompressor anstelle des Closure-Compilers, da er sowohl CSS als auch JS verarbeitet. Ein Problem, auf das wir gestoßen sind, war, dass Inline-Medienabfragen (Medienabfragen, die in einem Stylesheet erscheinen) im YUI-Kompressor 2.4.2 nicht funktionierten (siehe dieses Problem). Durch die Verwendung von YUI Compressor 2.4.4+ wurde das Problem behoben.

  • Verwendung von CSS-Image-Sprites, wo möglich.

  • pngcrush für die Bildkomprimierung verwendet.

  • dataURIs für kleine Bilder verwendet. Die Base64-Codierung erhöht die Größe des Bildes um etwa 30 %, spart aber die Netzwerkanfrage.

  • Die benutzerdefinierte Google-Suche wird automatisch mit einem einzelnen 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 eingebunden, auch wenn sie nie verwendet wurden. Modernizr ist großartig, führt aber bei jedem Laden eine Reihe von Tests durch. Einige dieser Tests nehmen kostspielige Änderungen am DOM vor und verlangsamen den Seitenaufbau. Jetzt binden wir diese Bibliotheken nur noch auf Seiten ein, auf denen sie tatsächlich benötigt werden. -2 Anfragen :)

Zusätzliche Leistungsoptimierungen:

  • Der gesamte JS-Code wurde nach Möglichkeit an das Ende der Seite verschoben.
  • Inline-<style>-Tags entfernt.
  • Im Cache gespeicherte DOM-Suchvorgänge und minimierte DOM-Manipulationen: Jedes Mal, wenn Sie das DOM berühren, führt der Browser einen Reflow durch. Reflows sind auf Mobilgeräten noch kostspieliger.
  • Überflüssiger clientseitiger Code wurde auf den Server ausgelagert. Insbesondere wird geprüft, ob der Navigationsstil der aktuellen Seite festgelegt ist: 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 flexible width:100%- oder width:auto-Elemente ersetzt.

Anwendungscache

Die mobile Version von html5rocks verwendet den Anwendungscache, um das erste Laden zu beschleunigen und Nutzern das Lesen von Inhalten offline zu ermöglichen.

Wenn du AppCache auf deiner Website implementierst, ist es sehr wichtig, dass du deine Manifestdatei nicht im Cache speicherst (entweder explizit in der Manifestdatei selbst oder implizit mit umfangreichen Cache-Control-Headern). Wenn das Manifest vom Browser im Cache gespeichert wird, ist das Debugging ein Albtraum. iOS und Android speichern diese Datei besonders gut im Cache, bieten aber keine bequeme Möglichkeit, den Cache zu leeren, wie es bei Desktop-Browsern der Fall ist.

Damit das Caching für unsere Website verhindert wird, legen wir zuerst fest, dass App Engine Manifestdateien nie im Cache speichert:

- 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 ein neues Manifest heruntergeladen wurde. 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 Netzwerkverkehr zu sparen. Das heißt, Sie sollten nicht jede Seite Ihrer Website erwähnen. Listen Sie nur die wichtigen Bilder, CSS- und JavaScript-Dateien auf. Sie sollten auf keinen Fall den mobilen Browser dazu zwingen, bei jeder Appcache-Aktualisierung eine große Anzahl von Assets herunterzuladen. Denken Sie stattdessen daran, dass der Browser eine HTML-Seite implizit im Cache speichert, wenn der Nutzer sie besucht (und sie ein <html manifest="...">-Attribut enthält).