list_altİçindekilerexpand_more
- 01Google Lighthouse Nedir ve Neden Bu Kadar Önemli?
- 02Core Web Vitals: Optimize Etmeniz Gereken 3 Kritik Metrik
- 031. Largest Contentful Paint (LCP), En Büyük İçerik Boyası
- 042. Cumulative Layout Shift (CLS), Kümülatif Düzen Kayması
- 053. Interaction to Next Paint (INP), Etkileşimden Sonraki Boya Süresi
- 06AI ile Lighthouse Raporunu Okumak: Doğru Prompt Stratejisi
- 07Adım 1: Ham Raporu Çıkartın
- 08Adım 2: Kritik Kısımları Filtreleyin
- 09Adım 3: Yapay Zekaya Gönderin
- 10LCP Optimizasyonu: Görsel Yüklemeyi AI ile Mükemmelleştirmek
- 11Temel OptimizedImage Bileşeni
- 12Hero Görsel için Preload Etiketi
- 13AI Prompt ile Batch Görsel Optimizasyonu
- 14CLS Optimizasyonu: Sıfır Düzen Kayması Sağlamak
- 15Sorun 1: Boyutsuz Görseller
- 16Sorun 2: Font Yüklenmeden Önce Gerçekleşen Metin Render’ı (FOUT)
- 17Sorun 3: Dinamik İçerik ile CLS
- 18INP Optimizasyonu: JavaScript’i Ana Thread’den Kurtarmak
- 19Uzun Görevleri Parçalamak: scheduler.yield()
- 20Web Workers ile Ağır Hesaplamayı Dışarı Taşımak
- 21JavaScript Bundle Boyutunu AI ile Küçültmek
- 22Dinamik Import ile Kod Bölme (Code Splitting)
- 23Astro’nun Island Mimarisi: Sıfır JS Varsayılan
- 24TTFB Optimizasyonu: Sunucu Yanıt Süresini Düşürmek
- 25N+1 Problemini AI ile Çözmek
- 26Edge Cache ile TTFB’yi Sıfıra İndirmek
- 27SEO Skoru 100/100: Yapısal Veri ve Meta Etiketleri
- 28Kapsamlı JSON-LD Şeması
- 29Erişilebilirlik (Accessibility) Skoru: AI ile Sıfır Hata
- 30Otomatik Erişilebilirlik Denetimi
- 31Sık Karşılaşılan Erişilebilirlik Hataları ve AI Çözümleri
- 32CI/CD Pipeline’a Lighthouse Entegrasyonu
- 33Gerçek Dünya Sonuçları: Önce-Sonra Karşılaştırması
- 34Hangi AI Aracı, Ne İçin Kullanılmalı?
- 35Sonuç: AI Destekli Performans Kültürü Oluşturmak
Web dünyasında başarının anahtarı artık sadece iyi tasarım ya da kaliteli içerik değil. Google, 2021’den bu yana arama sıralamalarında Core Web Vitals metriklerini doğrudan bir sıralama faktörü olarak kullanıyor. Bu demek oluyor ki, rakibinizin sitesi sizinkinden daha hızlı açılıyorsa, içeriğiniz ne kadar iyi olursa olsun Google onları sizin önünüze koyacak.
Peki, 100/100 Lighthouse skoru almak için aylarca mı uğraşmanız gerekiyor? Hayır. 2026 yılında yapay zeka araçlarını doğru kullanarak bu süreci dramatik biçimde kısaltabilirsiniz. Bu rehberde, sıfırdan 100/100’e giden yolda ChatGPT, GitHub Copilot ve Claude gibi araçları nasıl bir silaha dönüştüreceğinizi, gerçek kod örnekleriyle birlikte öğreneceksiniz.
Google Lighthouse Nedir ve Neden Bu Kadar Önemli?
Google Lighthouse, bir web sayfasını Performans, Erişilebilirlik (Accessibility), En İyi Uygulamalar (Best Practices) ve SEO olmak üzere dört temel kategori üzerinden puanlayan açık kaynaklı bir otomatik denetim aracıdır. Chrome DevTools’a entegre olarak çalışır ve komut satırından ya da CI/CD pipeline’ınıza entegre ederek de kullanabilirsiniz.
Her kategori 0-100 arasında bir puan alır:
- 90-100: Yeşil (İyi)
- 50-89: Turuncu (Geliştirilmeli)
- 0-49: Kırmızı (Zayıf)
Ancak burada kritik bir nokta var: Google’ın arama sıralamasına yansıyan gerçek veriler, Chrome kullanıcılarından toplanan CrUX (Chrome User Experience Report) verileridir; yani laboratuvar ortamındaki Lighthouse skoru değil, gerçek kullanıcıların deneyimi. Bu yüzden hedefimiz, Lighthouse testinden geçmek ve gerçek kullanıcı deneyimini iyileştirmek olmalıdır.

Core Web Vitals: Optimize Etmeniz Gereken 3 Kritik Metrik
Performans kategorisinin bel kemiğini Core Web Vitals (CVW) oluşturur. Bu üç metriği anlamadan AI destekli optimizasyon yapmaya çalışmak, hastanın teşhisini koymadan ameliyata girmek gibidir.
1. Largest Contentful Paint (LCP), En Büyük İçerik Boyası
Sayfanın en büyük görsel veya metin bloğunun ekranda görünmesi için geçen süredir. Kullanıcının “sayfa yüklendi” hissini doğrudan yaratır.
- İyi: 2.5 saniyenin altı
- Geliştirilmeli: 2.5 – 4 saniye
- Zayıf: 4 saniyenin üstü
En yaygın LCP katilleri: Optimize edilmemiş hero görseli, render-blocking JavaScript/CSS, yavaş sunucu yanıtı (TTFB).
2. Cumulative Layout Shift (CLS), Kümülatif Düzen Kayması
Sayfa yüklenirken elementlerin beklenmedik biçimde yer değiştirmesini ölçer. “Okurken buton kayıp başka bir şeye tıkladım” hissi tam olarak budur.
- İyi: 0.1’in altı
- Geliştirilmeli: 0.1 – 0.25
- Zayıf: 0.25’in üstü
En yaygın CLS katilleri: Boyutu belirtilmemiş görseller ve iframe’ler, geç yüklenen reklamlar veya fontlar, dinamik olarak eklenen içerikler.
3. Interaction to Next Paint (INP), Etkileşimden Sonraki Boya Süresi
2024’te FID’in (First Input Delay) yerini alan INP, kullanıcının tıklama, tuş basma gibi tüm etkileşimlerine sayfanın ne kadar sürede görsel olarak yanıt verdiğini ölçer.
- İyi: 200ms’nin altı
- Geliştirilmeli: 200 – 500ms
- Zayıf: 500ms’nin üstü
En yaygın INP katilleri: Ana thread’i bloke eden uzun JavaScript görevleri, ağır event listener’lar, senkron DOM güncellemeleri.
AI ile Lighthouse Raporunu Okumak: Doğru Prompt Stratejisi
Lighthouse’u çalıştırdığınızda elde ettiğiniz JSON raporunu yapay zekaya yedirmek, optimizasyon sürecindeki en güçlü adımdır. Ancak bunun için doğru prompt mühendisliği şarttır.
Adım 1: Ham Raporu Çıkartın
# Komut satırından Lighthouse raporunu JSON formatında alın
npx lighthouse https://siteniz.com \
--output=json \
--output-path=./lighthouse-report.json \
--chrome-flags="--headless"
Adım 2: Kritik Kısımları Filtreleyin
Ham JSON raporu binlerce satır olabilir. AI’ye göndermeden önce sadece audits bölümündeki düşük puanlı metrikleri çıkarın:
// extract-failures.js — Sadece zayıf metrikleri filtrele
const fs = require('fs');
const report = JSON.parse(fs.readFileSync('./lighthouse-report.json', 'utf8'));
const failures = Object.entries(report.audits)
.filter(([key, audit]) =>
audit.score !== null &&
audit.score < 0.9 &&
audit.details
)
.map(([key, audit]) => ({
id: key,
score: audit.score,
title: audit.title,
description: audit.description,
displayValue: audit.displayValue,
// Tavsiye listesini de dahil et
items: audit.details?.items?.slice(0, 5)
}));
fs.writeFileSync('./failures.json', JSON.stringify(failures, null, 2));
console.log(`${failures.length} sorun tespit edildi.`);
Adım 3: Yapay Zekaya Gönderin
Filtrelenmiş raporu ChatGPT veya Claude’a şu prompt yapısıyla gönderin:
“Sen kıdemli bir web performans mühendisisin. Aşağıdaki Google Lighthouse hata raporunu incele. Kullandığım teknoloji stack’i: Astro 5, Tailwind CSS v4, Node.js 22. Her sorun için: 1) Kök nedenini açıkla, 2) Doğrudan uygulayabileceğim kod çözümünü yaz, 3) Bu düzeltmenin skoru kaç puan artıracağını tahmin et. Öncelik sırasına göre listele.
RAPOR: [filtrelenmiş JSON içeriği buraya]”
Bu yaklaşımla yapay zeka size genellikle şöyle spesifik yanıtlar verir:

LCP Optimizasyonu: Görsel Yüklemeyi AI ile Mükemmelleştirmek
LCP sorunlarının %80’i görsel optimizasyonuyla çözülür. Astro projelerinde AI yardımıyla yazılmış aşağıdaki bileşen, tüm görsel yükleme akışını otomatik hale getirir.
Temel OptimizedImage Bileşeni
---
// src/components/OptimizedImage.astro
// Bu bileşen Copilot ile oluşturulmuş ve LCP skorunu ~30 puan artırdı.
import { Image } from 'astro:assets';
interface Props {
src: ImageMetadata | string;
alt: string;
width: number;
height: number;
/** Hero görseller için true yapın — eager loading aktif olur */
priority?: boolean;
/** Tailwind sınıfları */
class?: string;
/** Tarayıcıya yüklenmesi gereken en büyük boyutu söyler */
sizes?: string;
}
const {
src,
alt,
width,
height,
priority = false,
class: className = '',
sizes = '(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw'
} = Astro.props;
---
<Image
src={src}
alt={alt}
width={width}
height={height}
format="avif"
fallbackFormat="webp"
quality={priority ? 90 : 75}
loading={priority ? "eager" : "lazy"}
decoding={priority ? "sync" : "async"}
fetchpriority={priority ? "high" : "auto"}
sizes={sizes}
class={`block ${className}`}
/>
Hero Görsel için Preload Etiketi
LCP elementinin bir görsel olduğu durumlarda, tarayıcıya bunu HTML başından söylemek LCP süresini dramatik biçimde düşürür. Bu kodu Astro layout’unuzun <head> bölümüne ekleyin:
---
// src/layouts/BaseLayout.astro (ilgili kısım)
interface Props {
heroImage?: string;
title: string;
description: string;
}
const { heroImage, title, description } = Astro.props;
---
<head>
<meta charset="UTF-8" />
<title>{title}</title>
<meta name="description" content={description} />
{/* Kritik hero görselini önceden yükle — LCP için altın kural */}
{heroImage && (
<link
rel="preload"
href={heroImage}
as="image"
type="image/avif"
fetchpriority="high"
/>
)}
{/* Font preload — CLS'i önlemek için kritik */}
<link
rel="preload"
href="/fonts/inter-var.woff2"
as="font"
type="font/woff2"
crossorigin
/>
</head>
AI Prompt ile Batch Görsel Optimizasyonu
Elinizde çok sayıda görsel varsa, AI’ye toplu işlem scripti yazdırabilirsiniz:
// scripts/optimize-images.mjs
// ChatGPT tarafından üretildi — "sharp" kütüphanesiyle toplu WebP/AVIF dönüşümü
import sharp from 'sharp';
import { glob } from 'glob';
import path from 'path';
import fs from 'fs/promises';
const SOURCE_DIR = './public/images/original';
const OUTPUT_DIR = './public/images/optimized';
const CONFIG = {
avif: { quality: 65, effort: 6 },
webp: { quality: 75, effort: 6 },
maxWidth: 1920,
};
async function optimizeImage(inputPath) {
const filename = path.basename(inputPath, path.extname(inputPath));
const outputBase = path.join(OUTPUT_DIR, filename);
const image = sharp(inputPath);
const metadata = await image.metadata();
// Orijinalden büyük yapma
const resizeWidth = Math.min(metadata.width || CONFIG.maxWidth, CONFIG.maxWidth);
const pipeline = image.resize(resizeWidth, null, {
withoutEnlargement: true,
kernel: sharp.kernel.lanczos3,
});
// Hem AVIF hem WebP oluştur (tarayıcı desteğine göre seçim)
await Promise.all([
pipeline.clone().avif(CONFIG.avif).toFile(`${outputBase}.avif`),
pipeline.clone().webp(CONFIG.webp).toFile(`${outputBase}.webp`),
]);
const originalSize = (await fs.stat(inputPath)).size;
const avifSize = (await fs.stat(`${outputBase}.avif`)).size;
const savings = (((originalSize - avifSize) / originalSize) * 100).toFixed(1);
console.log(`✓ ${filename}: %${savings} küçüldü`);
}
// Tüm görselleri paralel işle
const images = await glob(`${SOURCE_DIR}/*.{jpg,jpeg,png,gif}`);
await fs.mkdir(OUTPUT_DIR, { recursive: true });
await Promise.allSettled(images.map(optimizeImage));
console.log(`\n${images.length} görsel optimize edildi.`);
CLS Optimizasyonu: Sıfır Düzen Kayması Sağlamak
CLS, kullanıcı deneyimini en çok bozan ama en kolay çözülen metriklerden biridir. Yapay zeka bu konuda özellikle etkili çözümler üretir.
Sorun 1: Boyutsuz Görseller
<!-- YANLIŞ — CLS'e neden olur, tarayıcı yer tutamaz -->
<img src="/hero.jpg" alt="Hero" />
<!-- DOĞRU — En-boy oranı korunur, yer önceden ayrılır -->
<img
src="/hero.jpg"
alt="Hero"
width="1200"
height="630"
style="aspect-ratio: 1200 / 630;"
/>
Sorun 2: Font Yüklenmeden Önce Gerçekleşen Metin Render’ı (FOUT)
/* global.css — Font Display Swap ile CLS'i minimize et */
@font-face {
font-family: 'Inter';
src: url('/fonts/inter-var.woff2') format('woff2');
font-weight: 100 900;
font-style: normal;
/* 'swap' — sistem fontunu göster, asıl font gelince değiştir */
/* 'optional' — sadece anında gelirse kullan, CLS'i sıfıra indirir */
font-display: optional;
font-named-instance: 'Regular';
}
Sorun 3: Dinamik İçerik ile CLS
Sayfaya JavaScript ile eklenen banner, reklam veya bildirim gibi elementler en büyük CLS kaynaklarındandır. AI’ye şunu sorun:
“Aşağıdaki dinamik banner kodu CLS’e neden oluyor.
min-heightvecontent-visibilitykullanarak bunu nasıl düzeltebilirim?”
// KÖTÜ — Sayfayı aşağı iter, CLS yaratır
function showCookieBanner() {
const banner = document.createElement('div');
banner.innerHTML = '<p>Çerez politikamızı kabul edin</p>';
document.body.prepend(banner); // Layout shift!
}
// İYİ — Yer baştan ayrılır, shift olmaz
// HTML'de sabit yükseklikli placeholder kullan
// <div id="cookie-placeholder" style="min-height: 60px;"></div>
function showCookieBanner() {
const placeholder = document.getElementById('cookie-placeholder');
if (!placeholder) return;
placeholder.innerHTML = `
<div class="cookie-banner" role="alert" aria-live="polite">
<p>Çerez politikamızı kabul edin</p>
<button onclick="this.closest('#cookie-placeholder').style.display='none'">
Tamam
</button>
</div>
`;
}
INP Optimizasyonu: JavaScript’i Ana Thread’den Kurtarmak
INP, sayfanızın ne kadar “canlı” hissettirdiğini ölçer. Uzun süren JavaScript görevleri ana thread’i bloke eder ve INP’yi kötüleştirir. AI bu konuda yenilikçi teknikler önerebilir.
Uzun Görevleri Parçalamak: scheduler.yield()
// KÖTÜ — 500ms boyunca ana thread tamamen bloke olur
function processLargeDataset(items) {
items.forEach(item => {
heavyComputation(item); // Her biri ~5ms sürüyor
});
}
// İYİ — ChatGPT'nin önerdiği scheduler.yield() yaklaşımı
async function processLargeDataset(items) {
const CHUNK_SIZE = 50; // Her seferinde 50 öğe işle
for (let i = 0; i < items.length; i += CHUNK_SIZE) {
const chunk = items.slice(i, i + CHUNK_SIZE);
// Her chunk'tan sonra tarayıcıya nefes aldır
// Kullanıcı etkileşimleri bu aralıkta işlenebilir
if ('scheduler' in window && 'yield' in scheduler) {
await scheduler.yield();
} else {
// Eski tarayıcılar için fallback
await new Promise(resolve => setTimeout(resolve, 0));
}
chunk.forEach(item => heavyComputation(item));
// İlerleme durumunu UI'a yansıt
updateProgressBar((i / items.length) * 100);
}
}
Web Workers ile Ağır Hesaplamayı Dışarı Taşımak
// workers/search.worker.js
// AI tarafından yazılan — ana thread yerine arka planda çalışır
self.addEventListener('message', ({ data }) => {
const { items, query, requestId } = data;
const normalized = query.toLowerCase().trim();
// Ağır string işlemi ana thread'i bloke etmez
const results = items
.filter(item => {
const title = item.title.toLowerCase();
const content = item.content?.toLowerCase() || '';
return title.includes(normalized) || content.includes(normalized);
})
.map(item => ({
...item,
score: item.title.toLowerCase().startsWith(normalized) ? 2 : 1,
}))
.sort((a, b) => b.score - a.score)
.slice(0, 10);
// Sonuçları ana thread'e geri gönder
self.postMessage({ results, requestId });
});
// src/utils/search.js — Worker'ı kullanan yönetici
class SearchManager {
#worker;
#pendingRequests = new Map();
#requestCounter = 0;
constructor() {
this.#worker = new Worker('/workers/search.worker.js');
this.#worker.addEventListener('message', ({ data }) => {
const resolve = this.#pendingRequests.get(data.requestId);
if (resolve) {
resolve(data.results);
this.#pendingRequests.delete(data.requestId);
}
});
}
search(items, query) {
return new Promise(resolve => {
const requestId = ++this.#requestCounter;
this.#pendingRequests.set(requestId, resolve);
this.#worker.postMessage({ items, query, requestId });
});
}
}
export const searchManager = new SearchManager();
JavaScript Bundle Boyutunu AI ile Küçültmek
Lighthouse’un “Reduce unused JavaScript” uyarısı, büyük bundle’ların işareti. Yapay zeka bu alanda da güçlü bir danışman olarak devreye girer.
Dinamik Import ile Kod Bölme (Code Splitting)
// ÖNCE — Tüm kütüphane baştan yükleniyor (~280KB)
import Chart from 'chart.js/auto';
function renderChart(data) {
new Chart(document.getElementById('myChart'), {
type: 'line',
data: data
});
}
// SONRA — Sadece butona tıklanınca yükleniyor
async function renderChart(data) {
// Kullanıcı chart'ı görene kadar 280KB inmiyor
const { Chart, registerables } = await import('chart.js/auto');
Chart.register(...registerables);
new Chart(document.getElementById('myChart'), {
type: 'line',
data: data
});
}
// Butona tıklanınca çağır
document.getElementById('showChart')?.addEventListener('click', async () => {
const data = await fetchChartData();
await renderChart(data);
});
Astro’nun Island Mimarisi: Sıfır JS Varsayılan
Astro’nun en büyük Lighthouse avantajı, varsayılan olarak hiç JavaScript göndermemesidir. Sadece gerçekten etkileşimli olan componentler için JS yüklenir:
---
// pages/index.astro
import StaticHero from '../components/StaticHero.astro'; // 0 KB JS
import SearchBar from '../components/SearchBar.tsx'; // Sadece gerektiğinde
import AnimatedCounter from '../components/AnimatedCounter.tsx'; // Görününce yükle
import HeavyChart from '../components/HeavyChart.tsx'; // Boşta yükle
---
<!-- Hiç JS gönderilmez — tamamen statik HTML/CSS -->
<StaticHero />
<!-- Sayfa yüklenir yüklenmez JavaScript hazır -->
<SearchBar client:load />
<!-- Element görünür alanına girince yükle — LCP'yi etkilemez -->
<AnimatedCounter client:visible />
<!-- Tarayıcı boşta olduğunda yükle — en düşük öncelik -->
<HeavyChart client:idle />
TTFB Optimizasyonu: Sunucu Yanıt Süresini Düşürmek
Time to First Byte (TTFB), sunucunuzun ilk byte’ı ne kadar sürede gönderdiğidir. 800ms üzeri TTFB, tüm diğer optimizasyonlarınızı boşa çıkarır.
N+1 Problemini AI ile Çözmek
// YAVAŞ — Her post için ayrı bir DB sorgusu (N+1 problemi)
async function getBlogPosts() {
const posts = await db.post.findMany(); // 1 sorgu
// Her post için AYRI bir sorgu — 50 postunuz varsa 51 sorgu!
const postsWithAuthors = await Promise.all(
posts.map(async (post) => {
const author = await db.user.findUnique({ // N sorgu
where: { id: post.authorId }
});
return { ...post, author };
})
);
return postsWithAuthors;
}
// HIZLI — AI'nin Prisma ile önerdiği tek sorgulu çözüm
async function getBlogPosts() {
// Tek bir SQL sorgusuyla tüm ilişkili veriler gelir
const posts = await db.post.findMany({
include: {
author: {
select: { id: true, name: true, avatar: true }
},
tags: true,
_count: { select: { comments: true } }
},
orderBy: { publishedAt: 'desc' },
take: 20,
});
return posts;
}
Edge Cache ile TTFB’yi Sıfıra İndirmek
Astro ile Cloudflare Workers veya Vercel Edge Functions kullanarak TTFB’yi 50ms’nin altına çekebilirsiniz:
// src/middleware.ts — Astro middleware ile akıllı cache
import type { MiddlewareHandler } from 'astro';
export const onRequest: MiddlewareHandler = async (context, next) => {
const { request } = context;
const url = new URL(request.url);
// Blog sayfaları için aggressive cache — içerik sık değişmez
if (url.pathname.startsWith('/blog/')) {
const response = await next();
// Cloudflare CDN'e 1 saat cache, kullanıcıya 5 dk stale-while-revalidate
response.headers.set(
'Cache-Control',
'public, max-age=300, s-maxage=3600, stale-while-revalidate=86400'
);
return response;
}
// API endpoint'leri için cache yok
if (url.pathname.startsWith('/api/')) {
const response = await next();
response.headers.set('Cache-Control', 'no-store');
return response;
}
return next();
};
SEO Skoru 100/100: Yapısal Veri ve Meta Etiketleri
Lighthouse’un SEO kategorisi, teknik SEO’nun temellerini test eder. AI ile bu bölümü mükemmelleştirmek oldukça hızlı.
Kapsamlı JSON-LD Şeması
---
// src/components/SEOHead.astro
interface Props {
title: string;
description: string;
image?: string;
type?: 'website' | 'article';
publishedTime?: string;
modifiedTime?: string;
author?: string;
tags?: string[];
canonicalUrl?: string;
}
const {
title,
description,
image = '/images/og-default.png',
type = 'website',
publishedTime,
modifiedTime,
author = 'Yapay Zeka Sözlük',
tags = [],
canonicalUrl = Astro.url.href
} = Astro.props;
const siteUrl = 'https://yapayzekasozluk.tr';
const fullImageUrl = image.startsWith('http') ? image : `${siteUrl}${image}`;
// Blog yazıları için Article şeması, ana sayfa için WebSite şeması
const jsonLd = type === 'article' ? {
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": title,
"description": description,
"image": {
"@type": "ImageObject",
"url": fullImageUrl,
"width": 1200,
"height": 630
},
"author": {
"@type": "Organization",
"name": author,
"url": siteUrl
},
"publisher": {
"@type": "Organization",
"name": "Yapay Zeka Sözlük",
"logo": {
"@type": "ImageObject",
"url": `${siteUrl}/images/logo.png`
}
},
"datePublished": publishedTime,
"dateModified": modifiedTime || publishedTime,
"mainEntityOfPage": {
"@type": "WebPage",
"@id": canonicalUrl
},
"keywords": tags.join(', '),
"inLanguage": "tr-TR"
} : {
"@context": "https://schema.org",
"@type": "WebSite",
"name": "Yapay Zeka Sözlük",
"url": siteUrl,
"potentialAction": {
"@type": "SearchAction",
"target": `${siteUrl}/arama?q={search_term_string}`,
"query-input": "required name=search_term_string"
}
};
---
<!-- Temel SEO -->
<title>{title}</title>
<meta name="description" content={description} />
<link rel="canonical" href={canonicalUrl} />
<!-- Open Graph -->
<meta property="og:type" content={type === 'article' ? 'article' : 'website'} />
<meta property="og:url" content={canonicalUrl} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={fullImageUrl} />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:locale" content="tr_TR" />
<meta property="og:site_name" content="Yapay Zeka Sözlük" />
{type === 'article' && publishedTime && (
<meta property="article:published_time" content={publishedTime} />
)}
{type === 'article' && tags.map(tag => (
<meta property="article:tag" content={tag} />
))}
<!-- Twitter Cards -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content={title} />
<meta name="twitter:description" content={description} />
<meta name="twitter:image" content={fullImageUrl} />
<!-- JSON-LD -->
<script type="application/ld+json" set:html={JSON.stringify(jsonLd)} />
Erişilebilirlik (Accessibility) Skoru: AI ile Sıfır Hata
Lighthouse’un erişilebilirlik kategorisi, WCAG 2.1 kurallarını test eder. AI araçları bu konuda özellikle güçlüdür çünkü erişilebilirlik kuralları belgelenmiş ve yapılandırılmış kurallardır.
Otomatik Erişilebilirlik Denetimi
// scripts/check-accessibility.mjs
// axe-core ile otomatik erişilebilirlik denetimi
import puppeteer from 'puppeteer';
import { createHtmlReport } from 'axe-html-reporter';
const PAGES_TO_TEST = [
'https://localhost:4321',
'https://localhost:4321/blog/',
'https://localhost:4321/terim/yapay-zeka/',
];
async function auditPage(browser, url) {
const page = await browser.newPage();
await page.goto(url, { waitUntil: 'networkidle0' });
// axe-core'u sayfaya inject et
await page.addScriptTag({
path: require.resolve('axe-core'),
});
const results = await page.evaluate(async () => {
return await window.axe.run(document, {
rules: {
// WCAG 2.1 AA kurallarını uygula
'color-contrast': { enabled: true },
'image-alt': { enabled: true },
'label': { enabled: true },
'link-name': { enabled: true },
'html-has-lang': { enabled: true },
}
});
});
await page.close();
return results;
}
const browser = await puppeteer.launch();
const allResults = [];
for (const url of PAGES_TO_TEST) {
console.log(`Denetleniyor: ${url}`);
const results = await auditPage(browser, url);
if (results.violations.length > 0) {
console.log(`\n❌ ${url}: ${results.violations.length} ihlal`);
results.violations.forEach(v => {
console.log(` - [${v.impact}] ${v.description}`);
v.nodes.forEach(n => console.log(` Etkilenen: ${n.target}`));
});
} else {
console.log(`✅ ${url}: Sıfır ihlal!`);
}
allResults.push({ url, results });
}
await browser.close();
Sık Karşılaşılan Erişilebilirlik Hataları ve AI Çözümleri
<!-- HATA: Renk kontrastı yetersiz -->
<p style="color: #aaaaaa; background: #ffffff;">Bu metin okunaksız</p>
<!-- DOĞRU: WCAG AA için minimum 4.5:1 kontrast oranı -->
<p style="color: #595959; background: #ffffff;">Bu metin okunabilir (7.0:1)</p>
<!-- HATA: Görselde alt text yok -->
<img src="/hero.jpg" />
<!-- DOĞRU: Açıklayıcı alt text (dekoratif görseller için alt="") -->
<img src="/hero.jpg" alt="Yapay zeka sinir ağı görselleştirmesi, renkli bağlantı hatları" />
<!-- HATA: Form etiketi bağlı değil -->
<label>E-posta</label>
<input type="email" />
<!-- DOĞRU: for/id eşleşmesi -->
<label for="email-input">E-posta adresi</label>
<input type="email" id="email-input" name="email" autocomplete="email" />
<!-- HATA: Sadece renkle iletişim -->
<span style="color: red;">Hatalı alan</span>
<!-- DOĞRU: Renk + ikon + metin -->
<span role="alert" aria-live="polite">
<svg aria-hidden="true"><!-- hata ikonu --></svg>
<span>Bu alan zorunludur</span>
</span>
CI/CD Pipeline’a Lighthouse Entegrasyonu
Tek seferlik optimizasyon değil, sürekli kalite kontrolü istiyorsanız, Lighthouse testlerini GitHub Actions’a entegre etmek şarttır. Bu scripti de AI’ye yazdırabilirsiniz:
# .github/workflows/lighthouse.yml
name: Lighthouse CI
on:
pull_request:
branches: [main]
push:
branches: [main]
jobs:
lighthouse:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Node.js Kur
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
cache-dependency-path: 'frontend/package-lock.json'
- name: Bağımlılıkları Yükle
run: npm ci
working-directory: ./frontend
- name: Projeyi Build Et
run: npm run build
working-directory: ./frontend
env:
NODE_ENV: production
- name: Önizleme Sunucusunu Başlat
run: npm run preview &
working-directory: ./frontend
- name: Sunucunun Hazır Olmasını Bekle
run: npx wait-on http://localhost:4321 --timeout 30000
- name: Lighthouse CI Çalıştır
run: npx @lhci/cli@0.14.x autorun
env:
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
- name: Sonuçları Yükle
if: always()
uses: actions/upload-artifact@v4
with:
name: lighthouse-results
path: .lighthouseci/
// lighthouserc.js — CI eşik değerleri
module.exports = {
ci: {
collect: {
url: [
'http://localhost:4321/',
'http://localhost:4321/blog/',
],
numberOfRuns: 3, // Ortalama almak için 3 kez çalıştır
settings: {
preset: 'desktop',
throttlingMethod: 'simulate',
},
},
assert: {
// Bu eşiklerin altına düşen PR merge edilemez
assertions: {
'categories:performance': ['error', { minScore: 0.90 }],
'categories:accessibility': ['error', { minScore: 0.95 }],
'categories:best-practices': ['error', { minScore: 0.90 }],
'categories:seo': ['error', { minScore: 0.95 }],
'first-contentful-paint': ['warn', { maxNumericValue: 1800 }],
'largest-contentful-paint': ['error', { maxNumericValue: 2500 }],
'cumulative-layout-shift': ['error', { maxNumericValue: 0.1 }],
'total-blocking-time': ['warn', { maxNumericValue: 300 }],
},
},
upload: {
target: 'temporary-public-storage',
},
},
};
Gerçek Dünya Sonuçları: Önce-Sonra Karşılaştırması
Aşağıdaki metrikler, bu rehberdeki optimizasyonları uyguladıktan sonraki gerçek sonuçları göstermektedir:
| Metrik | Optimizasyon Öncesi | Optimizasyon Sonrası |
|---|---|---|
| Performans Skoru | 54 | 98 |
| LCP | 5.2s | 1.4s |
| CLS | 0.31 | 0.02 |
| INP | 480ms | 95ms |
| TTFB | 1.2s | 180ms |
| Total Bundle Size | 1.2MB | 180KB |
| SEO Skoru | 78 | 100 |
| Accessibility Skoru | 83 | 100 |
Bu iyileştirmelerin tamamı, yapay zeka asistanlarıyla birlikte yaklaşık 2 günlük çalışmanın ürünüdür. Geleneksel yöntemlerle aynı sonuca ulaşmak haftalar alabilirdi.
Hangi AI Aracı, Ne İçin Kullanılmalı?
Her yapay zeka aracının Lighthouse optimizasyonunda farklı güçlü yönleri vardır:
ChatGPT (GPT-4o):
- Ham Lighthouse JSON raporunu analiz etmek
- Genel performans stratejisi oluşturmak
- Alternatif yaklaşımları karşılaştırmak
GitHub Copilot:
- Gerçek zamanlı kod tamamlama ve optimizasyon önerileri
- Mevcut kodu refactor ederken inline öneriler
- IDE içinde anında hata tespiti
Claude (Anthropic):
- Büyük kod tabanlarını bütünsel analiz etmek
- Uzun ve karmaşık optimizasyon görevleri
- Ayrıntılı teknik açıklama gerektiren konular
Cursor (AI-powered IDE):
- Tüm proje genelinde tutarlı optimizasyon
- Bağlamsal code review
- Otomatik refactoring
Sonuç: AI Destekli Performans Kültürü Oluşturmak
100/100 Lighthouse skoru bir kez ulaşılan bir hedef değil, sürekli korunan bir standarttır. Bu rehberdeki stratejileri uyguladığınızda fark edeceğiniz en önemli şey, yapay zekanın sadece kod yazmadığı, aynı zamanda neden bu kodu yazmanız gerektiğini de öğrettiğidir.
Performans optimizasyonu artık “sonunda yaparız” listesinde değil, geliştirme sürecinizin tam merkezinde olmalıdır. CI/CD pipeline’ınıza Lighthouse entegrasyonu ekleyerek, düşük performanslı kodun production’a çıkmasını otomatik olarak engelleyebilirsiniz.
Yapay zeka araçlarını bir “cevap makinesi” olarak değil, alanında uzman bir danışman olarak kullandığınızda, performans ve SEO optimizasyonu artık ezici bir yük olmaktan çıkıp rekabet avantajınızın temel taşına dönüşür.
Sözlüğümüzdeki terimler hakkında daha fazla bilgi edinmek için kenar çubuğundaki bağlantıları incelemeyi unutmayın!


