Ich optimiere wordpress speed ohne Plugins mit manuellen Eingriffen, die Ladezeiten sichtbar senken und Core Web Vitals zuverlässig treffen. So halte ich die Kontrolle über Requests, Ressourcen und Nebenwirkungen und eliminiere Ballast an der Quelle.
Zentrale Punkte
- Bilder konsequent vor dem Upload komprimieren und ins WebP-Format konvertieren
- Lazy Loading nativ per HTML-Attribut statt überlastete Erweiterungen
- Caching via .htaccess/Server und saubere Header-Strategie
- Code minimieren, bündeln und Render-Blocker vermeiden
- Ballast in WordPress, Datenbank und Themes entfernen
Warum ich ohne Plugins optimiere
Plugins wirken bequem, doch sie addieren Requests, Skripte und Styles, die initiale Renderpfade blockieren und meinen TTFB verschlechtern. Jede zusätzliche Abhängigkeit erhöht die Fehlerfläche und erschwert die Ursachenanalyse bei Performance-Einbrüchen. Mit manuellen Maßnahmen reduziere ich Ladeketten und halte die Anzahl aktiver Komponenten minimal. So senke ich Overhead, bleibe flexibel und reagiere schneller auf neue Anforderungen. Dieser Ansatz verhindert Nebenwirkungen durch Update-Ketten und hält die Wartung schlank.
Bilder schlank machen: Formate, Größen, Kompression
Große Bilder killen Time-to-First-Byte nicht, aber sie dominieren Transferzeit und LCP, daher reduziere ich jedes Asset vorab. Ich exportiere Fotos als JPEG oder WebP und nutze PNG nur bei echten Transparenzen. Ich skaliere die Abmessungen exakt auf die benötigten Viewport-Breiten, statt 4000px zu laden, wenn 800px reichen. Anschließend komprimiere ich konsequent mit Squoosh, ImageOptim oder Photoshop und prüfe sichtbare Artefakte. Für responsive Varianten setze ich auf srcset/sizes und nutze gern diesen kurzen Responsive-Images Leitfaden, damit der Browser automatisch die kleinste sinnvolle Quelle lädt und mein Datentransfer sinkt.
Lazy Loading nativ einsetzen
Ich lade Bilder und iFrames erst, wenn sie in den Viewport kommen, und zwar nativ per HTML5, statt zusätzliche Skripte einzubinden, die meinen Main-Thread belasten. Das Attribut loading=“lazy“ reicht in modernen Browsern vollkommen aus. So reduziere ich die Anzahl initialer Bytes und entzerre die kritische Renderphase. Gleichzeitig bleibt die Steuerung transparent, und ich entscheide, welche Above-the-Fold-Elemente ich bewusst eager lade. Kritische Hero-Bilder bekommen loading=“eager“, alles andere lädt versetzt.
<img src="beispiel.jpg" alt="Beispielbild" loading="lazy">
<iframe src="video.html" title="Video" loading="lazy"></iframe> LCP gezielt beschleunigen: Prioritäten und Platzhalter
Um den Largest Contentful Paint stabil zu verbessern, markiere ich mein größtes Above-the-Fold-Element explizit. Bilder erhalten fetchpriority=“high“ und definierte Abmessungen, damit der Browser sie vorzieht und CLS vermeidet. Ich ergänze bei Bedarf ein Preload, wenn der Pfad eindeutig ist.
<!-- LCP-Image priorisieren -->
<link rel="preload" as="image" href="/assets/hero.webp" imagesrcset="/assets/hero-800.webp 800w, /assets/hero-1200.webp 1200w" imagesizes="(min-width: 800px) 1200px, 100vw">
<img src="/assets/hero-800.webp"
srcset="/assets/hero-800.webp 800w, /assets/hero-1200.webp 1200w"
sizes="(min-width: 800px) 1200px, 100vw"
width="1200" height="700"
fetchpriority="high"
loading="eager"
decoding="async"
alt="Hero"> Ich setze bei Bildern und Containern Breite/Höhe oder aspect-ratio, um Layout-Sprünge auszuschließen. Für nicht-kritische Bereiche nutze ich content-visibility: auto und contain-intrinsic-size, damit der Browser Bereiche außerhalb des Viewports später rendert, ohne Layout zu verschieben.
/* Above-the-Fold reservieren */
.hero { aspect-ratio: 12 / 7; }
/* Nicht sichtbare Sektionen später layouten */
.section { content-visibility: auto; contain-intrinsic-size: 1000px; }
Browser-Caching gezielt konfigurieren
Wiederkehrende Besucher sollen statische Assets aus dem Cache laden, deshalb setze ich Ablaufzeiten direkt auf Serverebene per .htaccess oder im vHost. Lange TTLs für Bilder, moderate für CSS/JS, und kurze Defaults für HTML geben mir die Balance aus Aktualität und Geschwindigkeit. Ich achte auf konsistente Dateiversionierung, damit Updates trotz langer TTL sofort greifen. Kombiniert mit ETags oder Last-Modified-Headern sinkt der Traffic drastisch. So spare ich Bandbreite und verkürze die wahrgenommene Ladezeit.
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/pdf "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
ExpiresByType application/x-javascript "access plus 1 month"
ExpiresDefault "access plus 2 days"
</IfModule> Cache-Strategie, Versionierung und Revalidierung
Ich kombiniere lange TTLs mit Dateinamen-Hashing, damit Clients unverändert lange cachen (style.9c2a.css) und Updates sofort greifen. Bei häufig geänderten Bundles setze ich Cache-Control: public, max-age=31536000, immutable, während HTML kurze no-cache-Strategien behält. Für dynamische Antworten bevorzuge ich Conditional Requests über ETag oder Last-Modified, damit Clients sparsam revalidieren:
<IfModule mod_headers.c>
<FilesMatch "\.(css|js|woff2|png|jpe?g|gif|webp)$">
Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>
<FilesMatch "\.(html|json)$">
Header set Cache-Control "no-cache, no-store, must-revalidate"
</FilesMatch>
</IfModule> Bei Inhalten mit Format-Varianten (z. B. WebP vs. JPEG) prüfe ich, dass Vary: Accept am Edge korrekt gesetzt ist; so landen nicht die falschen Versionen im Cache. Versionierung halte ich konsistent über Build-Pipelines, damit kein Asset unkontrolliert veraltet.
CSS und JavaScript verschlanken
Ich minifiziere CSS/JS lokal in meinem Build-Prozess und entferne Kommentare, Leerzeichen und ungenutzte Selektoren. Kritische Styles für Above-the-Fold packe ich inline, den Rest lade ich asynchron oder als deferred Datei. Render-blockierende Skripte verschiebe ich ans Ende, versehe sie mit defer/async und halte die Anzahl externer Libraries klein. Bei Frameworks prüfe ich Tree-Shaking und Import-Scopes, damit ich nicht alles lade, was ich selten nutze. Wo möglich, bündele ich Dateien, um Requests zu senken, ohne das Caching hinten raus zu verschlechtern.
INP verbessern: Main-Thread entlasten
Für einen niedrigen Interaction to Next Paint zerlege ich lange Tasks in kleinere Happen, vermeide Layout-Thrashing und entkopple aufwändige Handlers von Interaktionen. Ich nutze defer für Module, setze passive Event-Listener und plane nicht-kritische Arbeit in Idle-Zeiten:
<script type="module" defer src="/assets/app.js"></script>
document.addEventListener('touchstart', onTouch, { passive: true });
const expensiveInit = () => { /* ... */ };
requestIdleCallback(expensiveInit, { timeout: 1500 });
// Lange Aufgaben aufsplitten
function chunkedWork(items) {
const batch = items.splice(0, 50);
// verarbeiten...
if (items.length) requestAnimationFrame(() => chunkedWork(items));
} Ich messe Long Tasks in DevTools, entferne doppelte Bibliotheken und ersetze jQuery-Utilities durch native APIs. DOM-Updates fasse ich zusammen, nutze transform statt top/left und halte Reflows minimal.
WordPress-Ballast abwerfen
Viele WP-Features brauche ich nicht auf produktiven Seiten, also deaktiviere ich Emojis, oEmbeds und Teile der REST-API und spare Requests. Dadurch schrumpft der Head, und weniger Skripte blockieren First Paint. Ich prüfe zusätzlich Pingbacks, RSD-Links und WLW-Manifest und schalte sie ab. Trackbacks und XML-RPC lege ich ebenfalls still, wenn sie keine Rolle spielen. So reduziere ich Angriffsfläche und halte die Startphase leicht.
// Emojis deaktivieren
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
remove_action( 'wp_print_styles', 'print_emoji_styles' );
// oEmbeds und REST API reduzieren
remove_action( 'wp_head', 'wp_oembed_add_host_js' );
add_filter('rest_enabled', '_return_false');
add_filter('rest_jsonp_enabled', '_return_false'); Drittanbieter-Skripte bändigen
Third-Party-Code ist oft der größte Bremsklotz. Ich initialisiere ihn verzögert, binde nur das Nötigste ein und lade ihn erst nach Interaktion oder Consent. Analytics/Tracking kommt async nach dem First Paint, Social-Widgets ersetze ich durch statische Links. Für iFrames nutze ich loading="lazy" und sandbox, um Nebenwirkungen zu begrenzen. YouTube-Embeds bekommen ein Vorschaubild und laden den Player erst bei Klick – das spart mehrere Requests zur Startzeit.
Datenbankpflege ohne Helfer
Ich lösche überflüssige Revisionen, leere Transients und räume Spam-Kommentare über phpMyAdmin auf, damit Abfragen schneller antworten. Autoloaded Options prüfe ich auf übermäßige Größe, denn sie landen in jeder Anfrage. In kleineren Installationen reichen ein paar gezielte SQL-Statements, um Tabellen zu optimieren. Ich kontrolliere, ob Cron-Jobs hängen und räume Postmeta auf, die alte Plugins hinterlassen haben. Regelmäßige Pflege verhindert, dass Queries ausufern und mein Backend träge wird.
System-Cron statt WP-Cron
Damit Cron-Jobs zuverlässig und performant laufen, entkopple ich sie vom Seitenaufruf. Ich deaktiviere den WP-Cron und plane echte System-Jobs, die in ruhigen Zeiten arbeiten.
// in wp-config.php
define('DISABLE_WP_CRON', true); # crontab -e (alle 5 Minuten)
*/5 * * * * /usr/bin/php -q /path/to/wp/wp-cron.php >/dev/null 2>&1 So blockiert kein Cron die Antwortzeit eines regulären Requests, und wiederkehrende Aufgaben wie Transient-Cleanup oder Sitemap-Generierung laufen planbar.
Theme, Plugins und Schriftarten kritisch prüfen
Ich entferne inaktive Themes und alle Erweiterungen, die Funktionen doppeln oder selten Nutzen bringen, damit der Autoloader weniger lädt. Für Schriften reduziere ich Varianten auf Regular/Bold und zwei Schriftschnitte, hoste sie lokal und aktiviere Preload für die Hauptdatei. Externe Ressourcen bereite ich mit DNS-Prefetch vor, wenn ich sie wirklich brauche. Für YouTube-Embeds verwende ich Vorschaubilder, um iFrames später zu initialisieren. So behalte ich Kontrolle über Renderpfade und halte die Startpayload klein.
<link rel="dns-prefetch" href="//fonts.googleapis.com">
<link rel="dns-prefetch" href="//www.youtube.com"> Schriften: Ladeverhalten, Subsetting, Fallbacks
Webfonts beeinflussen wahrgenommene Geschwindigkeit stark. Ich setze font-display: swap oder optional, damit Text sofort sichtbar ist. Variable Fonts prüfe ich kritisch und subsette Unicode-Bereiche, um Bytes zu sparen. Ein gezieltes Preload der wichtigsten WOFF2-Datei reduziert FOIT.
<link rel="preload" as="font" href="/fonts/brand-regular.woff2" type="font/woff2" crossorigin>
@font-face {
font-family: 'Brand';
src: url('/fonts/brand-regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
unicode-range: U+000-5FF; /* lateinische Grundmenge */
} Ich definiere saubere System-Fallbacks (z. B. Segoe UI, Roboto, SF Pro, Arial) in der Font-Stack, um Layout-Jumps zu minimieren. Über size-adjust gleiche ich metrische Unterschiede an, damit der Wechsel vom Fallback zur Webfont kaum sichtbar ist.
Server, PHP und Protokolle
Ohne passende Infrastruktur versandet jede Optimierung, deshalb achte ich auf schnelle SSDs, aktuelle PHP-Versionen und HTTP/2-Unterstützung. OPcache, Brotli/Gzip und HTTP/2 Multiplexing beschleunigen Auslieferung und reduzieren Blockaden. Wenn möglich, ziehe ich HTTP/3/QUIC in Betracht und prüfe Setup sowie TLS-Konfiguration sorgfältig; einen guten Einstieg liefert dieser kurze Beitrag zu HTTP/3 umsetzen. Load- und Stress-Tests zeigen mir, wie die Seite unter Last reagiert. So stelle ich sicher, dass mein Stack die Anwendung trägt und meine Maßnahmen Wirkung zeigen.
| Hosting-Anbieter | Features | Leistung | Support | Preis-Leistung |
|---|---|---|---|---|
| webhoster.de | SSD, PHP 8.*, HTTP/2 | ★★★★★ | ★★★★★ | ★★★★★ |
| Mitbewerber 1 | SSD, PHP 7.*, HTTP/2 | ★★★★☆ | ★★★★☆ | ★★★★☆ |
| Mitbewerber 2 | HDD, PHP 7.*, kein HTTP/2 | ★★★☆☆ | ★★★☆☆ | ★★★☆☆ |
PHP-FPM, OPcache und Transport optimieren
Ich stelle PHP-FPM so ein, dass Requests nicht in Warteschlangen landen. pm, pm.max_children und pm.max_requests dimensioniere ich zur Last. OPcache bekommt genug Speicher, um Recompilings zu vermeiden.
; php.ini / www.conf
opcache.enable=1
opcache.memory_consumption=256
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0
; PHP-FPM (Beispielwerte)
pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 8
pm.max_requests = 500 Auf der Transportschicht aktiviere ich Brotli vor Gzip, halte Keep-Alive offen und prüfe TLS-Resumption. Bei HTTP/2 kontrolliere ich Priorisierung, damit CSS/Schrift und LCP-Image Vorrang haben. Unter HTTP/3 beobachte ich Paketverluste und passe Pacing an.
CDN, Caching-Header und Geografie
Bei internationalem Traffic nutze ich ein Edge-Netz, um Latenz zu senken und statische Assets nah am Nutzer auszuliefern. Ich achte auf saubere Cache-Keys, Variant-Header (z. B. für WebP) und konsistente Versionierung. Kritische HTML-Seiten cache ich vorsichtig, API-Responses selektiv und Bilder aggressiv. Ein kurzer Überblick zur CDN-Optimierung hilft mir, Stolperfallen wie doppelte Komprimierung zu vermeiden. So kombiniere ich Server- und Edge-Caching und halte die Kosten im Blick.
Formate, Negotiation und Deduplizierung am Edge
Ich spiele Bilder in modernen Formaten (WebP, optional AVIF) aus und stelle sicher, dass das CDN Content-Negotiation respektiert. Wichtig sind korrekte Accept-Varianten und eine Eindeutigkeit der Cache-Keys. Double-Gzip vermeide ich, indem ich nur einmal komprimiere (Server oder Edge) und das Flag am jeweils anderen Ende deaktiviere. Für HTML setze ich konservative TTLs und strong ETags, Assets bleiben aggressiv gecacht.
Messung, Kennzahlen und Priorisierung
Ich starte mit einem klaren Performance-Budget und fokussiere mich auf LCP, CLS und INP, statt jeden Millisekundenwert isoliert zu betrachten. Field-Daten stehen über Lab-Werten, daher vergleiche ich reale Nutzersignale mit Testläufen. Waterfall-Diagramme decken blockierende Assets auf, Request-Maps zeigen doppelte Bibliotheken und unnötige Schriftdateien. Jede Änderung messe ich einzeln, um Regressions schnell zu erkennen. Erst wenn Zahlen konsistent besser werden, rolle ich sie breiter aus.
Arbeitsweise: sauber deployen, schnell zurückrollen
Ich binde Performance-Checks in meinen Deploy-Prozess ein: Builds erzeugen versionierte Artefakte, Lighthouse/DevTools-Tests laufen auf Staging, und nur geprüfte Bundles gehen live. Feature-Flags erlauben mir, riskante Änderungen kontrolliert auszurollen und bei Bedarf sofort zu deaktivieren. So halte ich Performance stabil, während ich neue Funktionen entwickle.
Kurz zusammengefasst: So setze ich es um
Ich optimiere zuerst Inhalte mit größtem Hebel: Bilder verkleinern, Lazy Loading aktivieren, kritische CSS-Teile inline und blockierende Skripte verschieben. Danach sichere ich Caching-Strategien auf Browser- und Serverseite, räume WordPress-Features und Datenbank auf und streiche unnötige Plugins. Ich prüfe Infrastruktur, HTTP/2/3, Brotli und OPcache und sorge für saubere Deployment-Prozesse mit Versionierung. Bei Bedarf ergänze ich ein CDN und reguliere Header und Variants. Abschließend kontrolliere ich Kennzahlen iterativ, bis LCP, CLS und INP stabil in grünen Bereichen liegen.


