Optimieren Ihrer HTML5-Website

Eric Bidelman

Einführung

Die Entwicklung von Apps für das mobile Web ist derzeit ein heiß diskutiertes Thema. In diesem Jahr waren Smartphones ausverkauft. Immer mehr Nutzer surfen im Web mit Mobilgeräten. Daher ist es für Entwickler äußerst wichtig, ihre Websites für mobile Browser zu optimieren.

Für viele Entwickler ist die mobile Welt noch unerforscht. Viele Nutzer haben bestehende Websites, die mobile Nutzer vollständig vernachlässigen. Die Website wurde in erster Linie für das Surfen auf Desktop-Computern entwickelt und wird in mobilen Browsern nicht so gut beeinträchtigt. Diese Website (html5rocks.com) ist da keine Ausnahme. Bei der Markteinführung stecken wir wenig Aufwand in eine mobile Version der Website.

Für Mobilgeräte optimierte html5rocks.com erstellen

Als Übung dachte ich, dass es interessant wäre, html5rocks (eine bestehende HTML5-Website) mit einer für Mobilgeräte optimierten Version zu erweitern. Ich war vor allem mit dem Arbeitsaufwand bei der Ausrichtung auf Smartphones konfrontiert. Ziel meiner Übung war es nicht, eine völlig neue mobile Website zu erstellen und zwei Codebasis zu verwalten. Das hätte ewig gedauert und viel Zeit verschwendet. Wir hatten bereits die Struktur der Website (Markup) definiert. Wir haben uns das anschaulich angesehen (CSS). Die Kernfunktionalität (JS) war vorhanden. Viele Websites befinden sich im selben Boot.

In diesem Artikel wird untersucht, wie wir eine für Android- und iOS-Geräte optimierte mobile Version von html5rocks erstellt haben. Laden Sie einfach html5rocks.com auf einem Gerät, das eines dieser Betriebssysteme unterstützt, um den Unterschied zu sehen. Es sind keine Weiterleitungen zu m.html5rocks.com oder sonstigen Schmierereien dieser Art vorhanden. Sie erhalten html5rocks unverändert... mit dem zusätzlichen Vorteil, dass es auf einem Mobilgerät gut aussieht und gut funktioniert.

html5rocks.com auf Computern html5rocks.com auf Mobilgeräten
html5rocks.com auf dem Computer (links) und auf dem Mobilgerät (rechts)

CSS-Medienabfragen

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

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

auf Druckgeräte ausgerichtet und dem Seiteninhalt beim Drucken ein bestimmter Stil zugewiesen wird. CSS3 führt das Konzept von Medientypen noch einen Schritt weiter und verbessert ihre Funktionalität mit Medienabfragen. Medienabfragen erhöhen die Nützlichkeit von Medientypen, indem sie eine präzisere Beschriftung von Stylesheets ermöglichen. Dadurch kann die Präsentation des Inhalts an eine bestimmte Reihe von Ausgabegeräten angepasst werden, ohne den Inhalt selbst ändern zu müssen. Klingt perfekt für ein vorhandenes Layout, das geändert werden muss!

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

Targeting auf Bildschirmgrößen

Im folgenden Beispiel würde phone.css für Geräte gelten, die der Browser als „Handheld“ einstuft, oder Geräte mit einer Bildschirmbreite von weniger als 320 Pixeln.

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

Wenn Medienabfragen das Keyword „only“ vorangestellt wird, wird die Regel von nicht CSS3-kompatiblen Browsern ignoriert.

So würden Sie auf Bildschirmgrößen zwischen 641 und 800 Pixel abzielen:

 <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. Im Folgenden wird ein Targeting auf all-Medientypen im Hochformat vorgenommen:

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

media="handheld"

Wir müssen kurz über media="handheld" sprechen. Fakt ist, dass media="handheld" von Android und iOS ignoriert wird. Die Behauptung besagt, dass Nutzern die High-End-Inhalte entgehen, die von Stylesheets bereitgestellt werden, die auf media="screen" ausgerichtet sind. Außerdem ist es weniger wahrscheinlich, dass Entwickler eine qualitativ minderwertige media="handheld"-Version beibehalten. Gemäß ihrem Motto „Full Web“ ignorieren die meisten modernen Smartphone-Browser einfach Handheld-Stylesheets.

Es wäre ideal, diese Funktion für das Targeting auf Mobilgeräte zu verwenden, aber in verschiedenen Browsern wurde sie auf unterschiedliche Weise implementiert:

  • Einige lesen nur das Handheld-Stylesheet.
  • Einige lesen nur das Handheld-Stylesheet, sofern vorhanden, verwenden aber standardmäßig das Bildschirm-Stylesheet.
  • Einige lesen sowohl das Handheld-Stylesheet als auch das Bildschirm-Stylesheet.
  • Einige lesen nur das Bildschirm-Stylesheet.

Opera Mini ignoriert media="handheld" nicht. Damit Windows Mobile media="handheld" erkennt, muss der Wert des Medienattributs für das Bildschirm-Stylesheet 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">

So verwendet html5rocks Medienabfragen

Medienabfragen werden in html5rocks für Mobilgeräte häufig verwendet. So konnten wir das Layout anpassen, ohne wesentliche Änderungen an unserem Django-Vorlagen-Markup vornehmen zu müssen. Eine echte Erleichterung! Außerdem ist der Support in den verschiedenen Browsern recht gut.

Im <head> 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 Haupt-Design von html5rocks.com definiert, aber jetzt wenden wir neue Stile (mobile.css) für Bildschirmbreiten unter 800 px an. Die Medienabfrage deckt Smartphones (~320px) und das iPad (~768px) ab. Der Effekt: Stile werden in base.css schrittweise überschrieben (nur bei Bedarf), damit das Design auf Mobilgeräten besser aussieht.

Einige der Stiländerungen, die von mobile.css erzwungen werden:

  • Reduziert überflüssige Leerzeichen/Abstände auf der Website. Auf kleinen Bildschirmen ist Platz das A und O!
  • Entfernt :hover Bundesstaaten. Sie werden auf Geräten mit Touchscreen nie gesehen.
  • Das Layout wird auf eine Spalte angepasst. Mehr dazu später.
  • Entfernt das box-shadow um das div-Element des Hauptcontainers der Website. Große Schatten verringern 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 Markup-Änderungen. CSS-Flexbox FTW!
  • opacity Änderungen werden entfernt. Das Ändern der Alphawerte beeinträchtigt die Leistung auf Mobilgeräten.

Mobile Meta-Tags

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

Einstellungen für den Darstellungsbereich

Die erste Meta-Einstellung, die Sie am häufigsten verwenden, ist die Darstellungsbereich-Eigenschaft. Durch Festlegen eines Darstellungsbereichs wird dem Browser mitgeteilt, wie die Inhalte auf den Bildschirm des Geräts passen sollen, und 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 festzulegen. Dieses Beispiel ermöglicht auch das Zoomen, was für eine Website, aber nicht für eine Webanwendung wünschenswert sein kann. 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 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 und low-dpi.

Wenn du deine Webseite für unterschiedliche Bildschirmdichten anpassen möchtest, verwende die CSS-Medienabfrage -webkit-device-pixel-ratio und/oder das Attribut window.devicePixelRatio in JavaScript und setze dann die Meta-Property target-densitydpi auf device-dpi. Dadurch wird Android daran gehindert, auf Ihrer Webseite zu skalieren, und Sie können über CSS und JavaScript die erforderlichen Anpassungen für jede Dichte vornehmen.

Weitere Informationen zur Ausrichtung auf Geräteauflösungen findest du in der WebView-Dokumentation von Android.

Surfen im Vollbildmodus

Es gibt zwei weitere iOS-spezifische Meta-Werte. apple-mobile-web-app-capable und apple-mobile-web-app-status-bar-style rendern Seiteninhalte im app-ähnlichen Vollbildmodus 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 Metaoptionen 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 auf dem Startbildschirm der Nutzenden ein auffälliges app-ähnliches Symbol erstellt, wenn sie Ihre Website als Lesezeichen speichern:

 <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 Snippet aus dem Abschnitt <head> von html5rocks, das alles zusammenführt:

 <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 praktischer, vertikal zu scrollen als horizontal. Für Mobilgeräte empfiehlt es sich, den Inhalt in einem einspaltigen vertikalen Layout darzustellen. Für html5rocks haben wir CSS3-Medienabfragen verwendet, um ein solches Layout zu erstellen. Und das, ohne das Markup zu ändern.

Index der Anleitungen. Anleitung HTML5-Funktionsseite. Seite mit Autorenprofilen.
Einspaltiges vertikales Layout auf der gesamten Website

Optimierung für Mobilgeräte

Die meisten Optimierungen, die wir vorgenommen haben, hätten von vornherein hätte vorgenommen werden sollen. Dazu gehören die Reduzierung der Anzahl der Netzwerkanfragen, die JS/CSS-Komprimierung, die GZIP-Komprimierung (in der App Engine kostenlos verfügbar) und die Minimierung von DOM-Manipulationen. Diese Methoden sind gängige Best Practices, werden jedoch gelegentlich übersehen, wenn eine Website so schnell zur Verfügung steht.

Adressleiste automatisch ausblenden

Bei mobilen Browsern gibt es nicht so viel Platz auf dem Bildschirm wie bei Desktop-Browsern. Auf verschiedenen Plattformen sehen Sie manchmal eine große ältere Adressleiste oben auf dem Bildschirm, auch wenn die Seite fertig geladen ist.

Eine einfache Möglichkeit besteht darin, mithilfe von JavaScript auf der Seite zu scrollen. Selbst wenn Sie dies nur um ein Pixel tun, wird die lästige Adressleiste geschützt. Um das Ausblenden der Adressleiste auf html5rocks zu erzwingen, habe ich einen onload-Event-Handler an das window-Objekt angehängt und die Seite vertikal um ein Pixel gescrollt:

Adressleiste.
Hässliche Adressleiste belegt mehr Platz auf dem Bildschirm.
  // Hides mobile browser's address bar when page is done loading.
  window.addEventListener('load', function(e) {
    setTimeout(function() { window.scrollTo(0, 1); }, 1);
  }, false);

Dieser Listener wurde in unsere Vorlagenvariable is_mobile gepackt, da er auf dem Desktop nicht benötigt wird.

Netzwerkanfragen reduzieren, Bandbreite sparen

Es ist bekannt, dass eine geringere Anzahl von HTTP-Anfragen die Leistung erheblich verbessern kann. Mobilgeräte begrenzen die Anzahl der gleichzeitigen Verbindungen, die der Browser herstellen kann, weiter, sodass mobile Websites noch stärker von der Reduzierung dieser irrelevanten Anfragen profitieren. Außerdem ist es wichtig, jedes Byte einzusparen, da die Bandbreite auf Smartphones oft begrenzt ist. Sie können Nutzern Geld kosten!

Im Folgenden sind einige der Ansätze aufgeführt, die wir gewählt haben, um Netzwerkanfragen zu minimieren und die Bandbreite auf html5rocks zu reduzieren:

  • iFrames entfernen – iFrames sind langsam! Ein großer Teil unserer Latenz stammte von Freigabe-Widgets von Drittanbietern (Buzz, Google Friend Connect, Twitter, Facebook) auf Anleitungsseiten. 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 wurde Markup ausgeblendet, wenn es nicht in das mobile Profil gepasst hat. Ein gutes Beispiel waren die vier abgerundeten Felder oben auf der Startseite:

Schaltflächen auf der Startseite
Feld-Schaltflächen auf der Startseite.

Auf der mobilen Website fehlen sie. Denken Sie daran, dass der Browser weiterhin eine Anfrage für jedes Symbol stellt, auch wenn deren Container mit display:none ausgeblendet ist. Daher reichte es nicht aus, diese Schaltflächen einfach auszublenden. Dadurch würde nicht nur Bandbreite verschwendet, der Nutzer würde die Früchte dieser verschwendeten Bandbreite nicht einmal sehen. Die Lösung bestand darin, den booleschen Wert "is_mobile" in unserer Django-Vorlage zu erstellen, um HTML-Abschnitte bedingt auszulassen. Wenn der Nutzer die Website auf einem Smart-Home-Gerät aufruft, werden die Schaltflächen ausgelassen.

  • Anwendungs-Cache: Dies ermöglicht uns nicht nur Offline-Support, sondern ermöglicht auch einen schnelleren Start.

  • CSS/JS-Komprimierung: Wir verwenden den YUI-Komprimierungsprogramm anstelle des Closure-Compilers, weil er sowohl CSS als auch JS verarbeitet. Ein Problem, das uns auftrat, war, dass Inline-Medienabfragen (Medienabfragen, die in einem Stylesheet angezeigt werden) in YUI Compressor 2.4.2 verschoben wurden (siehe dieses Problem). Mit YUI Compressor 2.4.4+ wurde das Problem behoben.

  • Verwendung von CSS-Bild-Sprites nach Möglichkeit

  • PNGCrush wurde für die Bildkomprimierung verwendet.

  • DataURIs wurden für kleine Bilder verwendet. Mit der Base64-Codierung wird das Bild um ca. 30%größer, die Netzwerkanfrage wird aber eingespart.

  • Die benutzerdefinierte Suche von Google wurde automatisch mit einem einzelnen Skript-Tag statt dynamisch mit google.load() geladen. Letzteres stellt eine zusätzliche 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 toll, führt aber bei jedem Laden eine Reihe von Tests durch. Bei einigen dieser Tests werden kostspielige Änderungen am DOM vorgenommen und der Seitenaufbau verlangsamt. Jetzt binden wir diese Bibliotheken nur auf Seiten ein, auf denen sie 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 wurden entfernt.
  • Im Cache gespeicherte DOM-Suchen und minimierte DOM-Manipulationen – Jedes Mal, wenn Sie das DOM berühren, führt der Browser eine Umformatierung durch. Reflows sind auf Mobilgeräten noch kostspieliger.
  • Überflüssigen clientseitiger Code wurde auf den Server ausgelagert. Insbesondere wird geprüft, ob der Navigationsstil der aktuellen Seite festgelegt wurde: 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%“ oder „width:auto“ ersetzt.

Anwendungscache

Die mobile Version von html5rocks verwendet den Anwendungscache, um den anfänglichen Ladevorgang zu beschleunigen und Nutzern das Lesen von Inhalten offline zu ermöglichen.

Bei der Implementierung von AppCache auf Ihrer Website ist es sehr wichtig, dass Sie die Manifestdatei nicht im Cache speichern (entweder explizit in der Manifestdatei selbst oder implizit mit umfangreichen Cachesteuerungsheadern). Wenn Ihr Manifest vom Browser im Cache gespeichert wird, ist das Debuggen ein Albtraum. iOS und Android speichern diese Datei besonders gut im Cache, bieten aber keine bequeme Möglichkeit, den Cache zu leeren, wie dies bei Desktop-Browsern der Fall ist.

Um eine besagte Cache-Speicherung für unsere Website zu verhindern, haben wir zunächst App Engine so eingestellt, dass Manifest-Dateien 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 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);

Um Netzwerkverkehr einzusparen, sollte dein Manifest einfach sein. Nennen Sie nicht jede Seite Ihrer Website. Listen Sie einfach die wichtigen Bilder, CSS und JavaScript-Dateien auf. Als Letztes möchten Sie den mobilen Browser zwingen, bei jeder Appcache-Aktualisierung eine große Anzahl von Assets herunterzuladen. Denke stattdessen daran, dass der Browser eine HTML-Seite implizit im Cache speichert, wenn der Nutzer sie besucht (und sie enthält das Attribut <html manifest="...">).