Core Web Vitals 2025 Rehberi: INP, LCP ve CLS ile SEO Performansını Artırın
2025'te Core Web Vitals Google ranking için kritik faktör. Interaction to Next Paint (INP), Largest Contentful Paint (LCP) ve Cumulative Layout Shift (CLS) metriklerini optimize ederek hem SEO hem kullanıcı deneyimini iyileştirin.
Core Web Vitals 2025 Rehberi: INP, LCP ve CLS ile SEO Performansını Artırın
Google, 2025'te Core Web Vitals'ı ranking algoritmasının merkezine yerleştirdi. Artık ne kadar kaliteli içerik üretirseniz üretin, sitenizin performance metrikleri kötüyse üst sıralarda görünmeniz neredeyse imkansız. Özellikle mobile-first indexing düşünüldüğünde, mobil performans artık opsiyonel değil, zorunlu.
Mart 2024'te yapılan kritik güncellemede, First Input Delay (FID) metriği emekliye ayrıldı ve yerine Interaction to Next Paint (INP) geldi. Bu değişiklik, web vitals'ın daha gerçekçi kullanıcı deneyimini ölçmesini sağladı.
Bu kapsamlı rehberde, Core Web Vitals'ın 2025 standartlarını, her bir metriğin ne anlama geldiğini, nasıl ölçüleceğini ve en önemlisi nasıl optimize edileceğini detaylandıracağız.
İçindekiler
- Core Web Vitals Nedir ve Neden Önemli?
- INP (Interaction to Next Paint) - Yeni Standart
- LCP (Largest Contentful Paint)
- CLS (Cumulative Layout Shift)
- Core Web Vitals Ölçüm Araçları
- Mobile-First Optimization
- Gerçek Dünya Optimization Örnekleri
- Common Issues ve Çözümleri
- Sık Sorulan Sorular
Core Web Vitals Nedir ve Neden Önemli?
Core Web Vitals, Google'ın kullanıcı deneyimini ölçmek için belirlediği üç kritik metriktir:
- INP (Interaction to Next Paint) - Interaktivite hızı
- LCP (Largest Contentful Paint) - Loading hızı
- CLS (Cumulative Layout Shift) - Visual kararlılık
Neden SEO için Kritik?
Direct Ranking Factor: Google 2021'den beri Core Web Vitals'ı ranking signal olarak kullanıyor. 2025'te bu etki daha da arttı.
User Experience = Rankings: İyi vitals = düşük bounce rate, yüksek dwell time, daha fazla conversion. Bunlar indirect ranking signals.
Mobile-First Indexing: Google artık sadece mobile versiyonunuzu index ediyor. Mobile Core Web Vitals skorunuz, ranking'inizin temelidir.
// Örnek: Kötü vitals'ın etkisi
// LCP: 5.2s, INP: 450ms, CLS: 0.35
// Result: Google sıralamasında 3. sayfaya düşüş
// İyileştirme sonrası:
// LCP: 1.8s, INP: 120ms, CLS: 0.05
// Result: İlk sayfaya yükseliş, %40 trafik artışı2025 Hedef Değerleri
Google'ın belirlediği "good" kategorisi eşik değerleri:
| Metrik | İyi | İyileştirme Gerekli | Kötü |
|---|---|---|---|
| INP | ≤ 200ms | 200-500ms | > 500ms |
| LCP | ≤ 2.5s | 2.5-4.0s | > 4.0s |
| CLS | ≤ 0.1 | 0.1-0.25 | > 0.25 |
Sayfanızın %75'i (75th percentile) bu değerleri geçmelidir.
INP (Interaction to Next Paint) - Yeni Standart
Mart 2024'te INP, FID'in yerine geçti ve Core Web Vitals'ın en önemli metriği haline geldi. FID sadece ilk interaksiyonu ölçerken, INP sayfadaki tüm interaksiyonları ölçer.
INP Nedir?
INP, kullanıcının bir interaksiyon yapmasından (tıklama, dokunma, tuş basma) sonraki visual update'in ne kadar sürede geldiğini ölçer.
Kullanıcı tıklama yapar
↓
JavaScript çalışır (Input Delay)
↓
Browser render başlar (Processing Time)
↓
Ekran güncellenir (Presentation Delay)
↓
TOPLAM = INP
INP vs FID
// FID - Sadece ilk interaksiyon
user.firstClick() // Bu ölçülür
user.secondClick() // ❌ Ölçülmez
user.typing() // ❌ Ölçülmez
// INP - Tüm interaksiyonlar
user.firstClick() // ✅ Ölçülür
user.secondClick() // ✅ Ölçülür
user.typing() // ✅ Ölçülür
user.scrolling() // ✅ ÖlçülürGerçek dünyada kullanıcılar sadece bir kez tıklamıyor, INP bu gerçeği yansıtıyor.
INP Nasıl Optimize Edilir?
1. JavaScript Execution Süresini Azaltın
// ❌ Kötü - Long task
function processData(data) {
// 500ms süren blocking code
for (let i = 0; i < 1000000; i++) {
// Heavy computation
}
}
button.addEventListener('click', () => {
processData(hugeDataset) // UI freeze eder
})
// ✅ İyi - Chunked processing
async function processDataChunked(data) {
const chunkSize = 1000
for (let i = 0; i < data.length; i += chunkSize) {
const chunk = data.slice(i, i + chunkSize)
await processChunk(chunk)
// Browser'a render için zaman tanı
await new Promise(resolve => setTimeout(resolve, 0))
}
}
button.addEventListener('click', async () => {
await processDataChunked(hugeDataset) // UI responsive kalır
})2. Code Splitting ve Lazy Loading
// ❌ Kötü - Tüm kod upfront yüklenir
import { heavyLibrary } from 'heavy-library' // 250kb
import { featureA } from './featureA' // 100kb
import { featureB } from './featureB' // 80kb
// ✅ İyi - Sadece gerektiğinde yükle
button.addEventListener('click', async () => {
const { featureA } = await import('./featureA')
featureA.execute()
})3. Third-Party Scripts Optimizasyonu
<!-- ❌ Kötü - Blocking script -->
<script src="https://analytics.com/script.js"></script>
<script src="https://ads.com/script.js"></script>
<!-- ✅ İyi - Async/defer -->
<script async src="https://analytics.com/script.js"></script>
<script defer src="https://ads.com/script.js"></script>
<!-- ✅ Daha iyi - Partytown ile web worker'da çalıştır -->
<script type="text/partytown" src="https://analytics.com/script.js"></script>4. Event Handler Optimization
// ❌ Kötü - Her scroll event'te çalışır
window.addEventListener('scroll', () => {
// Heavy computation
updateHeader()
checkVisibility()
})
// ✅ İyi - Debounced
import { debounce } from 'lodash-es'
window.addEventListener('scroll', debounce(() => {
updateHeader()
checkVisibility()
}, 100))
// ✅ Daha iyi - Passive listener + RAF
window.addEventListener('scroll', () => {
requestAnimationFrame(() => {
updateHeader()
})
}, { passive: true })LCP (Largest Contentful Paint)
LCP, sayfanın en büyük görünür elementinin ne kadar sürede render edildiğini ölçer. Kullanıcının "sayfa yüklendi" algısını doğrudan etkiler.
LCP Elementi Nedir?
Genellikle şunlardan biri:
- Hero image
- Video thumbnail
- Background image with text
- Large text block
<!-- Muhtemel LCP elementleri -->
<img src="hero.jpg" alt="Hero" /> <!-- En yaygın -->
<video poster="thumbnail.jpg"></video>
<div style="background-image: url(bg.jpg)">
<h1>Large Heading</h1>
</div>LCP Optimizasyonu
1. Image Optimization
<!-- ❌ Kötü -->
<img src="hero.jpg" alt="Hero" />
<!-- ✅ İyi -->
<img
src="hero.jpg"
srcset="hero-400.jpg 400w, hero-800.jpg 800w, hero-1200.jpg 1200w"
sizes="(max-width: 600px) 400px, (max-width: 1000px) 800px, 1200px"
alt="Hero"
fetchpriority="high"
decoding="async"
width="1200"
height="600"
/>
<!-- ✅ Daha iyi - Modern formats -->
<picture>
<source srcset="hero.avif" type="image/avif" />
<source srcset="hero.webp" type="image/webp" />
<img src="hero.jpg" alt="Hero" fetchpriority="high" />
</picture>2. Preload Critical Resources
<head>
<!-- LCP image'ı preload et -->
<link rel="preload" as="image" href="hero.jpg" fetchpriority="high" />
<!-- Critical CSS -->
<link rel="preload" as="style" href="critical.css" />
<!-- Critical font -->
<link
rel="preload"
as="font"
href="font.woff2"
type="font/woff2"
crossorigin
/>
</head>3. Reduce Server Response Time (TTFB)
// Next.js örneği - Static generation
export async function generateStaticParams() {
return [{ slug: 'post-1' }, { slug: 'post-2' }]
}
// CDN caching
export const revalidate = 3600 // 1 saat cache
// Edge functions
export const runtime = 'edge' // Cloudflare Workers, Vercel Edge4. Remove Render-Blocking Resources
<!-- ❌ Kötü - Blocking CSS -->
<link rel="stylesheet" href="styles.css" />
<!-- ✅ İyi - Critical CSS inline, rest async -->
<style>
/* Critical CSS inline */
.hero { display: flex; }
</style>
<link
rel="preload"
href="styles.css"
as="style"
onload="this.onload=null;this.rel='stylesheet'"
/>
<noscript><link rel="stylesheet" href="styles.css" /></noscript>CLS (Cumulative Layout Shift)
CLS, sayfa yüklenirken beklenmedik layout shift'lerini ölçer. Kullanıcı okurken içerik aniden kaymışsa, berbat bir deneyimdir.
CLS Nasıl Hesaplanır?
CLS = (Impact Fraction) × (Distance Fraction)
Impact: Kaç piksel alanın kaydığı Distance: Ne kadar mesafe kaydığı
CLS Nedenleri ve Çözümleri
1. Images Without Dimensions
<!-- ❌ Kötü - Boyut belirtilmemiş -->
<img src="photo.jpg" alt="Photo" />
<!-- Image yüklenince layout kayar -->
<!-- ✅ İyi - Aspect ratio reserved -->
<img src="photo.jpg" alt="Photo" width="800" height="600" />
<!-- veya CSS ile -->
<img src="photo.jpg" alt="Photo" style="aspect-ratio: 800/600; width: 100%;" />2. Dynamic Content Injection
// ❌ Kötü - Layout shift yaratır
async function loadAd() {
const ad = await fetchAd()
document.getElementById('ad-slot').innerHTML = ad
// Content aşağı kayar!
}
// ✅ İyi - Reserved space
<div id="ad-slot" style="min-height: 250px;">
<!-- Ad buraya gelecek, space zaten ayrılmış -->
</div>3. Web Fonts (FOIT/FOUT)
/* ❌ Kötü - Font yüklenince layout değişir */
body {
font-family: 'CustomFont', sans-serif;
}
/* ✅ İyi - font-display ile FOFT prevent */
@font-face {
font-family: 'CustomFont';
src: url('font.woff2') format('woff2');
font-display: optional; /* FOUT önler */
}
/* ✅ Daha iyi - Fallback font size match */
body {
font-family: 'CustomFont', Arial, sans-serif;
/* size-adjust ile fallback match */
}
@font-face {
font-family: 'CustomFont';
src: url('font.woff2');
size-adjust: 105%; /* Arial boyutuna yaklaştır */
}4. Animations ve Transitions
/* ❌ Kötü - Layout properties animate eder */
.box {
transition: width 0.3s, height 0.3s;
}
.box:hover {
width: 200px; /* Layout shift! */
}
/* ✅ İyi - Transform kullan (compositor thread'de) */
.box {
transition: transform 0.3s;
}
.box:hover {
transform: scale(1.2); /* Layout shift yok */
}Core Web Vitals Ölçüm Araçları
1. PageSpeed Insights
https://pagespeed.web.dev/
Lab Data: Simüle edilmiş ortamda ölçüm Field Data: Gerçek kullanıcılardan Chrome UX Report
2. Chrome DevTools
// Performance tab'da:
// - INP için Event Timing
// - LCP için Largest Contentful Paint marker
// - CLS için Layout Shifts
// Console'da Web Vitals ölçümü:
import { onCLS, onINP, onLCP } from 'web-vitals'
onLCP(console.log)
onINP(console.log)
onCLS(console.log)3. Real User Monitoring (RUM)
// app/layout.jsx
import { SpeedInsights } from '@vercel/speed-insights/next'
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<SpeedInsights /> {/* Otomatik RUM */}
</body>
</html>
)
}4. Google Search Console
Core Web Vitals report'u hangi sayfalarda problem olduğunu gösterir:
- Mobile/Desktop ayrı raporlar
- Sayfa grupları (poor/needs improvement/good)
- Zaman içinde trend
Mobile-First Optimization
Google mobile performansı önceliklendirir. Desktop vitals mükemmel olsa bile, mobile kötüyse ranking düşer.
Mobile Optimization Checklist
1. Responsive Images
<picture>
<!-- Mobile için küçük, optimize edilmiş -->
<source
media="(max-width: 600px)"
srcset="hero-mobile.avif"
type="image/avif"
/>
<!-- Desktop için büyük -->
<source srcset="hero-desktop.avif" type="image/avif" />
<img src="hero-desktop.jpg" alt="Hero" />
</picture>2. Touch Target Size
/* WCAG 2.2 minimum: 24x24 CSS pixels */
button, a {
min-width: 44px;
min-height: 44px;
/* Apple guideline: 44x44pt */
}3. Reduce Mobile JavaScript
// Desktop için ağır features yükle
if (window.innerWidth > 1024) {
import('./desktop-features')
}
// Mobile için lightweight alternatives
if ('ontouchstart' in window) {
import('./mobile-gestures')
}Gerçek Dünya Optimization Örnekleri
Case Study: E-ticaret Sitesi
Başlangıç:
- LCP: 4.8s
- INP: 520ms
- CLS: 0.42
Optimizasyonlar:
- Hero image AVIF formatına çevrildi (-65% boyut)
- Product images lazy load edildi
- Third-party scripts async yapıldı
- Intersection Observer ile below-fold content defer edildi
Sonuç:
- LCP: 1.6s (%67 iyileşme)
- INP: 145ms (%72 iyileşme)
- CLS: 0.04 (%90 iyileşme)
- SEO Etkisi: Organik trafik %43 arttı, conversion %28 arttı
Case Study: Blog Sitesi
// Önce: Tüm blog posts upfront render
function BlogList({ posts }) {
return posts.map(post => <BlogCard post={post} />)
}
// Sonra: Virtual scrolling
import { FixedSizeList } from 'react-window'
function BlogList({ posts }) {
return (
<FixedSizeList
height={600}
itemCount={posts.length}
itemSize={200}
>
{({ index, style }) => (
<BlogCard post={posts[index]} style={style} />
)}
</FixedSizeList>
)
}Sonuç: 500 post listesi için INP 680ms'den 95ms'ye düştü.
Common Issues ve Çözümleri
Issue: "Largest Contentful Paint element not visible"
<!-- Problem: LCP elementi lazy load edilmiş -->
<img loading="lazy" src="hero.jpg" />
<!-- Çözüm: Above-fold images eager loading -->
<img loading="eager" fetchpriority="high" src="hero.jpg" />Issue: "Long tasks blocking main thread"
// Problem: Synchronous heavy computation
function heavyTask() {
for (let i = 0; i < 1000000; i++) {
// CPU-intensive
}
}
// Çözüm: Web Worker'da çalıştır
// worker.js
self.onmessage = (e) => {
const result = heavyComputation(e.data)
self.postMessage(result)
}
// main.js
const worker = new Worker('worker.js')
worker.postMessage(data)
worker.onmessage = (e) => {
updateUI(e.data) // Non-blocking!
}Issue: "CLS from dynamic ads"
// Problem: Ad slots boyut bilmiyor
<div id="ad"></div>
// Çözüm: Reserved space
<div
id="ad"
style={{
minHeight: '250px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}}
>
<div>Ad Loading...</div>
</div>Sık Sorulan Sorular
Core Web Vitals ne sıklıkla güncelleniyor?
Google, field data'yı 28 günlük rolling average ile güncelliyor. Yaptığınız iyileştirmelerin etkisini görmek 4-6 hafta sürebilir.
Lab ve Field Data farklı, hangisi önemli?
Field Data (gerçek kullanıcılar) ranking için kullanılır. Lab Data (PageSpeed Insights) debug için faydalıdır.
Single Page Apps (SPA) için CWV nasıl ölçülür?
Soft navigations (SPA route changes) için Web Vitals extension kullanın. Yakında Google bu ölçümleri de algoritmasına ekleyecek.
Third-party scripts CWV'yi etkiler mi?
Evet, ciddi şekilde. Google Tag Manager, analytics, ads CWV'nin %50-70'ini etkileyebilir. Partytown veya async loading kullanın.
Mobile ve Desktop ayrı optimize edilmeli mi?
Evet. Mobile öncelikli olmalı çünkü Google mobile-first indexing kullanıyor. Responsive design yeterli değil, mobile-specific optimizations gerekli.
CWV skoru 100 olmalı mı?
Hayır. 75-85 arası skor zaten "good" kategorisi. 100 peşinde koşmak diminishing returns getirir.
Sonuç
Core Web Vitals 2025'te artık opsiyonel değil, zorunlu. Google'ın ranking algoritmasındaki ağırlığı her geçen gün artıyor. INP'nin FID'in yerine geçmesiyle, gerçek kullanıcı deneyimi artık daha doğru ölçülüyor.
İyi haber: Core Web Vitals optimizasyonu aynı zamanda gerçek kullanıcı deneyimini de iyileştiriyor. Daha hızlı sayfa, daha az layout shift, daha responsive UI = daha mutlu kullanıcılar = daha fazla conversion.
Aksiyon Öğeleri:
- PageSpeed Insights'ta sitenizi test edin
- Mobile skorlarınızı önceliklendirin
- LCP elementi için image optimization yapın
- Third-party scripts'i async/defer yapın
- CLS için tüm images'a width/height ekleyin
- Google Search Console'da Core Web Vitals report'unu inceleyin
- 4 hafta sonra tekrar ölçün ve iterate edin
Performance optimization bir sprint değil marathon. Sürekli monitoring ve iyileştirme yapın!
Projenizi Hayata Geçirelim
Web sitesi, mobil uygulama veya yapay zeka çözümü mü arıyorsunuz? Fikirlerinizi birlikte değerlendirelim.
Ücretsiz Danışmanlık Alın