jQuery hat über ein Jahrzehnt lang echte Browser-Kompatibilitätsprobleme gelöst. 2008, als dieser Artikel erstmals veröffentlicht wurde, war das Schreiben von Cross-Browser-JavaScript ohne jQuery wirklich schmerzhaft. Internet Explorer 6 behandelte Events anders, CSS-Selektoren waren inkonsistent und AJAX erforderte browserspezifische XMLHttpRequest-Implementierungen.
Erfahre mehr über WordPress-Geschwindigkeitsoptimierung bei WPPoland.
2026 wird jedes Problem, das jQuery löste, nativ von Browsern behandelt. Die Frage ist nicht mehr ob man migrieren sollte, sondern wie man es sicher tut, ohne bestehende Funktionalität zu beschädigen.
Warum jQuery 2026 technische Schulden darstellt
jQuery 3.7 wiegt 87KB unkomprimiert (30KB gzipped). Das mag wenig klingen, aber bedenke, was es kostet:
- Total Blocking Time (TBT): jQuery muss geparst und ausgeführt werden, bevor abhängiger Code laufen kann. Auf Mittelklasse-Mobilgeräten fügt das 150-300ms zur TBT hinzu.
- Interaction to Next Paint (INP): jQuerys Event-Delegationssystem fügt jeder Benutzerinteraktion Overhead hinzu und verschlechtert messbar die INP-Werte.
- Abhängigkeitskette: Das Laden von jQuery bedeutet, dass jedes davon abhängige Script warten muss, was eine Kaskade blockierender Ressourcen erzeugt.
- Redundanter Code: Jede jQuery-Methode, die du aufrufst, hat ein natives Äquivalent, das der Browser bereits mitbringt. Du bezahlst doppelt für dieselbe Funktionalität.
Performance-Benchmarks: jQuery vs Vanilla JS
Reale Messungen an einem WordPress-Theme mit typischen Interaktionen (Menü-Toggle, Tab-Wechsel, Formularvalidierung, AJAX-Nachladen):
| Metrik | Mit jQuery | Ohne jQuery | Verbesserung |
|---|---|---|---|
| Gesamte JS-Grösse | 142KB | 55KB | -61% |
| TBT (mobil) | 480ms | 180ms | -62% |
| INP (p75) | 220ms | 95ms | -57% |
| LCP | 2.1s | 1.7s | -19% |
| Lighthouse Performance | 72 | 94 | +22 Punkte |
Diese Zahlen stammen von einer produktiven WordPress-Website mit GeneratePress und WooCommerce, getestet auf einem Moto G Power (einem repräsentativen Mittelklassegerät).
Modernes JavaScript (ES2024+) ersetzt jedes jQuery-Muster
Die ES2024-Spezifikation, vollständig unterstützt in Chrome 124+, Firefox 126+, Safari 17.4+ und Edge 124+, bietet native Alternativen für jedes gängige jQuery-Muster.
DOM-Selektion
// jQuery
const $buttons = $('.btn');
const $container = $('#main-container');
const $firstItem = $('.menu-item:first');
// Vanilla JS (ES2024+)
const buttons = document.querySelectorAll('.btn');
const container = document.getElementById('main-container');
const firstItem = document.querySelector('.menu-item');
// Scoped-Selektion (wie jQuery .find())
const navLinks = container.querySelectorAll('a.nav-link');
Wichtiger Unterschied: querySelectorAll gibt eine statische NodeList zurück, keine Live-Collection. Das ist tatsächlich sicherer, weil sich die Liste nicht unerwartet ändert, wenn der DOM mutiert.
Event-Handling
// jQuery
$('.btn').click(function () {
$(this).toggleClass('active');
});
$('.menu').on('click', '.menu-item', function () {
// delegiertes Event
});
// Vanilla JS
document.querySelectorAll('.btn').forEach(btn => {
btn.addEventListener('click', () => {
btn.classList.toggle('active');
});
});
// Event-Delegation (ersetzt .on() mit Selektor)
document.querySelector('.menu').addEventListener('click', (e) => {
const item = e.target.closest('.menu-item');
if (item) {
// Menüelement-Klick behandeln
}
});
Die Methode closest() ist das moderne Äquivalent zum delegierten Event-Matching von jQuery. Sie traversiert den DOM-Baum nach oben, um den nächsten Vorfahren zu finden, der einem Selektor entspricht.
Klassen-Manipulation
// jQuery
$el.addClass('active');
$el.removeClass('hidden');
$el.toggleClass('open');
$el.hasClass('visible');
// Vanilla JS
el.classList.add('active');
el.classList.remove('hidden');
el.classList.toggle('open');
el.classList.contains('visible');
// Mehrere Klassen gleichzeitig
el.classList.add('active', 'highlighted', 'animate-in');
el.classList.remove('hidden', 'collapsed');
AJAX mit fetch API und async/await
// jQuery
$.ajax({
url: '/wp-json/wp/v2/posts',
method: 'GET',
data: { per_page: 5 },
success: function (posts) { renderPosts(posts); },
error: function (xhr) { console.error(xhr); }
});
// Vanilla JS (modernes async/await)
async function loadPosts() {
try {
const response = await fetch('/wp-json/wp/v2/posts?per_page=5');
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const posts = await response.json();
renderPosts(posts);
} catch (error) {
console.error('Laden der Beiträge fehlgeschlagen:', error);
}
}
// POST mit Nonce (WordPress-Muster)
async function submitForm(data) {
const response = await fetch('/wp-json/custom/v1/submit', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': wpApiSettings.nonce,
},
body: JSON.stringify(data),
});
return response.json();
}
Animationen ohne jQuery
jQuerys .fadeIn(), .slideDown() und .animate() können durch CSS-Transitions, CSS-Animationen oder die Web Animations API ersetzt werden.
// jQuery
$('.panel').slideDown(300);
$('.modal').fadeIn(200);
// CSS-Ansatz (bevorzugt für Performance)
// In CSS:
// .panel { max-height: 0; overflow: hidden; transition: max-height 0.3s ease; }
// .panel.open { max-height: 500px; }
// In JS:
panel.classList.add('open');
// Web Animations API (für komplexe, programmatische Animationen)
modal.animate(
[
{ opacity: 0, transform: 'scale(0.95)' },
{ opacity: 1, transform: 'scale(1)' },
],
{ duration: 200, easing: 'ease-out', fill: 'forwards' }
);
Die Web Animations API läuft auf dem Compositor-Thread, was bedeutet, dass Animationen den Haupt-Thread nicht blockieren. jQuery-Animationen laufen auf dem Haupt-Thread und verursachen Jank auf langsameren Geräten.
DOM-Manipulation
// jQuery
$('<div class="notice">Hallo</div>').appendTo('#container');
$('.old-element').replaceWith('<span>Neu</span>');
$('.item').remove();
$('.list').empty();
// Vanilla JS
const notice = document.createElement('div');
notice.className = 'notice';
notice.textContent = 'Hallo';
container.append(notice);
// Oder insertAdjacentHTML für HTML-Strings verwenden
container.insertAdjacentHTML('beforeend', '<div class="notice">Hallo</div>');
// Ersetzen
oldElement.replaceWith(Object.assign(document.createElement('span'), { textContent: 'Neu' }));
// Entfernen
item.remove();
// Leeren
list.replaceChildren();
Document ready
// jQuery
$(document).ready(function () { /* ... */ });
$(function () { /* Kurzform */ });
// Vanilla JS
document.addEventListener('DOMContentLoaded', () => {
// DOM ist bereit
});
// Oder platziere dein <script>-Tag mit type="module" am Ende des <body>
// Module werden standardmässig deferred, sodass der DOM bereits bereit ist
Web Components: der moderne Ersatz für jQuery-Plugins
jQuery-Plugins boten wiederverwendbare UI-Komponenten (Slider, Modals, Tabs, Akkordeons). 2026 bieten Web Components eine standardbasierte Alternative mit besserer Kapselung.
Beispiel: eine Toggle-Panel-Komponente
class TogglePanel extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
const title = this.getAttribute('title') || 'Umschalten';
this.shadowRoot.innerHTML = `
<style>
:host { display: block; margin: 1rem 0; }
button {
width: 100%; padding: 0.75rem 1rem;
background: #f5f5f5; border: 1px solid #ddd;
cursor: pointer; text-align: left;
font-size: 1rem; font-weight: 600;
}
.content {
display: none; padding: 1rem;
border: 1px solid #ddd; border-top: none;
}
:host([open]) .content { display: block; }
</style>
<button part="trigger">${title}</button>
<div class="content"><slot></slot></div>
`;
this.shadowRoot.querySelector('button').addEventListener('click', () => {
this.toggleAttribute('open');
});
}
}
customElements.define('toggle-panel', TogglePanel);
Verwendung in HTML:
<toggle-panel title="Versandinformationen">
<p>Kostenloser Versand bei Bestellungen über 50 EUR.</p>
</toggle-panel>
Web Components bieten Shadow-DOM-Kapselung (Styles lecken nicht nach aussen), Slots für Content-Projektion und Lifecycle-Callbacks. Sie funktionieren in jedem modernen Browser ohne Polyfills.
Wann Web Components vs. ein Framework verwenden
| Szenario | Empfehlung |
|---|---|
| Einfaches interaktives Widget (Akkordeon, Tabs, Modal) | Web Component |
| Vollständige SPA (Single Page Application) | React / Vue / Svelte |
| WordPress-Block (Gutenberg) | React (WordPress-Standard) |
| Geteilte Komponente über mehrere Websites | Web Component |
| Komplexes State Management | Framework mit State-Bibliothek |
Migrationsstrategie für WordPress-Projekte
Schritt 1: jQuery-Nutzung prüfen
Führe diesen Befehl in deinem Theme-Verzeichnis aus, um alle jQuery-Referenzen zu finden:
grep -rn '\$(\|jQuery\.\|jQuery(' --include='*.js' --include='*.php' .
Kategorisiere jede Nutzung:
- Dein Code (Theme/eigenes Plugin): migriere das
- Drittanbieter-Plugin: lass es, das Plugin verwaltet seine eigenen Abhängigkeiten
- WordPress-Admin: nicht anfassen, der WordPress-Core kümmert sich darum
Schritt 2: Erstelle einen Migrationsplan
Priorisiere nach Auswirkung:
- Frontend-Theme-Code (betrifft jeden Besucher) - zuerst migrieren
- Eigenes Plugin-Frontend - als zweites migrieren
- Admin-Anpassungen - zuletzt migrieren (weniger Traffic)
Schritt 3: Muster schrittweise ersetzen
Schreibe nicht alles auf einmal um. Ersetze eine Datei nach der anderen:
- Entferne
array('jquery')aus dem Abhängigkeits-Array der Datei inwp_enqueue_script - Ersetze alle jQuery-Muster durch Vanilla-JS-Äquivalente
- Teste in Chrome, Firefox, Safari und Edge
- Teste mit allen aktiven Plugins
- Führe Lighthouse vorher und nachher aus, um die Verbesserung zu messen
Schritt 4: Das WordPress-AJAX-Muster behandeln
WordPress Legacy-AJAX verwendet admin-ajax.php mit jQuery:
// Altes Muster (jQuery + admin-ajax)
jQuery.post(ajaxurl, {
action: 'my_custom_action',
nonce: myData.nonce,
post_id: 123,
}, function (response) {
console.log(response);
});
// Modernes Muster (fetch + REST API)
async function myCustomAction(postId) {
const response = await fetch('/wp-json/myplugin/v1/action', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': myData.nonce,
},
body: JSON.stringify({ post_id: postId }),
});
return response.json();
}
Der REST-API-Ansatz ist schneller (kein admin-ajax.php-Overhead), besser cachebar und folgt modernen WordPress-Entwicklungsstandards.
Schritt 5: Scripts korrekt einbinden
// Vorher (mit jQuery-Abhängigkeit)
wp_enqueue_script(
'my-theme-scripts',
get_template_directory_uri() . '/js/main.js',
array('jquery'),
'1.0.0',
true
);
// Nachher (ohne jQuery, mit Modul-Unterstützung)
wp_enqueue_script_module(
'my-theme-scripts',
get_template_directory_uri() . '/js/main.js',
array(),
'2.0.0'
);
WordPress 6.5+ unterstützt wp_enqueue_script_module(), das Scripts als ES-Module mit type="module" lädt und native import/export-Syntax ermöglicht.
Wann jQuery beizubehalten noch sinnvoll ist
jQuery kann weiterhin gerechtfertigt sein, wenn:
- Legacy-Codebasis mit über 50 jQuery-Plugin-Abhängigkeiten: Die Migrationskosten übersteigen den Performance-Gewinn. Plane ein schrittweises Auslaufen über 6-12 Monate.
- WordPress-Admin-Anpassungen: Der Admin-Bereich lädt jQuery bereits. Eigene Admin-Scripts mit jQuery-Abhängigkeit hinzuzufügen kostet nichts extra.
- Anforderungen von Drittanbieter-Plugins: Einige beliebte Plugins (bestimmte Formular-Builder, Page-Builder) erfordern jQuery. Kämpfe nicht gegen die Abhängigkeit, wenn du sie nicht kontrollieren kannst.
- Wissenslücken im Team: Wenn dein Entwicklungsteam nicht vertraut mit modernem JS ist, investiere in Schulung vor einer erzwungenen Migration. Das Verständnis dessen, was ein WordPress-Entwickler tut, hilft dabei, realistische Erwartungen an die während der Migration benötigten Fähigkeiten zu setzen.
Das Ziel ist pragmatische Verbesserung, nicht ideologische Reinheit. Entferne jQuery dort, wo es Performance kostet und keinen Mehrwert bietet. Behalte es dort, wo das Entfernen Dinge kaputt machen oder mehr kosten würde, als es einspart.
ES2024+-Funktionen, die gängige jQuery-Utilities ersetzen
Strukturierter Klon (Deep Copy)
// jQuery
const copy = $.extend(true, {}, original);
// ES2024+
const copy = structuredClone(original);
Array-ähnliche Iteration
// jQuery
$.each(items, function (index, item) { /* ... */ });
// ES2024+
items.forEach((item, index) => { /* ... */ });
// Oder mit Array.from für NodeLists
Array.from(document.querySelectorAll('.item')).map(item => item.textContent);
// Oder Spread-Operator
[...document.querySelectorAll('.item')].filter(item => item.dataset.active);
Deferred/Promise-Muster
// jQuery
const deferred = $.Deferred();
deferred.resolve('fertig');
deferred.promise().then(val => console.log(val));
// ES2024+
const promise = new Promise((resolve) => resolve('fertig'));
promise.then(val => console.log(val));
// Promise.withResolvers() - ES2024-Funktion
const { promise, resolve, reject } = Promise.withResolvers();
IntersectionObserver (ersetzt jQuery-Scroll-Handler)
// jQuery (teurer Scroll-Handler)
$(window).scroll(function () {
$('.lazy-image').each(function () {
if ($(this).offset().top < $(window).scrollTop() + $(window).height()) {
$(this).attr('src', $(this).data('src'));
}
});
});
// Vanilla JS (performant, außerhalb des Haupt-Threads)
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img);
}
});
});
document.querySelectorAll('.lazy-image').forEach(img => observer.observe(img));
Alternativen durch Utility-Bibliotheken (wenn du einen Helper brauchst)
Wenn du dieselben Vanilla-JS-Muster immer wieder schreibst, ziehe eine Micro-Library statt jQuery in Betracht:
| Bibliothek | Grösse | Zweck |
|---|---|---|
| Alpine.js | 15KB | Deklarative Reaktivität (x-data, x-on) |
| htmx | 14KB | AJAX, WebSocket, SSE über HTML-Attribute |
| Petite-Vue | 6KB | Vue-kompatible Template-Syntax |
| Keine (Vanilla) | 0KB | Beste Performance, volle Kontrolle |
Für WordPress-Themes 2026 ist die Empfehlung Vanilla JS für einfache Interaktionen und Alpine.js oder htmx, wenn du deklaratives Verhalten ohne volles Framework benötigst.
jQuery best practices in 2026
Wenn du noch jQuery-Code pflegst - ob aus eigener Wahl oder weil eine Legacy-Codebasis es erfordert - minimieren diese Praktiken den Schaden:
- Lade jQuery aus dem WordPress-Core, niemals von einem CDN. WordPress bündelt eine kompatible Version. Eine zweite Kopie von
cdnjsodercode.jquery.comzu laden bedeutet doppeltes Gewicht und potenzielle Versionskonflikte. - Verwende
jQuerystatt$in WordPress. WordPress führt jQuery im No-Conflict-Modus aus. Code injQuery(function($) { ... })zu wrappen verhindert Kollisionen mit anderen Bibliotheken. - Vermeide verschachteltes
.ready(). Ein einzigesjQuery(function($) { ... })reicht aus. Verschachtelte.ready()-Aufrufe erzeugen Callback-Pyramiden und verwirren die Ausführungsreihenfolge. - Cache Selektoren. Jeder
$('.my-class')-Aufruf durchläuft den DOM. Speichere Ergebnisse in einer Variablen, wenn du denselben Selektor mehr als einmal verwendest. - Delegiere Events statt sie an einzelne Elemente zu binden. Verwende
$(parent).on('click', '.child', handler)statt$('.child').click(handler). Das behandelt dynamisch hinzugefügte Elemente und verwendet weniger Event-Listener. - Verwende jQuery nicht für CSS-Animationen. Verwende CSS-Transitions oder die Web Animations API. jQuerys
.animate()läuft auf dem Haupt-Thread und verursacht Jank. - Setze
jqueryals Abhängigkeit nur wenn nötig. Wenn eine Script-Datei jQuery nicht verwendet, entferne es aus dem Abhängigkeits-Array vonwp_enqueue_script, um unnötiges Laden von jQuery zu vermeiden.
Neueste jQuery-Version und was sich geändert hat
Stand 2026 ist jQuery 3.7.1 die neueste stabile Version (veröffentlicht im August 2023). jQuery 4.0.0-beta.2 befindet sich seit Februar 2024 in der Beta-Phase, ohne angekündigtes stabiles Release-Datum.
jQuery-4.0-Änderungen, die für WordPress relevant sind:
| Änderung | Auswirkung |
|---|---|
| Lässt IE-11-Support fallen | Kein Effekt - WordPress 6.6+ hat IE 11 bereits abgeschafft |
Entfernt veraltete APIs (.click(), .bind(), .delegate()) | Plugins, die diese verwenden, werden nicht mehr funktionieren |
| Kleineres Bundle (~68KB vs 87KB) | Bescheidene Verbesserung, immer noch schwerer als kein jQuery |
FormData-basiertes $.ajax() für Datei-Uploads | Schöneres API, aber fetch() kann das nativ |
Der WordPress-Core liefert derzeit jQuery 3.7.1 aus und hat sich nicht verpflichtet, Version 4.0 zu bündeln. Die praktische Erkenntnis: Warte nicht auf jQuery 4, um die Performance zu verbessern. Migriere zu Vanilla JS wo möglich und verwende jQuery-3.7.1-Best-Practices dort, wo eine Migration noch nicht machbar ist.
Wer verwendet jQuery noch in 2026
jQuery wird auf geschätzten 77% aller Websites geladen (laut W3Techs), hauptsächlich weil WordPress, Shopify und Legacy-Enterprise-Websites es standardmässig einbinden. Aber “geladen” bedeutet nicht “benötigt”.
Die Aufschlüsselung:
- WordPress-Websites: jQuery wird auf praktisch jeder WordPress-Seite geladen, weil die Admin-Bar und viele beliebte Plugins davon abhängen. Im Frontend ist die tatsächliche Abhängigkeit oft nur ein oder zwei Scripts.
- Shopify-Themes: Die meisten Shopify-Themes bündeln jQuery für Warenkorb-Interaktionen. Shopify hat keine Pläne, es abzuschaffen.
- Legacy-Enterprise-Systeme: Banken, Regierungsportale und große E-Commerce-Plattformen haben oft jQuery in Codebasen eingebettet, die aus den Jahren 2010-2015 stammen. Migration ist teuer und hat niedrige Priorität.
- Neue Projekte: Fast keine. React, Vue, Svelte und Vanilla JS dominieren die Neuentwicklung. Kein modernes Framework oder Starter-Template enthält jQuery.
Wenn du 2026 ein neues WordPress-Theme oder -Plugin beginnst, gibt es keinen Grund, jQuery als Abhängigkeit hinzuzufügen. Die Browser-APIs reichen für jedes gängige Muster aus. Mehr zum richtigen Erstellen von Plugins findest du im Abschnitt WordPress-Plugin-Best-Practices in unserem Plugin-Stack-Leitfaden.
Fazit: die Migrations-Checkliste
- Prüfe die gesamte jQuery-Nutzung in deinem Theme und eigenen Plugins
- Miss die aktuellen Core Web Vitals als Referenzwert
- Ersetze den Frontend-Theme-Code zuerst (grösster Besuchereinfluss)
- Verwende
querySelector,addEventListener,fetch,classListund Web Animations API - Ziehe Web Components für wiederverwendbare UI-Elemente in Betracht
- Verwende
wp_enqueue_script_module()für ES-Modul-Unterstützung - Teste in allen großen Browsern nach jeder Dateimigration
- Miss die Core Web Vitals erneut und dokumentiere die Verbesserung
- Behalte jQuery nur für Admin-Scripts und Drittanbieter-Plugin-Abhängigkeiten
- Schule dein Team in modernen JavaScript-Mustern
Die Web-Plattform 2026 bietet alles, was jQuery bot, und mehr. Jedes Kilobyte unnötiges JavaScript, das du entfernst, macht deine WordPress-Website schneller, barrierefreier und einfacher zu warten.

