1. Pengenalan Web Performance
Web Performance Optimization adalah serangkaian teknik dan strategi untuk membuat website memuat lebih cepat, merespons lebih responsif, dan memberikan pengalaman pengguna yang lebih baik. Performa website bukan sekadar soal kecepatan β ini langsung memengaruhi SEO ranking, conversion rate, dan user retention.
Menurut riset Google, 53% pengguna mobile meninggalkan halaman yang memuat lebih dari 3 detik. Setiap peningkatan 0.1 detik pada waktu muat dapat meningkatkan conversion rate hingga 8%. Ini menjadikan performa web sebagai faktor kritis dalam kesuksesan bisnis online.
Mengapa Performa Penting?
| Faktor | Dampak | Data |
|---|---|---|
| SEO Ranking | Google menggunakan Core Web Vitals sebagai ranking signal | Halaman lambat turun peringkat |
| User Experience | Pengguna mengharapkan halaman dimuat dalam < 3 detik | 53% bounce jika > 3s |
| Conversion Rate | Setiap 100ms penundaan menurunkan penjualan 1% | Amazon kehilangan $1.6B per detik |
| Bandwidth Cost | Optimasi mengurangi penggunaan data dan biaya server | Hingga 60% penghematan |
| Accessibility | Website cepat lebih mudah diakses di jaringan lambat | Pengguna 3G/4G terbantu |
Faktor yang Mempengaruhi Performa
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β LIFECYCLE PEMUATAN HALAMAN β β β β Browser Network Server Rendering β β Request Transfer Process Display β β β β βββββββ βββββββββββ βββββββββββ ββββββββββββ β β β DNS β ββββΊ β TCP + β βββΊ β Server ββββΊβ Parse β β β βLookupβ β TLS β β Responseβ β HTML β β β βββββββ βββββββββββ βββββββββββ ββββββ¬ββββββ β β β β β βββββββΌββββββ β β β Build β β β β DOM β β β βββββββ¬ββββββ β β β β β βββββββββββββββββββββββββββββββββββββββββββββββββββ β β β β β βΌ β β βββββββββββ βββββββββββ βββββββββββ ββββββββββββ β β β Fetch ββββΊβ CSSOM ββββΊβ Render ββββΊβ Paint β β β β CSS β β Build β β Tree β β & Compositeβ β βββββββββββ βββββββββββ βββββββββββ ββββββββββββ β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Performa web adalah proses berkelanjutan. Mulailah dengan mengukur performa saat ini menggunakan tools seperti Lighthouse, PageSpeed Insights, atau WebPageTest, lalu perbaiki secara bertahap berdasarkan metrik yang paling bermasalah.
2. Core Web Vitals
Core Web Vitals adalah tiga metrik inti yang diukur Google untuk menilai pengalaman pengguna pada halaman web. Metrik-metrik ini menjadi faktor ranking resmi sejak tahun 2021 dan terus diperbarui.
Tiga Metrik Utama
| Metrik | Kepanjangan | Yang Diukur | Target |
|---|---|---|---|
| LCP | Largest Contentful Paint | Waktu render elemen terbesar | β€ 2.5 detik |
| INP | Interaction to Next Paint | Responsivitas interaksi pengguna | β€ 200 ms |
| CLS | Cumulative Layout Shift | Perpindahan layout visual | β€ 0.1 |
LCP (Largest Contentful Paint)
LCP mengukur waktu yang dibutuhkan untuk merender elemen konten terbesar yang terlihat di viewport. Elemen yang biasanya menjadi LCP meliputi gambar hero, video, atau blok teks besar.
// Mengukur LCP menggunakan PerformanceObserver
const lcpObserver = new PerformanceObserver((entryList) => {
const entries = entryList.getEntries();
const lastEntry = entries[entries.length - 1];
console.log('LCP:', lastEntry.startTime.toFixed(2), 'ms');
console.log('Element:', lastEntry.element);
// Kategorikan skor
if (lastEntry.startTime <= 2500) {
console.log('β
LCP Good');
} else if (lastEntry.startTime <= 4000) {
console.log('β οΈ LCP Needs Improvement');
} else {
console.log('β LCP Poor');
}
});
lcpObserver.observe({ type: 'largest-contentful-paint', buffered: true });
Teknik Optimasi LCP
<!-- Preload font yang digunakan di hero section -->
<link rel="preload" href="/fonts/inter-bold.woff2"
as="font" type="font/woff2" crossorigin>
<!-- Preload gambar hero (LCP element) -->
<link rel="preload" href="/images/hero.webp"
as="image" type="image/webp">
<!-- Preconnect ke domain CDN -->
<link rel="preconnect" href="https://cdn.example.com" crossorigin>
<!-- DNS Prefetch untuk domain pihak ketiga -->
<link rel="dns-prefetch" href="https://analytics.google.com">
<!-- Render-blocking CSS β inline critical CSS -->
<style>
/* Critical CSS di-inline langsung di HTML */
.hero { display: flex; align-items: center; min-height: 100vh; }
.hero h1 { font-size: 3rem; font-weight: 700; color: #fff; }
</style>
<!-- Non-critical CSS dimuat secara async -->
<link rel="preload" href="/css/full.css" as="style"
onload="this.onload=null;this.rel='stylesheet'">
INP (Interaction to Next Paint)
INP mengukur responsivitas halaman terhadap interaksi pengguna β klik, ketuk, dan penekanan tombol. INP menggantikan FID (First Input Delay) sebagai metrik responsivitas utama.
// β Buruk: Blocking main thread dengan operasi berat
button.addEventListener('click', () => {
// Operasi sinkron yang berat β memblokir respons
for (let i = 0; i < 1000000; i++) {
heavyCalculation(i);
}
updateUI();
});
// β
Baik: Gunakan requestIdleCallback atau setTimeout
button.addEventListener('click', () => {
// Bagi pekerjaan berat menjadi chunk kecil
const items = Array.from({ length: 1000000 });
function processChunk(startIndex) {
const chunk = items.slice(startIndex, startIndex + 1000);
chunk.forEach(item => heavyCalculation(item));
if (startIndex + 1000 < items.length) {
// Yield kembali ke main thread
requestIdleCallback(() => processChunk(startIndex + 1000));
} else {
updateUI();
}
}
requestIdleCallback(() => processChunk(0));
});
// β
Baik: Gunakan Web Workers untuk komputasi berat
const worker = new Worker('heavy-task.js');
worker.postMessage({ data: largeDataset });
worker.onmessage = (e) => {
updateUI(e.data.result);
};
CLS (Cumulative Layout Shift)
CLS mengukur perpindahan elemen visual yang tidak terduga selama pemuatan halaman. Layout shift terjadi ketika elemen berubah posisi setelah render awal.
/* Selalu tentukan dimensi gambar */
img, video {
max-width: 100%;
height: auto;
aspect-ratio: attr(width) / attr(height);
}
/* Atau gunakan aspect-ratio property */
.hero-image {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
}
/* Placeholder untuk iklan / konten dinamis */
.ad-container {
min-height: 250px; /* Reserve space */
background: #1a1a1a;
}
/* Font loading β hindari FOIT */
@font-face {
font-family: 'CustomFont';
src: url('/fonts/custom.woff2') format('woff2');
font-display: swap; /* Tampilkan fallback font dulu */
}
/* Hindari inject konten di atas konten existing */
.notification-banner {
/* Gunakan position: sticky bukan absolute */
position: sticky;
top: 0;
z-index: 1000;
}
Jangan sembunyikan layout shift dengan trik visual. Google tetap mendeteksi pergeseran elemen meskipun tidak terlihat oleh mata. Pastikan setiap elemen yang dimuat secara dinamis memiliki ruang yang dialokasikan sebelum konten muncul.
3. Lazy Loading
Lazy loading adalah teknik menunda pemuatan resource yang tidak langsung dibutuhkan hingga pengguna membutuhkannya. Ini sangat efektif untuk gambar, video, dan komponen JavaScript yang berada di bawah fold (tidak terlihat di viewport awal).
Native Lazy Loading (HTML)
<!-- Gambar di bawah fold: gunakan loading="lazy" -->
<img src="/images/product-1.webp"
alt="Produk 1"
width="400" height="300"
loading="lazy"
decoding="async">
<!-- Gambar di atas fold: JANGAN lazy load -->
<img src="/images/hero.webp"
alt="Hero Banner"
width="1200" height="600"
loading="eager"
fetchpriority="high">
<!-- Lazy load iframe (video YouTube, Google Maps) -->
<iframe src="https://www.youtube.com/embed/VIDEO_ID"
loading="lazy"
width="560" height="315"
title="Video Tutorial"
allowfullscreen></iframe>
Intersection Observer API
Untuk kontrol lebih lanjut, gunakan Intersection Observer untuk lazy load elemen kapan pun sesuai kebutuhan:
// Lazy load gambar dengan Intersection Observer
function setupLazyImages() {
const images = document.querySelectorAll('img[data-src]');
const imageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
// Ganti data-src dengan src
img.src = img.dataset.src;
// Jika ada srcset
if (img.dataset.srcset) {
img.srcset = img.dataset.srcset;
}
img.classList.add('loaded');
observer.unobserve(img);
}
});
}, {
rootMargin: '200px 0px', // Mulai load 200px sebelum terlihat
threshold: 0.01
});
images.forEach(img => imageObserver.observe(img));
}
// Jalankan saat DOM siap
document.addEventListener('DOMContentLoaded', setupLazyImages);
// Contoh HTML:
// <img data-src="/images/foto.webp"
// src="/images/placeholder.svg"
// alt="Foto" width="400" height="300">
Lazy Load Komponen JavaScript
import { lazy, Suspense } from 'react';
// Lazy load komponen berat
const ChartDashboard = lazy(() => import('./ChartDashboard'));
const VideoPlayer = lazy(() => import('./VideoPlayer'));
const MapComponent = lazy(() => import('./MapComponent'));
function Dashboard() {
return (
<div className="dashboard">
<h1>Dashboard</h1>
{/* Komponen dimuat hanya saat dibutuhkan */}
<Suspense fallback={<div className="skeleton">Memuat chart...</div>}>
<ChartDashboard />
</Suspense>
<Suspense fallback={<div className="skeleton">Memuat video...</div>}>
<VideoPlayer src="/videos/tutorial.mp4" />
</Suspense>
<Suspense fallback={<div className="skeleton">Memuat peta...</div>}>
<MapComponent lat={-6.2} lng={106.8} />
</Suspense>
</div>
);
}
4. Code Splitting
Code splitting adalah teknik memecah bundle JavaScript besar menjadi beberapa chunk yang lebih kecil. Alih-alih memuat seluruh aplikasi sekaligus, pengguna hanya memuat kode yang dibutuhkan untuk halaman saat ini.
Mengapa Code Splitting Penting?
| Tanpa Code Splitting | Dengan Code Splitting |
|---|---|
| Satu bundle.js berukuran 2 MB | Multiple chunks 50-200 KB each |
| Memuat semua kode sekaligus | Hanya memuat kode halaman aktif |
| TTI lambat (5-10 detik) | TTI cepat (1-3 detik) |
| Cache tidak efisien | Perubahan kecil = re-download kecil |
Dynamic Import
// β Static import β semua dimuat sekaligus
import { Chart } from 'chart.js';
import moment from 'moment';
import lodash from 'lodash';
// β
Dynamic import β dimuat saat dibutuhkan
async function renderChart(data) {
// Chart.js dimuat hanya saat fungsi dipanggil
const { Chart } = await import('chart.js/auto');
const chart = new Chart(document.getElementById('chart'), {
type: 'bar',
data: data
});
return chart;
}
// Dynamic import dengan error handling
async function loadAnalytics() {
try {
const module = await import('./analytics.js');
module.trackPageView();
} catch (error) {
console.error('Gagal memuat modul analytics:', error);
// Fallback: kirim data dasar tanpa library
sendBasicAnalytics();
}
}
// Conditional loading β hanya di halaman tertentu
if (window.location.pathname === '/dashboard') {
import('./dashboard-charts.js').then(module => {
module.initCharts();
});
}
Code Splitting dengan Vite / Webpack
// vite.config.js
import { defineConfig } from 'vite';
export default defineConfig({
build: {
rollupOptions: {
output: {
// Pisahkan vendor libraries ke chunk terpisah
manualChunks: {
'vendor-react': ['react', 'react-dom'],
'vendor-utils': ['lodash', 'date-fns'],
'vendor-charts': ['chart.js', 'd3'],
},
},
},
// Batasi ukuran chunk warning
chunkSizeWarningLimit: 500, // 500 KB
},
});
Route-based Code Splitting
import { lazy, Suspense } from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
// Setiap halaman di-split menjadi chunk terpisah
const HomePage = lazy(() => import('./pages/HomePage'));
const ProductPage = lazy(() => import('./pages/ProductPage'));
const CheckoutPage = lazy(() => import('./pages/CheckoutPage'));
const ProfilePage = lazy(() => import('./pages/ProfilePage'));
const AdminPage = lazy(() => import('./pages/AdminPage'));
function App() {
return (
<BrowserRouter>
<Suspense fallback={<div className="page-loader">Loading...</div>}>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/produk/:id" element={<ProductPage />} />
<Route path="/checkout" element={<CheckoutPage />} />
<Route path="/profil" element={<ProfilePage />} />
<Route path="/admin/*" element={<AdminPage />} />
</Routes>
</Suspense>
</BrowserRouter>
);
}
5. Image Optimization
Gambar biasanya menyumbang 50-70% total ukuran halaman web. Mengoptimalkan gambar adalah salah satu cara paling efektif untuk meningkatkan performa.
Format Gambar Modern
| Format | Kompresi | Dukungan Browser | Cocok Untuk |
|---|---|---|---|
| WebP | 25-34% lebih kecil dari JPEG | 97%+ browser | Gambar umum, foto |
| AVIF | 50% lebih kecil dari JPEG | ~90% browser modern | Foto berkualitas tinggi |
| SVG | Vektor, ukuran sangat kecil | Semua browser | Icon, logo, ilustrasi |
| JPEG | Lossy, kompresi baik | Semua browser | Fallback untuk browser lama |
| PNG | Lossless, transparansi | Semua browser | Gambar dengan transparansi |
Responsive Images dengan picture Tag
<!-- Gunakan <picture> untuk format modern dengan fallback -->
<picture>
<!-- AVIF untuk browser yang mendukung (terkecil) -->
<source
srcset="/images/hero-400.avif 400w,
/images/hero-800.avif 800w,
/images/hero-1200.avif 1200w"
sizes="(max-width: 600px) 400px,
(max-width: 1024px) 800px,
1200px"
type="image/avif">
<!-- WebP sebagai opsi kedua -->
<source
srcset="/images/hero-400.webp 400w,
/images/hero-800.webp 800w,
/images/hero-1200.webp 1200w"
sizes="(max-width: 600px) 400px,
(max-width: 1024px) 800px,
1200px"
type="image/webp">
<!-- JPEG sebagai fallback -->
<img
src="/images/hero-800.jpg"
alt="Hero Banner"
width="1200" height="600"
loading="eager"
fetchpriority="high">
</picture>
<!-- Menggunakan srcset untuk resolusi berbeda -->
<img
srcset="/images/foto-small.webp 480w,
/images/foto-medium.webp 768w,
/images/foto-large.webp 1200w"
sizes="(max-width: 600px) 100vw,
(max-width: 1024px) 50vw,
33vw"
src="/images/foto-medium.webp"
alt="Foto produk"
loading="lazy"
decoding="async"
width="800" height="600">
Optimasi Gambar dengan Script
# Instal Sharp β library pemrosesan gambar untuk Node.js
npm install sharp
# Atau gunakan CLI tools
npm install -g @squoosh/cli # Google Squoosh CLI
npm install -g imagemin-cli # Imagemin CLI
# Contoh: Konversi batch ke WebP menggunakan sharp
node -e "
const sharp = require('sharp');
const fs = require('fs');
const path = require('path');
const inputDir = './images/original';
const outputDir = './images/optimized';
fs.readdirSync(inputDir).forEach(file => {
const input = path.join(inputDir, file);
const output = path.join(outputDir,
file.replace(/\.(jpg|png)$/, '.webp'));
sharp(input)
.resize({ width: 1200, withoutEnlargement: true })
.webp({ quality: 80 })
.toFile(output)
.then(info => console.log(file, 'β', info.size / 1024, 'KB'));
});
"
Layanan CDN modern seperti Cloudflare Images, Cloudinary, dan imgix bisa melakukan transformasi gambar secara otomatis β resize, crop, konversi format, dan kompresi β hanya dengan mengubah URL gambar. Ini menghilangkan kebutuhan untuk membuat versi gambar secara manual.
6. Caching Strategies
Caching menyimpan salinan resource di lokasi yang lebih dekat dengan pengguna sehingga halaman dimuat lebih cepat saat dikunjungi kembali. Strategi caching yang tepat dapat mengurangi waktu muat hingga 80%.
Browser Caching (HTTP Headers)
# /etc/nginx/conf.d/cache.conf
# Cache aset statis (CSS, JS, gambar, font) selama 1 tahun
location ~* \.(css|js|jpg|jpeg|png|gif|webp|avif|svg|woff2|woff)$ {
expires 1y;
add_header Cache-Control "public, immutable";
add_header Vary "Accept-Encoding";
}
# Cache HTML selama 5 menit dengan revalidation
location ~* \.html$ {
expires 5m;
add_header Cache-Control "public, must-revalidate";
}
# API response β cache 1 jam
location /api/ {
expires 1h;
add_header Cache-Control "public, stale-while-revalidate=3600";
}
# Tidak cache halaman sensitif
location /admin/ {
add_header Cache-Control "no-store, no-cache, must-revalidate";
add_header Pragma "no-cache";
}
Service Worker Caching
// service-worker.js β Cache-First Strategy untuk aset statis
const CACHE_NAME = 'beebane-v1';
const STATIC_ASSETS = [
'/',
'/index.html',
'/css/style.css',
'/js/app.js',
'/images/logo_beebane.png',
'/offline.html',
];
// Install: cache aset statis
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME).then(cache => {
return cache.addAll(STATIC_ASSETS);
})
);
self.skipWaiting();
});
// Activate: hapus cache lama
self.addEventListener('activate', (event) => {
event.waitUntil(
caches.keys().then(keys => {
return Promise.all(
keys.filter(key => key !== CACHE_NAME)
.map(key => caches.delete(key))
);
})
);
self.clients.claim();
});
// Fetch: strategi cache-first untuk aset, network-first untuk API
self.addEventListener('fetch', (event) => {
const url = new URL(event.request.url);
// Aset statis: cache-first
if (STATIC_ASSETS.includes(url.pathname)) {
event.respondWith(
caches.match(event.request).then(cached => {
return cached || fetch(event.request);
})
);
return;
}
// API: network-first dengan fallback ke cache
if (url.pathname.startsWith('/api/')) {
event.respondWith(
fetch(event.request)
.then(response => {
const clone = response.clone();
caches.open(CACHE_NAME).then(cache => {
cache.put(event.request, clone);
});
return response;
})
.catch(() => caches.match(event.request))
);
return;
}
});
Strategi Caching yang Umum
| Strategi | Cara Kerja | Cocok Untuk |
|---|---|---|
| Cache-First | Ambil dari cache dulu, baru network | Aset statis (CSS, JS, gambar) |
| Network-First | Ambil dari network dulu, cache sebagai fallback | Halaman HTML, data dinamis |
| Stale-While-Revalidate | Tampilkan cache sambil update di background | API yang sering berubah |
| Network-Only | Selalu ambil dari network | Data real-time, login |
7. Content Delivery Network (CDN)
CDN (Content Delivery Network) adalah jaringan server yang tersebar di seluruh dunia yang menyimpan salinan konten statis website Anda. Saat pengguna mengakses situs, konten dikirimkan dari server terdekat secara geografis β mengurangi latency secara signifikan.
Cara Kerja CDN
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β CARA KERJA CDN β β β β Pengguna Jakarta ββββΊ PoP Singapore ββββΊ Origin Server US β β β β β β β β [Cache HIT] β [Cache MISS] β β β β Response: 20ms β Fetch dari originβ β β ββββββββββββββββββββββ Simpan di cache β β β ββββββ β β β β Pengguna Tokyo ββββΊ PoP Tokyo ββββΊ [Cache ada] β β β β β β β Response: 15ms β β β βββββββββββββββββββββ β β β β Server CDN tersebar di 200+ lokasi worldwide β β Latency turun dari 300ms β 20ms = 15x lebih cepat β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Populer CDN Services
| CDN | Free Plan | PoP Locations | Fitur Utama |
|---|---|---|---|
| Cloudflare | β Ya | 300+ kota | DDoS protection, Workers, image optimization |
| Netlify | β Ya | Global edge | Deploy previews, serverless functions |
| Vercel | β Ya | Edge network | Next.js optimization, ISR, Edge Functions |
| AWS CloudFront | Free tier | 400+ PoP | Integrasi AWS, Lambda@Edge |
| Bunny CDN | Pay-as-go | 114 PoP | Harga murah, video streaming |
Konfigurasi CDN Dasar
<!-- Font dari Google Fonts CDN dengan preconnect -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
<!-- Self-host lebih baik daripada CDN pihak ketiga -->
<!-- Download font dan simpan di server/CDN sendiri -->
<style>
@font-face {
font-family: 'Inter';
src: url('/fonts/inter-variable.woff2') format('woff2-variations');
font-weight: 100 900;
font-display: swap;
}
</style>
<!-- Subresource Integrity β keamanan CDN pihak ketiga -->
<script src="https://cdn.jsdelivr.net/npm/react@18/umd/react.production.min.js"
integrity="sha384-xxx..."
crossorigin="anonymous"></script>
Saat menggunakan CDN pihak ketiga, selalu gunakan atribut integrity (SRI β Subresource Integrity) untuk memverifikasi bahwa file yang dikirim tidak dimodifikasi oleh pihak lain. Selain itu, self-hosting library di CDN sendiri lebih aman dan tidak bergantung pada pihak ketiga.
8. Tools Pengukuran Performa
Sebelum mengoptimasi, Anda perlu mengukur terlebih dahulu. Berikut tools yang direkomendasikan untuk mengukur dan menganalisis performa website:
| Tools | Tipe | Yang Diukur |
|---|---|---|
| Google Lighthouse | Lab | Performance score, accessibility, SEO, best practices |
| PageSpeed Insights | Lab + Field | Core Web Vitals, LCP, INP, CLS |
| Chrome DevTools | Lab | Network waterfall, performance profiling, coverage |
| WebPageTest | Lab | Detailed waterfall, filmstrip, multi-location test |
| CrUX Dashboard | Field | Real user metrics dari Chrome users |
| SpeedCurve | Lab + Field | Performance monitoring, visual regression |
Menggunakan Lighthouse dari CLI
# Instal Lighthouse globally npm install -g lighthouse # Jalankan audit pada halaman website lighthouse https://example.com \ --output=html \ --output-path=./report.html \ --chrome-flags="--headless --no-sandbox" \ --only-categories=performance # Jalankan untuk mobile lighthouse https://example.com \ --preset=perf \ --form-factor=mobile \ --throttling-method=simulate # Bandingkan performa sebelum dan sesudah optimasi lighthouse https://example.com --output=json --output-path=before.json # ... lakukan optimasi ... lighthouse https://example.com --output=json --output-path=after.json # Hasil umum yang ingin dicapai: # Performance Score: β₯ 90 # LCP: β€ 2.5s # INP: β€ 200ms # CLS: β€ 0.1
9. Best Practices Ringkas
Berikut checklist cepat untuk optimasi performa web yang harus Anda terapkan:
- Minifikasi CSS, JavaScript, dan HTML untuk mengurangi ukuran file
- Kompresi menggunakan Brotli (lebih baik dari Gzip) untuk transfer data
- Tree shaking untuk menghapus kode yang tidak digunakan dari bundle
- Font optimization β gunakan font-display: swap dan subset karakter
- Critical CSS β inline CSS penting, defer sisanya
- Reduce third-party scripts β audit dan hapus script yang tidak perlu
- HTTP/2 atau HTTP/3 β gunakan multiplexing untuk parallel loading
- Resource hints β preload, prefetch, preconnect untuk resource kritis
- Server-side rendering (SSR) atau Static Site Generation (SSG) untuk FCP cepat
- Monitor terus-menerus β gunakan RUM (Real User Monitoring) untuk data field
# /etc/nginx/conf.d/compression.conf # Brotli compression (lebih efisien dari Gzip) brotli on; brotli_comp_level 6; brotli_types text/plain text/css text/javascript application/javascript application/json application/xml image/svg+xml; # Gzip sebagai fallback gzip on; gzip_comp_level 6; gzip_min_length 256; gzip_vary on; gzip_types text/plain text/css text/javascript application/javascript application/json image/svg+xml;
10. Quiz: Uji Pemahamanmu!
Setelah membaca tutorial di atas, jawablah 5 pertanyaan berikut untuk menguji pemahamanmu tentang Web Performance Optimization: