Performance-Optimierung (GZIP, Caching, Expires Header etc.) mit Hilfe der .htaccess

Kurze Ladezeiten sind ein wichtiges Qualitätsmerkmal für Websites und werden von Google & Co. als Bewertungskriterium herangezogen. Eine Möglichkeit um die Geschwindigkeit der eigenen Seite zu erhöhen führt über die .htaccess-Datei. Hier können Ablaufdaten für verschiedene Dateitypen oder die Kompression mittels GZIP/Brotli eingerichtet werden. In diesem Beitrag archivieren wir eine Standard-Vorlage für die .htaccess.

Kompression, Caching & Performance-Optimierung in der .htaccess

Die folgende Methode funktioniert nur für Apache-Webserver, da Nginx-Server die Regeln in einer anderen Syntax und in einer anderen Datei erwarten. Bevor ihr Änderungen vornehmt, solltet ihr zunächst ein Backup der .htaccess-Datei erstellen! Anschließend könnt ihr den folgenden Code einfügen.

Zuerst werden die Medientypen (MIME-Type) definiert, die der Webserver für moderne Dateiformate (Schriften, Bilder, Videos, Audio, Manifeste) verwenden soll, damit Browser diese Dateien korrekt interpretieren und darstellen können. Danach wird festgelegt, welche Dateien komprimiert werden sollen. Standardmäßig wird dafür Gzip als Kompressions-Methode verwendet. Falls verfügbar, wird die modernere und effektivere Brotli-Methode benutzt. Anschließend werden für jeden Dateityp die Vorhaltezeiten für das Browser-Caching definiert. Für Dateien, die sich typischerweise häufig ändern (HTML, JSON etc.), sind kurze Zeiträume definiert. Für eher statische Assets (Bilder, Videos, Audio etc.) gelten dagegen lange Vorhaltezeiten.

# ----------------------------------------------------------------------
# Compression and Caching
# ----------------------------------------------------------------------

<IfModule mod_mime.c>
   # --- Manifest ---
   AddType application/manifest+json .webmanifest
   # --- Fonts ---
   AddType font/woff2 .woff2
   AddType font/woff .woff
   # --- Images ---
   AddType image/svg+xml .svg .svgz
   AddType image/webp .webp
   AddType image/avif .avif
   AddType image/x-icon .ico
   # --- Video ---
   AddType video/mp4 .mp4
   AddType video/ogg .ogv
   AddType video/webm .webm
   # --- Audio ---
   AddType audio/mpeg .mp3
   AddType audio/ogg .ogg
   AddType audio/webm .weba
</IfModule>

<IfModule mod_deflate.c>
   # Exclude already-compressed files from further compression
   <IfModule mod_setenvif.c>
      SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|webp|avif|ico|svgz|zip|gz|gzip|bz2|br|rar|7z|mp4|mp3|webm|ogv|ogg|weba|woff|woff2|pdf)$ no-gzip
   </IfModule>

   # Compress text-based MIME types
   AddOutputFilterByType DEFLATE text/html
   AddOutputFilterByType DEFLATE text/plain
   AddOutputFilterByType DEFLATE text/xml
   AddOutputFilterByType DEFLATE text/css
   AddOutputFilterByType DEFLATE text/javascript
   AddOutputFilterByType DEFLATE application/javascript
   AddOutputFilterByType DEFLATE application/x-javascript
   AddOutputFilterByType DEFLATE application/json
   AddOutputFilterByType DEFLATE application/ld+json
   AddOutputFilterByType DEFLATE application/xml
   AddOutputFilterByType DEFLATE application/xhtml+xml
   AddOutputFilterByType DEFLATE application/rss+xml
   AddOutputFilterByType DEFLATE application/atom+xml
   AddOutputFilterByType DEFLATE application/manifest+json
   AddOutputFilterByType DEFLATE image/svg+xml
</IfModule>

<IfModule mod_brotli.c>
  # Compress text-based content with Brotli (better compression than gzip)
  AddOutputFilterByType BROTLI_COMPRESS text/html
  AddOutputFilterByType BROTLI_COMPRESS text/plain
  AddOutputFilterByType BROTLI_COMPRESS text/xml
  AddOutputFilterByType BROTLI_COMPRESS text/css
  AddOutputFilterByType BROTLI_COMPRESS text/javascript
  AddOutputFilterByType BROTLI_COMPRESS application/javascript
  AddOutputFilterByType BROTLI_COMPRESS application/x-javascript
  AddOutputFilterByType BROTLI_COMPRESS application/json
  AddOutputFilterByType BROTLI_COMPRESS application/ld+json
  AddOutputFilterByType BROTLI_COMPRESS application/xml
  AddOutputFilterByType BROTLI_COMPRESS application/xhtml+xml
  AddOutputFilterByType BROTLI_COMPRESS application/rss+xml
  AddOutputFilterByType BROTLI_COMPRESS application/atom+xml
  AddOutputFilterByType BROTLI_COMPRESS application/manifest+json
  AddOutputFilterByType BROTLI_COMPRESS image/svg+xml
</IfModule>

<IfModule mod_expires.c>
   ExpiresActive On
   ExpiresDefault "access plus 0 seconds"

   # -- HTML/XML (short cache) ---
   ExpiresByType text/html "access plus 60 seconds"
   ExpiresByType application/xhtml+xml "access plus 60 seconds"
   # --- Manifest (moderate cache) ---
   ExpiresByType application/manifest+json "access plus 1 day"
   # --- Data/Feeds (short cache) ---
   ExpiresByType application/json "access plus 5 minutes"
   ExpiresByType application/ld+json "access plus 5 minutes"
   ExpiresByType application/xml "access plus 5 minutes"
   ExpiresByType text/xml "access plus 5 minutes"
   ExpiresByType application/rss+xml "access plus 5 minutes"
   ExpiresByType application/atom+xml "access plus 5 minutes"
   # --- CSS/JS (long cache) ---
   ExpiresByType text/css "access plus 1 year"
   ExpiresByType text/javascript "access plus 1 year"
   ExpiresByType application/javascript "access plus 1 year"
   ExpiresByType application/x-javascript "access plus 1 year"
   # --- Fonts (long cache) ---
   ExpiresByType font/woff "access plus 1 year"
   ExpiresByType font/woff2 "access plus 1 year"
   # --- Images (long cache) ---
   ExpiresByType image/avif "access plus 1 year"
   ExpiresByType image/gif "access plus 1 year"
   ExpiresByType image/jpeg "access plus 1 year"
   ExpiresByType image/png "access plus 1 year"
   ExpiresByType image/svg+xml "access plus 1 year"
   ExpiresByType image/webp "access plus 1 year"
   ExpiresByType image/x-icon "access plus 1 year"
   # --- Video (long cache) ---
   ExpiresByType video/mp4 "access plus 1 year"
   ExpiresByType video/ogg "access plus 1 year"
   ExpiresByType video/webm "access plus 1 year"
   # -- Audio: long cache ---
   ExpiresByType audio/mpeg "access plus 1 year"
   ExpiresByType audio/ogg "access plus 1 year"
   ExpiresByType audio/webm "access plus 1 year"
   # --- Other (long cache) ---
   ExpiresByType application/pdf "access plus 1 year"
</IfModule>

<IfModule mod_headers.c>
   # Remove ETag (rely on Cache-Control instead for better CDN compatibility)
   Header unset ETag
   FileETag None

   # Set Vary header for content negotiation
   Header set Vary "Accept-Encoding"

   # Security headers
   Header always set X-Content-Type-Options "nosniff"

   # Remove WordPress headers from static assets
   <FilesMatch "\.(css|js|jpg|jpeg|png|gif|webp|avif|svg|svgz|ico|woff|woff2|mp4|mp3|ogg|ogv|webm|weba|pdf|json|xml|webmanifest)$">
      Header unset Pragma
      Header unset Set-Cookie
   </FilesMatch>

   # -- HTML/XML (short cache) ---
   <FilesMatch "\.(html|htm|xhtml)$">
      Header set Cache-Control "public, max-age=60, stale-while-revalidate=86400"
   </FilesMatch>

   # --- Manifest (moderate cache) ---
   <FilesMatch "\.webmanifest$">
      Header set Cache-Control "public, max-age=86400"
   </FilesMatch>

   # --- Data/Feeds (short cache) ---
   <FilesMatch "\.(json|xml)$">
      Header set Cache-Control "public, max-age=300, stale-if-error=3600"
   </FilesMatch>

   # --- CSS/JS (long cache) ---
   <FilesMatch "\.(css|js)$">
      Header set Cache-Control "public, max-age=31536000, immutable"
   </FilesMatch>

   # --- Fonts (long cache) ---
   <FilesMatch "\.(woff|woff2)$">
      Header set Cache-Control "public, max-age=31536000, immutable"
      Header set Access-Control-Allow-Origin "*"
   </FilesMatch>

   # --- Images (long cache) ---
   <FilesMatch "\.(jpg|jpeg|png|gif|webp|avif|svg|svgz|ico)$">
      Header set Cache-Control "public, max-age=31536000, immutable"
   </FilesMatch>

   # --- Video (long cache) ---
   <FilesMatch "\.(mp4|webm|ogv)$">
      Header set Cache-Control "public, max-age=31536000, immutable"
   </FilesMatch>

   # -- Audio: long cache ---
   <FilesMatch "\.(mp3|ogg|weba)$">
      Header set Cache-Control "public, max-age=31536000, immutable"
   </FilesMatch>

   # --- Other (long cache) ---
   <FilesMatch "\.pdf$">
      Header set Cache-Control "public, max-age=31536000, immutable"
   </FilesMatch>
</IfModule>

Feedback & Ergänzungen – 2 Kommentare

  1. Danny Patterson
    schrieb am 06.06.2019 um 20:11 Uhr:

    Hallo Jonas,

    wie sieht es bzgl. der Performance aus? Sollte man hierbei nicht nur das übernehmen was man auch wirklich auf der Webseite / Shop / Blog verwendet? Schliesslich müsste der Webserver diese auch komplett bei jedem Aufruf verarbeiten und entsprechende Module aktivieren, die eventuell nicht vorhanden sind.

    Ich versuche gerade bei den Umleitungen, Cache und auch beim Quellcode immer nur so wenig wie möglich und so viel wie nötig zu verwenden. Gerade was die ganzen Schriftarten angeht, wenn man entsprechende nicht verwendet spart man sich hier auch eine Menge an unnötigen Text und schafft mehr „Übersicht“.

    Antworten
    • Jonas Hellwig
      schrieb am 07.06.2019 um 09:37 Uhr:

      Hallo Danny, du hast vollkommen recht. Dieser Beitrag fasst einige mögliche Optimierungen zum schnellen Copy+Paste zusammen. Hier je nach Bedarf anzupassen macht durchaus Sinn.

      Antworten

Kommentar zu dieser Seite

Wir freuen uns über Anregungen, Ergänzungen oder Hinweise zu Fehlern. Wir lesen jeden Eintrag, veröffentlichen aber nur, was den Inhalt sinnvoll ergänzt.

Geschrieben von:

Jonas Hellwig

Benutzerbild

Jonas ist Gründer von kulturbanause und des kulturbanause Blogs. Er arbeitet an der Schnittstelle zwischen UX/UI Design, Frontend und Redaktion und hat zahlreiche Fachbücher und Video-Trainings veröffentlicht. Jonas Hellwig ist regelmäßig als Sprecher auf Fachveranstaltungen anzutreffen und unterstützt mit Seminaren und Workshops Agenturen und Unternehmen bei der Planung, der Gestaltung und der technischen Umsetzung von Web-Projekten.

Jonas Hellwig bei Mastodon, LinkedIn, Xing und YouTube.

Konstantin Hanke

Benutzerbild

Konstantin arbeitet als Webentwickler bei kulturbanause. Seine Hauptaufgabe ist die technische Umsetzung von klaren, soliden und effizienten Webauftritten und Website-Komponenten. Darüber hinaus kümmert er sich um die Wartung, Optimierung und Weiterentwicklung von bestehenden Websites. Sein besonderes Interesse gilt der Idee von quelloffener, freier Software.

Projekte mit kulturbanause

Wir wissen wovon wir reden. Wir realisieren komplette Projekte oder unterstützen punktuell in den Bereichen Design, Development, Strategy und Content.

Design + Code

Schulungen von kulturbanause

Wir bieten Seminare und Workshops zu den Themen Konzept, Design und Development. Immer up-to-date, praxisnah, kurzweilig und mit dem notwendigen Blick über den Tellerrand.

Schulung + Beratung