Web Performance Optimization 2025
Web sitesi hızı artık bir lüks değil, zorunluluk! Google'ın ranking faktörü, kullanıcı deneyiminin temelive dönüşüm oranlarının belirleyicisi. Bu rehberde, 2025'te web performansını maksimuma çıkarmanın tüm yollarını öğreneceksiniz.
Neden Performans Kritik?
📊 İstatistikler:
- 1 saniye gecikme = %7 dönüşüm kaybı
- Sayfa yükleme 3+ saniye = %53 kullanıcı terk ediyor
- %100 hız artışı = %8 dönüşüm artışı
- Google arama sıralamasında direkt faktör
- Mobile kullanıcılar %73 daha sabırsız
Core Web Vitals 2025
Google'ın resmi performans metrikleri:
1. LCP (Largest Contentful Paint)
Hedef: < 2.5 saniye
En büyük içeriğin yüklenme süresi.
// LCP tracking
new PerformanceObserver((list) => {
const entries = list.getEntries();
const lastEntry = entries[entries.length - 1];
console.log('LCP:', lastEntry.renderTime || lastEntry.loadTime);
}).observe({ entryTypes: ['largest-contentful-paint'] });
Optimizasyon:
<!-- Priority hint -->
<img src="hero.jpg" fetchpriority="high" loading="eager">
<!-- Preload critical images -->
<link rel="preload" as="image" href="hero.jpg">
<!-- WebP format -->
<picture>
<source srcset="hero.webp" type="image/webp">
<img src="hero.jpg" alt="Hero">
</picture>
2. FID (First Input Delay) → INP (Interaction to Next Paint)
Hedef: < 100ms (FID) / < 200ms (INP)
İlk etkileşime yanıt süresi.
// INP measurement
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
const delay = entry.processingStart - entry.startTime;
console.log('Input delay:', delay);
}
});
observer.observe({ type: 'first-input', buffered: true });
Optimizasyon:
// Code splitting
const HeavyComponent = lazy(() => import('./HeavyComponent'));
// Debounce expensive operations
const debouncedSearch = debounce((query) => {
// Expensive search operation
}, 300);
// Use Web Workers for heavy computations
const worker = new Worker('heavy-calc.js');
worker.postMessage(data);
3. CLS (Cumulative Layout Shift)
Hedef: < 0.1
Görsel kararlılık - beklenmeyen kaymalara karşı.
/* Reserve space for images */
img {
aspect-ratio: 16 / 9;
width: 100%;
height: auto;
}
/* Font loading optimization */
@font-face {
font-family: 'MyFont';
src: url('font.woff2') format('woff2');
font-display: swap; /* Prevent layout shift */
}
/* Ad placeholder */
.ad-container {
min-height: 250px; /* Reserve space */
}
Resource Optimization
1. Image Optimization
Modern Formats:
<picture>
<!-- AVIF (best compression, 2025 standard) -->
<source srcset="image.avif" type="image/avif">
<!-- WebP (good fallback) -->
<source srcset="image.webp" type="image/webp">
<!-- JPEG (universal fallback) -->
<img src="image.jpg" alt="Description">
</picture>
Responsive Images:
<img
srcset="
small.jpg 400w,
medium.jpg 800w,
large.jpg 1200w
"
sizes="
(max-width: 600px) 400px,
(max-width: 900px) 800px,
1200px
"
src="large.jpg"
alt="Responsive image"
loading="lazy"
decoding="async"
>
Image CDN:
// Cloudinary example
const imageUrl = `https://res.cloudinary.com/demo/image/upload/
w_800, // Width
f_auto, // Format auto (AVIF/WebP/JPEG)
q_auto, // Quality auto
c_fill, // Crop mode
g_auto // Gravity auto (smart crop)
/sample.jpg`;
2. Font Optimization
/* Font loading strategy */
@font-face {
font-family: 'Inter';
src: url('/fonts/inter.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
/* Optional: unicode-range for subsetting */
unicode-range: U+0020-007F;
}
/* Preload critical fonts */
<link
rel="preload"
href="/fonts/inter.woff2"
as="font"
type="font/woff2"
crossorigin
>
Variable Fonts (2025 Best Practice):
@font-face {
font-family: 'Inter Variable';
src: url('inter-variable.woff2') format('woff2');
font-weight: 100 900; /* All weights in one file! */
font-display: swap;
}
3. CSS Optimization
Critical CSS:
<style>
/* Inline critical above-the-fold CSS */
body { margin: 0; font-family: sans-serif; }
.header { background: #000; color: #fff; }
.hero { height: 100vh; }
</style>
<!-- Async load rest -->
<link rel="preload" href="styles.css" as="style" onload="this.rel='stylesheet'">
CSS Minification & Purging:
// PostCSS config
module.exports = {
plugins: [
require('tailwindcss'),
require('autoprefixer'),
require('cssnano')({
preset: ['advanced', {
discardComments: { removeAll: true },
reduceIdents: true,
zindex: false
}]
}),
require('@fullhuman/postcss-purgecss')({
content: ['./src/**/*.html', './src/**/*.js'],
safelist: ['active', 'hover']
})
]
};
4. JavaScript Optimization
Code Splitting:
// Route-based code splitting
const routes = [
{
path: '/',
component: () => import('./pages/Home.js')
},
{
path: '/about',
component: () => import('./pages/About.js')
}
];
// Dynamic import
button.addEventListener('click', async () => {
const module = await import('./heavy-module.js');
module.init();
});
Tree Shaking:
// ❌ Import all
import _ from 'lodash';
// ✅ Import only what you need
import { debounce } from 'lodash-es';
// ✅ Even better: individual package
import debounce from 'lodash.debounce';
Minification & Compression:
// Webpack config
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
compress: {
drop_console: true, // Remove console.logs
pure_funcs: ['console.info', 'console.debug']
}
}
})
],
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
priority: 10
}
}
}
}
};
Caching Strategies
1. Browser Caching
# Nginx configuration
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
location ~* \.(html)$ {
expires 1h;
add_header Cache-Control "public, must-revalidate";
}
2. Service Worker Caching
// service-worker.js
const CACHE_NAME = 'v1';
const urlsToCache = [
'/',
'/styles.css',
'/script.js',
'/logo.png'
];
// Install
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME)
.then((cache) => cache.addAll(urlsToCache))
);
});
// Fetch with cache-first strategy
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request)
.then((response) => response || fetch(event.request))
);
});
3. CDN Usage
<!-- Static assets via CDN -->
<script src="https://cdn.example.com/js/app.min.js"></script>
<link rel="stylesheet" href="https://cdn.example.com/css/style.min.css">
<!-- DNS prefetch for external domains -->
<link rel="dns-prefetch" href="https://cdn.example.com">
<link rel="preconnect" href="https://cdn.example.com" crossorigin>
Server-Side Optimization
1. Compression
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types
text/plain
text/css
text/javascript
application/javascript
application/json
image/svg+xml;
# Brotli compression (better than gzip)
brotli on;
brotli_comp_level 6;
brotli_types
text/plain
text/css
application/javascript
application/json;
2. HTTP/2 & HTTP/3
# Enable HTTP/2
listen 443 ssl http2;
# Enable HTTP/3 (QUIC)
listen 443 quic reuseport;
add_header Alt-Svc 'h3=":443"; ma=86400';
3. Server-Side Rendering (SSR)
// Next.js example
export async function getServerSideProps() {
const data = await fetchData();
return {
props: { data }
};
}
// Static Generation (even better!)
export async function getStaticProps() {
const data = await fetchData();
return {
props: { data },
revalidate: 60 // ISR: Revalidate every 60 seconds
};
}
Database Optimization
1. Query Optimization
-- ❌ BAD: N+1 query problem
SELECT * FROM users;
-- Then for each user:
SELECT * FROM posts WHERE user_id = ?;
-- ✅ GOOD: Join query
SELECT users.*, posts.*
FROM users
LEFT JOIN posts ON users.id = posts.user_id;
-- Add indexes
CREATE INDEX idx_posts_user_id ON posts(user_id);
CREATE INDEX idx_posts_created_at ON posts(created_at DESC);
2. Caching Layer
// Redis caching example
const redis = require('redis');
const client = redis.createClient();
async function getUser(id) {
// Check cache first
const cached = await client.get(`user:${id}`);
if (cached) return JSON.parse(cached);
// If not in cache, query database
const user = await db.query('SELECT * FROM users WHERE id = ?', [id]);
// Store in cache
await client.setex(`user:${id}`, 3600, JSON.stringify(user));
return user;
}
Monitoring & Analytics
1. Real User Monitoring (RUM)
// Web Vitals tracking
import { getCLS, getFID, getFCP, getLCP, getTTFB } from 'web-vitals';
function sendToAnalytics(metric) {
// Send to Google Analytics
gtag('event', metric.name, {
value: Math.round(metric.value),
metric_id: metric.id,
metric_value: metric.value,
metric_delta: metric.delta
});
}
getCLS(sendToAnalytics);
getFID(sendToAnalytics);
getFCP(sendToAnalytics);
getLCP(sendToAnalytics);
getTTFB(sendToAnalytics);
2. Performance Budget
// Webpack performance budget
module.exports = {
performance: {
maxAssetSize: 244000, // 244 KB
maxEntrypointSize: 244000,
hints: 'error' // Fail build if exceeded
}
};
Progressive Web App (PWA)
// manifest.json
{
"name": "My App",
"short_name": "App",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#000000",
"icons": [
{
"src": "/icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/icon-512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
Performance Checklist
✅ Images
- [ ] Modern formats (AVIF/WebP)
- [ ] Responsive images (srcset)
- [ ] Lazy loading
- [ ] CDN usage
- [ ] Compression (80-85% quality)
✅ CSS
- [ ] Critical CSS inline
- [ ] Minification
- [ ] Purge unused CSS
- [ ] Async loading
✅ JavaScript
- [ ] Code splitting
- [ ] Tree shaking
- [ ] Minification
- [ ] Defer/async loading
- [ ] Remove unused code
✅ Fonts
- [ ] WOFF2 format
- [ ] font-display: swap
- [ ] Preload critical fonts
- [ ] Variable fonts
- [ ] Subset fonts
✅ Server
- [ ] Gzip/Brotli compression
- [ ] HTTP/2 enabled
- [ ] CDN configured
- [ ] Caching headers
- [ ] Database optimization
✅ Monitoring
- [ ] Core Web Vitals tracking
- [ ] Performance budget
- [ ] Regular audits
- [ ] A/B testing
Tools & Resources
Testing Tools:
- Google PageSpeed Insights
- WebPageTest
- Lighthouse
- GTmetrix
- Chrome DevTools
Optimization Tools:
- ImageOptim / Squoosh
- TinyPNG / Compressor.io
- PurgeCSS
- Webpack Bundle Analyzer
Monitoring:
- Google Analytics 4
- New Relic
- Datadog
- Sentry Performance
Sonuç
Web performans optimizasyonu sürekli bir süreç:
- Ölç - Mevcut durumu analiz et
- Optimize Et - İyileştirmeler yap
- Test Et - Sonuçları kontrol et
- Tekrarla - Sürekli iyileştir
Hedef Skorlar:
- PageSpeed: 90+
- LCP: < 2.5s
- FID/INP: < 100ms
- CLS: < 0.1
Web sitenizin performansını birlikte optimize edelim! 🚀
📧 iletisim@cesayazilim.com
📞 +90 850 225 53 34