jQuery rozwiązywał realne problemy kompatybilności między przeglądarkami przez ponad dekadę. W 2008 roku, gdy ten artykuł został po raz pierwszy opublikowany, pisanie JavaScript działającego w różnych przeglądarkach bez jQuery było naprawdę bolesne. Internet Explorer 6 obsługiwał zdarzenia inaczej, selektory CSS były niespójne, a AJAX wymagał specyficznych dla przeglądarki implementacji XMLHttpRequest.
Dowiedz się więcej o optymalizacji szybkości WordPress na WPPoland.
W 2026 roku każdy problem, który jQuery rozwiązywał, jest teraz obsługiwany natywnie przez przeglądarki. Pytanie nie brzmi już czy migrować, ale jak zrobić to bezpiecznie bez psowania istniejącej funkcjonalności.
Dlaczego jQuery jest długiem technicznym w 2026
jQuery 3.7 waży 87KB nieskompresowanego (30KB gzipped). To może brzmieć niewiele, ale rozważ, co to kosztuje:
- Total Blocking Time (TBT): jQuery musi zostać sparsowane i wykonane zanim jakikolwiek zależny kod się uruchomi. Na średniej klasy urządzeniach mobilnych dodaje to 150-300ms do TBT.
- Interaction to Next Paint (INP): System delegacji zdarzeń jQuery dodaje narzut do każdej interakcji użytkownika, mierzalnie pogarszając wyniki INP.
- Łańcuch zależności: Załadowanie jQuery oznacza, że każdy skrypt od niego zależny musi czekać, tworząc kaskadę blokujących zasobów.
- Redundantny kod: Każda metoda jQuery, którą wywołujesz, ma natywny odpowiednik, który przeglądarka już dostarcza. Płacisz podwójnie za tę samą funkcjonalność.
Benchmarki wydajności: jQuery vs czysty JS
Pomiary z rzeczywistego świata na motywie WordPress z typowymi interakcjami (toggle menu, przełączanie zakładek, walidacja formularza, ładowanie AJAX):
| Metryka | Z jQuery | Bez jQuery | Poprawa |
|---|---|---|---|
| Całkowity rozmiar JS | 142KB | 55KB | -61% |
| TBT (mobilny) | 480ms | 180ms | -62% |
| INP (p75) | 220ms | 95ms | -57% |
| LCP | 2.1s | 1.7s | -19% |
| Wydajność Lighthouse | 72 | 94 | +22 punkty |
Te liczby pochodzą z produkcyjnej strony WordPress działającej na GeneratePress z WooCommerce, testowanej na Moto G Power (reprezentatywnym urządzeniu średniej klasy).
Nowoczesny JavaScript (ES2024+) zastępuje każdy wzorzec jQuery
Specyfikacja ES2024, w pełni obsługiwana w Chrome 124+, Firefox 126+, Safari 17.4+ i Edge 124+, zapewnia natywne alternatywy dla każdego popularnego wzorca jQuery.
Selekcja DOM
// 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');
// Selekcja z zakresem (jak jQuery .find())
const navLinks = container.querySelectorAll('a.nav-link');
Kluczowa różnica: querySelectorAll zwraca statyczny NodeList, nie żywą kolekcję. Jest to bezpieczniejsze, ponieważ lista nie zmienia się nieoczekiwanie, gdy DOM mutuje.
Obsługa zdarzeń
// jQuery
$('.btn').click(function () {
$(this).toggleClass('active');
});
$('.menu').on('click', '.menu-item', function () {
// zdarzenie delegowane
});
// Vanilla JS
document.querySelectorAll('.btn').forEach(btn => {
btn.addEventListener('click', () => {
btn.classList.toggle('active');
});
});
// Delegacja zdarzeń (zastępuje .on() z selektorem)
document.querySelector('.menu').addEventListener('click', (e) => {
const item = e.target.closest('.menu-item');
if (item) {
// obsłuż kliknięcie elementu menu
}
});
Metoda closest() jest nowoczesnym odpowiednikiem dopasowywania zdarzeń delegowanych jQuery. Przechodzi w górę drzewa DOM, aby znaleźć najbliższego przodka pasującego do selektora.
Manipulacja klasami
// 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');
// Wiele klas naraz
el.classList.add('active', 'highlighted', 'animate-in');
el.classList.remove('hidden', 'collapsed');
AJAX z fetch API i 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 (nowoczesne 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('Nie udało się załadować postów:', error);
}
}
// POST z nonce (wzorzec WordPress)
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();
}
Animacje bez jQuery
jQuery .fadeIn(), .slideDown() i .animate() można zastąpić przejściami CSS, animacjami CSS lub Web Animations API.
// jQuery
$('.panel').slideDown(300);
$('.modal').fadeIn(200);
// Podejście CSS (preferowane dla wydajności)
// W CSS:
// .panel { max-height: 0; overflow: hidden; transition: max-height 0.3s ease; }
// .panel.open { max-height: 500px; }
// W JS:
panel.classList.add('open');
// Web Animations API (dla złożonych, programowych animacji)
modal.animate(
[
{ opacity: 0, transform: 'scale(0.95)' },
{ opacity: 1, transform: 'scale(1)' },
],
{ duration: 200, easing: 'ease-out', fill: 'forwards' }
);
Web Animations API działa na wątku kompozytora, co oznacza, że animacje nie blokują głównego wątku. Animacje jQuery działają na głównym wątku i powodują jank na wolniejszych urządzeniach.
Manipulacja DOM
// jQuery
$('<div class="notice">Witaj</div>').appendTo('#container');
$('.old-element').replaceWith('<span>Nowy</span>');
$('.item').remove();
$('.list').empty();
// Vanilla JS
const notice = document.createElement('div');
notice.className = 'notice';
notice.textContent = 'Witaj';
container.append(notice);
// Lub użyj insertAdjacentHTML dla ciągów HTML
container.insertAdjacentHTML('beforeend', '<div class="notice">Witaj</div>');
// Zamień
oldElement.replaceWith(Object.assign(document.createElement('span'), { textContent: 'Nowy' }));
// Usuń
item.remove();
// Opróżnij
list.replaceChildren();
Document ready
// jQuery
$(document).ready(function () { /* ... */ });
$(function () { /* skrót */ });
// Vanilla JS
document.addEventListener('DOMContentLoaded', () => {
// DOM gotowy
});
// Lub po prostu umieść <script> z type="module" na końcu <body>
// Moduły są odraczane domyślnie, więc DOM jest już gotowy
Web Components: nowoczesny zamiennik wtyczek jQuery
Wtyczki jQuery zapewniały wielokrotnego użytku komponenty UI (slidery, modale, zakładki, akordeony). W 2026 roku Web Components oferują alternatywę opartą na standardach z lepszą enkapsulacją.
Przykład: komponent panelu przełączanego
class TogglePanel extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
const title = this.getAttribute('title') || 'Przełącz';
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);
Użycie w HTML:
<toggle-panel title="Informacje o wysyłce">
<p>Darmowa wysyłka przy zamówieniach powyżej 50 EUR.</p>
</toggle-panel>
Web Components zapewniają enkapsulację Shadow DOM (style nie wyciekają), sloty do projekcji treści i callbacki cyklu życia. Działają w każdej nowoczesnej przeglądarce bez polyfilli.
Kiedy używać Web Components vs framework
| Scenariusz | Rekomendacja |
|---|---|
| Prosty interaktywny widget (akordeon, zakładki, modal) | Web Component |
| Pełna SPA (aplikacja jednostronicowa) | React / Vue / Svelte |
| Blok WordPress (Gutenberg) | React (standard WordPress) |
| Współdzielony komponent między wieloma stronami | Web Component |
| Złożone zarządzanie stanem | Framework z biblioteką stanu |
Strategia migracji dla projektów WordPress
Krok 1: Zbadaj użycie jQuery
Uruchom to polecenie w katalogu motywu, aby znaleźć wszystkie odwołania do jQuery:
grep -rn '\$(\|jQuery\.\|jQuery(' --include='*.js' --include='*.php' .
Skategoryzuj każde użycie:
- Twój kod (motyw/własna wtyczka): migruj to
- Wtyczka zewnętrzna: zostaw, wtyczka zarządza własnymi zależnościami
- Admin WordPress: nie ruszaj, rdzeń WordPress to obsługuje
Krok 2: Stwórz plan migracji
Ustal priorytety według wpływu:
- Kod frontendowy motywu (wpływa na każdego odwiedzającego) - migruj najpierw
- Frontend własnej wtyczki - migruj jako drugi
- Dostosowania panelu admina - migruj na końcu (mniejszy ruch)
Krok 3: Zamieniaj wzorce przyrostowo
Nie przepisuj wszystkiego naraz. Zamieniaj jeden plik na raz:
- Usuń
array('jquery')z tablicy zależnościwp_enqueue_scriptpliku - Zamień wszystkie wzorce jQuery na odpowiedniki czystego JS
- Testuj w Chrome, Firefox, Safari i Edge
- Testuj ze wszystkimi aktywnymi wtyczkami
- Uruchom Lighthouse przed i po, aby zmierzyć poprawę
Krok 4: Obsłuż wzorzec AJAX WordPress
Starszy AJAX WordPress używa admin-ajax.php z jQuery:
// Stary wzorzec (jQuery + admin-ajax)
jQuery.post(ajaxurl, {
action: 'my_custom_action',
nonce: myData.nonce,
post_id: 123,
}, function (response) {
console.log(response);
});
// Nowoczesny wzorzec (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();
}
Podejście REST API jest szybsze (brak narzutu admin-ajax.php), lepiej się cachuje i jest zgodne z nowoczesnymi standardami rozwoju WordPress.
Krok 5: Prawidłowo rejestruj skrypty
// Przed (z zależnością jQuery)
wp_enqueue_script(
'my-theme-scripts',
get_template_directory_uri() . '/js/main.js',
array('jquery'),
'1.0.0',
true
);
// Po (bez jQuery, z obsługą modułów)
wp_enqueue_script_module(
'my-theme-scripts',
get_template_directory_uri() . '/js/main.js',
array(),
'2.0.0'
);
WordPress 6.5+ obsługuje wp_enqueue_script_module(), który ładuje skrypty jako moduły ES z type="module", umożliwiając natywną składnię import/export.
Kiedy zachowanie jQuery nadal ma sens
jQuery może być nadal uzasadnione, jeśli:
- Stara baza kodu z ponad 50 zależnościami wtyczek jQuery: Koszt migracji przekracza korzyść wydajnościową. Zaplanuj stopniowe wycofywanie w ciągu 6-12 miesięcy.
- Dostosowania panelu admina WordPress: Panel administracyjny już ładuje jQuery. Dodanie własnych skryptów admina z zależnością jQuery nic nie kosztuje.
- Wymagania wtyczek zewnętrznych: Niektóre popularne wtyczki (pewne kreatory formularzy, page buildery) wymagają jQuery. Nie walcz z zależnością, jeśli nie możesz jej kontrolować.
- Luka w umiejętnościach zespołu: Jeśli twój zespół programistyczny nie jest biegły w nowoczesnym JS, zainwestuj w szkolenie przed wymuszeniem migracji. Zrozumienie kim jest programista WordPress pomaga ustalić realistyczne oczekiwania co do umiejętności potrzebnych podczas migracji.
Celem jest pragmatyczna poprawa, nie ideologiczna czystość. Usuń jQuery tam, gdzie kosztuje cię wydajność i nie dodaje wartości. Zachowaj go tam, gdzie usunięcie zepsułoby coś lub kosztowałoby więcej, niż oszczędza.
Funkcje ES2024+ zastępujące popularne narzędzia jQuery
Klon strukturalny (głęboka kopia)
// jQuery
const copy = $.extend(true, {}, original);
// ES2024+
const copy = structuredClone(original);
Iteracja po elementach tablicopodobnych
// jQuery
$.each(items, function (index, item) { /* ... */ });
// ES2024+
items.forEach((item, index) => { /* ... */ });
// Lub z Array.from dla NodeList
Array.from(document.querySelectorAll('.item')).map(item => item.textContent);
// Lub operator spread
[...document.querySelectorAll('.item')].filter(item => item.dataset.active);
Wzorce Deferred/Promise
// jQuery
const deferred = $.Deferred();
deferred.resolve('gotowe');
deferred.promise().then(val => console.log(val));
// ES2024+
const promise = new Promise((resolve) => resolve('gotowe'));
promise.then(val => console.log(val));
// Promise.withResolvers() - funkcja ES2024
const { promise, resolve, reject } = Promise.withResolvers();
IntersectionObserver (zastępuje obsługę scrollowania jQuery)
// jQuery (kosztowna obsługa scrollowania)
$(window).scroll(function () {
$('.lazy-image').each(function () {
if ($(this).offset().top < $(window).scrollTop() + $(window).height()) {
$(this).attr('src', $(this).data('src'));
}
});
});
// Vanilla JS (wydajne, poza głównym wątkiem)
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));
Alternatywy w postaci bibliotek narzędziowych (jeśli potrzebujesz helpera)
Jeśli wielokrotnie piszesz te same wzorce czystego JS, rozważ mikro-bibliotekę zamiast jQuery:
| Biblioteka | Rozmiar | Przeznaczenie |
|---|---|---|
| Alpine.js | 15KB | Deklaratywna reaktywność (x-data, x-on) |
| htmx | 14KB | AJAX, WebSocket, SSE przez atrybuty HTML |
| Petite-Vue | 6KB | Składnia szablonów kompatybilna z Vue |
| Brak (vanilla) | 0KB | Najlepsza wydajność, pełna kontrola |
Dla motywów WordPress w 2026, rekomendacją jest czysty JS dla prostych interakcji i Alpine.js lub htmx, jeśli potrzebujesz deklaratywnego zachowania bez pełnego frameworka.
Najlepsze praktyki jQuery w 2026
Jeśli nadal utrzymujesz kod jQuery - czy to z wyboru, czy dlatego, że wymaga tego starsza baza kodu - te praktyki minimalizują szkody:
- Ładuj jQuery z rdzenia WordPress, nigdy z CDN. WordPress zawiera kompatybilną wersję. Ładowanie drugiej kopii z
cdnjslubcode.jquery.comoznacza podwójną wagę i potencjalne konflikty wersji. - Używaj
jQueryzamiast$w WordPress. WordPress uruchamia jQuery w trybie no-conflict. Opakowywanie kodu wjQuery(function($) { ... })zapobiega kolizjom z innymi bibliotekami. - Unikaj zagnieżdżania
.ready(). Wystarczy jedenjQuery(function($) { ... }). Zagnieżdżone wywołania.ready()tworzą piramidy callbacków i mylą kolejność wykonywania. - Cachuj selektory. Każde wywołanie
$('.my-class')przechodzi DOM. Przechowuj wyniki w zmiennej, gdy używasz tego samego selektora więcej niż raz. - Deleguj zdarzenia zamiast wiązać je do pojedynczych elementów. Używaj
$(parent).on('click', '.child', handler)zamiast$('.child').click(handler). To obsługuje dynamicznie dodawane elementy i używa mniej listenerów zdarzeń. - Nie używaj jQuery do animacji CSS. Używaj przejść CSS lub Web Animations API. Metoda
.animate()jQuery działa na głównym wątku i powoduje jank. - Ustaw
jqueryjako zależność tylko gdy jest potrzebne. Jeśli plik skryptu nie używa jQuery, usuń go z tablicy zależnościwp_enqueue_script, aby uniknąć niepotrzebnego ładowania jQuery.
Najnowsza wersja jQuery i co się zmieniło
W 2026 roku jQuery 3.7.1 to najnowsza stabilna wersja (wydana w sierpniu 2023). jQuery 4.0.0-beta.2 jest w fazie beta od lutego 2024, bez ogłoszonej daty stabilnego wydania.
Zmiany w jQuery 4.0 istotne dla WordPress:
| Zmiana | Wpływ |
|---|---|
| Porzuca wsparcie dla IE 11 | Brak wpływu - WordPress 6.6+ już porzucił IE 11 |
Usuwa przestarzałe API (.click(), .bind(), .delegate()) | Wtyczki używające tych metod przestaną działać |
| Mniejszy bundle (~68KB vs 87KB) | Skromna poprawa, nadal cięższy niż brak jQuery |
$.ajax() oparty na FormData do przesyłania plików | Ładniejsze API, ale fetch() robi to natywnie |
Rdzeń WordPress obecnie zawiera jQuery 3.7.1 i nie zobowiązał się do włączenia wersji 4.0. Praktyczny wniosek: nie czekaj na jQuery 4, aby poprawić wydajność. Migruj do czystego JS gdzie to możliwe i stosuj najlepsze praktyki jQuery 3.7.1 tam, gdzie migracja nie jest jeszcze wykonalna.
Kto nadal używa jQuery w 2026
jQuery nadal ładuje się na szacunkowo 77% wszystkich stron internetowych (według W3Techs), głównie dlatego, że WordPress, Shopify i starsze systemy korporacyjne dołączają go domyślnie. Ale “załadowany” nie oznacza “potrzebny”.
Rozbicie:
- Strony WordPress: jQuery ładuje się na praktycznie każdej stronie WordPress, ponieważ pasek admina i wiele popularnych wtyczek od niego zależy. Na frontendzie faktyczna zależność to często tylko jeden lub dwa skrypty.
- Motywy Shopify: Większość motywów Shopify dołącza jQuery do interakcji koszyka. Shopify nie planuje go wycofywać.
- Starsze systemy korporacyjne: Banki, portale rządowe i duże platformy e-commerce często mają jQuery osadzony w bazach kodu sięgających lat 2010-2015. Migracja jest kosztowna i niskopriorytetowa.
- Nowe projekty: Prawie żadne. React, Vue, Svelte i czysty JS dominują w nowych projektach. Żaden nowoczesny framework ani szablon startowy nie dołącza jQuery.
Jeśli zaczynasz nowy motyw lub wtyczkę WordPress w 2026 roku, nie ma powodu, aby dodawać jQuery jako zależność. API przeglądarek wystarczają dla każdego popularnego wzorca. Więcej o tworzeniu wtyczek we właściwy sposób znajdziesz w sekcji najlepszych praktyk dla wtyczek WordPress w naszym przewodniku po stosie wtyczek.
Podsumowanie: lista kontrolna migracji
- Zbadaj całe użycie jQuery w swoim motywie i własnych wtyczkach
- Zmierz aktualne Core Web Vitals jako punkt odniesienia
- Zamień kod frontendowy motywu jako pierwszy (największy wpływ na odwiedzających)
- Używaj
querySelector,addEventListener,fetch,classListi Web Animations API - Rozważ Web Components dla wielokrotnego użytku elementów UI
- Używaj
wp_enqueue_script_module()do obsługi modułów ES - Testuj we wszystkich głównych przeglądarkach po migracji każdego pliku
- Zmierz Core Web Vitals ponownie i udokumentuj poprawę
- Zachowaj jQuery tylko dla skryptów admina i zależności wtyczek zewnętrznych
- Przeszkol swój zespół w nowoczesnych wzorcach JavaScript
Platforma webowa w 2026 roku zapewnia wszystko, co oferował jQuery, i więcej. Każdy kilobajt zbędnego JavaScript, który usuniesz, sprawia, że twoja strona WordPress jest szybsza, bardziej dostępna i łatwiejsza w utrzymaniu.


