Optymalizacja JavaScript
Code splitting, minifikacja, tree shaking i eliminacja nieużywanego kodu
Dlaczego optymalizować JavaScript?
JavaScript może znacząco wpływać na wydajność strony, szczególnie na FID/INP i LCP. Nieoptymalizowany JavaScript może blokować renderowanie, spowalniać interakcje i zwiększać rozmiar strony.
Główne problemy: zbyt duże pliki, render-blocking skrypty, nieużywany kod, brak code splitting, brak minifikacji.
Techniki optymalizacji
1. Code Splitting
Dziel kod na mniejsze fragmenty ładowane na żądanie. Zmniejsza to początkowy rozmiar bundle'a.
// Dynamic import
const module = await import('./heavy-module.js');
// React lazy loading
const HeavyComponent = React.lazy(() => import('./HeavyComponent'));
<Suspense fallback={<Loading />}>
<HeavyComponent />
</Suspense>Korzyści: Mniejszy początkowy bundle, szybsze First Contentful Paint, ładowanie kodu tylko gdy jest potrzebny.
2. Tree Shaking
Usuwa nieużywany kod podczas bundlowania. Wymaga ES6 modules (import/export).
// ❌ Źle - importuje całą bibliotekę
import _ from 'lodash';
// ✅ Dobrze - importuje tylko potrzebną funkcję
import debounce from 'lodash/debounce';
// ✅ Lepsze - użyj ESM build
import { debounce } from 'lodash-es';Narzędzia: Webpack, Rollup, Vite automatycznie wykonują tree shaking.
3. Minifikacja
Zmniejsza rozmiar pliku poprzez usunięcie białych znaków, komentarzy i skrócenie nazw zmiennych.
❌ Przed minifikacją:
function calculateTotalPrice(items) {
let total = 0;
for (let i = 0; i < items.length; i++) {
total += items[i].price;
}
return total;
}✅ Po minifikacji:
function calculateTotalPrice(a){let b=0;for(let c=0;c<a.length;c++)b+=a[c].price;return b}Narzędzia: Terser, UglifyJS, esbuild
4. Defer i Async
Kontroluj kiedy JavaScript jest ładowany i wykonywany:
<!-- Defer - wykonuje się po załadowaniu HTML, zachowuje kolejność --> <script defer src="app.js"></script> <!-- Async - wykonuje się natychmiast po pobraniu, bez kolejności --> <script async src="analytics.js"></script> <!-- Brak defer/async - blokuje renderowanie --> <script src="blocking.js"></script>
- defer: Dla skryptów, które muszą wykonać się w kolejności
- async: Dla niezależnych skryptów (analytics, reklamy)
- Brak: Unikaj - blokuje renderowanie
5. Eliminacja nieużywanego kodu
- Usuń nieużywane funkcje i klasy
- Unikaj importowania całych bibliotek
- Usuń dead code i zakomentowany kod
- Użyj narzędzi do analizy bundle'a (webpack-bundle-analyzer)
6. Web Workers dla ciężkich operacji
Przenieś ciężkie obliczenia do Web Worker, aby nie blokować głównego wątku:
// main.js
const worker = new Worker('worker.js');
worker.postMessage({ data: largeArray });
worker.onmessage = (e) => {
console.log('Result:', e.data);
};
// worker.js
self.onmessage = (e) => {
const result = heavyComputation(e.data.data);
self.postMessage(result);
};Checklista optymalizacji JavaScript
Budowanie i bundle
- Włącz code splitting
- Minifikuj kod produkcyjny
- Włącz tree shaking
- Kompresuj JavaScript (Gzip/Brotli)
Ładowanie
- Użyj defer dla krytycznych skryptów
- Użyj async dla niezależnych skryptów
- Lazy load niekrytycznych modułów