Bundle boyutu
Paketi küçültme ve neyin yüklendiğini görme.
Bundle Nedir
Bundle, uygulama kodunuzun ve bağımlılıklarının tarayıcı ve sunucu için birleştirilip optimize edilmiş çıktı dosyalarıdır. Bu işi yapan araca bundler denir. Küçük bundle daha hızlı iner, daha az çalıştırma süresi ister ve Core Web Vitals değerlerini iyileştirir.1
JavaScript'in bedeli yalnızca indirme değildir: script'i işlemenin asıl maliyeti indirme ve CPU'da çalıştırma süresidir, bu da özellikle düşük güçlü telefonlarda hissedilir.2 2025'te medyan bir sayfa masaüstünde 708 KB, mobilde 646 KB JavaScript yüklüyordu.3
Bugün kullanacağınız bundler büyük ihtimalle hazır gelir. Next.js 16'da varsayılan bundler Turbopack'tir.4 Vite 8 ise Rolldown adlı tek bir Rust tabanlı bundler kullanır.5 Next.js code splitting ve tree shaking gibi optimizasyonları otomatik yapar; sizin işiniz bunlara engel olmamak ve neyin yüklendiğini görmektir.1
Tree Shaking
Tree shaking, kullanılmayan kodun (dead code) bundle'dan atılmasıdır. Bundler, hangi modülün ne export ettiğini ve nerede import edildiğini import/export ifadelerinden çıkarır.6
// utils.ts
export function formatPrice(n: number) { /* ... */ }
export function parseCsv(text: string) { /* ... */ } // hiç import edilmiyor
// page.tsx
import { formatPrice } from "./utils"; // parseCsv bundle'a girmezİşe yaraması için birkaç şart var:78
ES module kullanın.
require()çalışma anında çağrılan bir fonksiyon olduğu için bundler onu derleme anında güvenle analiz edemez.sideEffectsalanı: Bir paketpackage.json'da"sideEffects": falsediyorsa bundler kullanılmayan dosyaları çekinmeden atar. Yalnızca import edildiği için çalışan dosyalar (polyfill, global CSS) listede belirtilmelidir, yoksa production'da düşebilir.Named import tercih edin ve ES module yayınlayan paketleri seçin. Kütüphanenin tamamını getiren import kalıpları eski kurulumlarda tree shaking'i bozabilir.
Code Splitting
Code splitting, bundle'ı parçalara bölüp ilk görünüm için gereken kodu önce, geri kalanı ihtiyaç olunca yüklemektir. Büyük bir başlangıç script'i ana thread'i meşgul eder, etkileşimi geciktirir.9 V8 ekibinin pratik kuralı: 50-100 kB'ı aşan bir bundle'ı daha küçük parçalara bölün.2
Temel araç dinamik import()'tur. Modül, satır çalıştığında ayrı bir dosya olarak iner:10
"use client";
export function Search({ names }: { names: string[] }) {
return (
<input
onChange={async (e) => {
const Fuse = (await import("fuse.js")).default; // yalnızca yazınca iner
console.log(new Fuse(names).search(e.currentTarget.value));
}}
/>
);
}React.lazy
Bir component'i ilk render edildiği anda yüklemek için lazy kullanılır. Yüklenirken Suspense fallback'i gösterir. İçe aktarılan component default export olmalı ve lazy çağrısı component'in dışında, modülün üst seviyesinde yapılmalıdır; içeride tanımlarsanız her render'da state sıfırlanır.11
import { lazy, Suspense } from "react";
const MarkdownPreview = lazy(() => import("./MarkdownPreview"));
export function Editor() {
return (
<Suspense fallback={<p>Yükleniyor...</p>}>
<MarkdownPreview />
</Suspense>
);
}next/dynamic
Next.js'te next/dynamic, React.lazy ile Suspense'in birleşimidir. Lazy loading Client Component'ler için anlamlıdır; Server Component'ler zaten otomatik olarak bölünür.10
"use client";
import { useState } from "react";
import dynamic from "next/dynamic";
const Chart = dynamic(() => import("./Chart"), {
loading: () => <p>Grafik yükleniyor...</p>,
});
export function Report() {
const [open, setOpen] = useState(false);
return (
<>
<button onClick={() => setOpen(true)}>Grafiği göster</button>
{open && <Chart />} {/* kod yalnızca tıklayınca iner */}
</>
);
}Named export için import("./hello").then((mod) => mod.Hello) yazılır. ssr: false seçeneği yalnızca Client Component içinde çalışır, Server Component'te hata verir.10
İpucu
Modal, grafik, zengin metin editörü, harita gibi ilk ekranda görünmeyen ve ağır olan parçalar code splitting için en iyi adaylardır.
Bundle'ı Görmek
Tahmin etmek yerine bundle'ın içine bakın. Bu araçlar her modülü alanı boyutuyla orantılı bir dikdörtgen olarak çizer (treemap).1
Next.js
Next.js 16.1 ve sonrasında Turbopack ile çalışan yerleşik bir analiz aracı vardır:1
$ pnpm dlx next analyzeArayüzde route'a, client/server ortamına ve dosya türüne göre filtreleyebilir, bir modüle tıklayıp onu sayfaya hangi import zincirinin getirdiğini görebilirsiniz.112 --output ile sonuç .next/diagnostics/analyze klasörüne kaydedilir; optimizasyon öncesi ve sonrasını karşılaştırmak için kullanışlıdır.1 Araç ilk sürümlerde next experimental-analyze adıyla duyuruldu, eski yazılarda bu adı görebilirsiniz.12
Projeniz --webpack ile derleniyorsa @next/bundle-analyzer plugin'i ve ANALYZE=true npm run build komutu kullanılır.1
Vite
Vite'ta yaygın seçenek rollup-plugin-visualizer'dır; build sonrası bir HTML rapor üretir.13
$ pnpm add --save-dev rollup-plugin-visualizer// vite.config.ts
import { defineConfig, type PluginOption } from "vite";
import { visualizer } from "rollup-plugin-visualizer";
export default defineConfig({
plugins: [visualizer({ gzipSize: true }) as PluginOption], // listede en sonda
});Hiç ayar eklemeden bakmak isterseniz npx vite-bundle-visualizer aynı plugin'i sizin için çalıştırır.14
Paketin Maliyetini Kurmadan Görmek
Yeni bir bağımlılık eklemeden önce boyutuna bakın. Bundlephobia bir npm paketinin boyutunu, neyden oluştuğunu ve export'larını gösterir.15 pkg-size.dev paketi tarayıcınızda gerçekten kurup bundle'lar; önbellek yerine her seferinde taze kurulum yaptığı için iç içe bağımlılıklardaki değişiklikleri de yansıtır.16
Yap
Paketi eklemeden önce boyutuna ve tree shaking'e uygun olup olmadığına bakın.
Aynı işi yapan iki paketi bu araçlarla karşılaştırın.
Barrel Dosyaları
Barrel dosyası, kendi kodu olmayan, yalnızca başka modülleri yeniden export eden dosyadır (çoğunlukla index.ts). Her klasöre bir barrel koyulduğunda tek bir import, zincirleme olarak projenin büyük kısmını yükleyebilir; bu da özellikle geliştirme sunucusunu, testleri ve lint'i yavaşlatır.17
// components/index.ts (barrel)
export * from "./Button";
export * from "./Modal";
export * from "./DataGrid"; // Button'ı isteyen herkes bunu da işletirİkon ve UI kütüphaneleri de büyük barrel'larla gelir; bazılarında giriş dosyasında 10.000'e yakın export vardır.18 Next.js bu yüzden optimizePackageImports seçeneğini sunar: barrel'ı analiz edip import'u doğrudan kullandığınız modüle yönlendirir.18 lucide-react, date-fns, @mui/material, react-icons gibi popüler kütüphaneler varsayılan olarak zaten optimize edilir; listede olmayan bir paket için elle eklersiniz:19
// next.config.ts
const nextConfig = {
experimental: {
optimizePackageImports: ["my-icon-library"],
},
};
export default nextConfig;Yapma
Kendi projenizde her klasöre
index.tsbarrel'ı koymayın; doğrudan dosyadan import edin:import { Button } from "@/components/Button".17
Üçüncü Parti Script'ler
Analytics, tag manager, chat ve reklam script'leri sizin bundle'ınızda görünmez ama aynı ana thread'i kullanır. Sayfaların %90'ından fazlası en az bir üçüncü parti kaynak kullanıyor; medyan sayfa masaüstünde 83, mobilde 79 üçüncü parti isteği yapıyor.20 Genel kural: kritik render yolunda gerekmiyorsa üçüncü parti script'i async ya da defer ile yükleyin.21
Next.js'te bunu next/script ve strategy prop'u ile yaparsınız:22
| Strateji | Ne zaman yüklenir | Örnek |
|---|---|---|
beforeInteractive | Next.js kodundan önce; yalnızca root layout'ta | Bot tespiti, çerez onayı |
afterInteractive | Varsayılan; hydration'ın bir kısmından sonra | Tag manager, analytics |
lazyOnload | Tarayıcı boştayken, her şey yüklendikten sonra | Chat widget'ı, sosyal medya eklentisi |
import Script from "next/script";
export default function Page() {
return <Script src="https://example.com/chat.js" strategy="lazyOnload" />;
}worker stratejisi hâlâ deneyseldir ve App Router'da çalışmaz. onLoad gibi olay prop'ları yalnızca Client Component'te kullanılabilir.22
Server Components ve Client Bundle
Server Component'te kullanılan kütüphaneler istemciye gönderilmez; tarayıcıya yalnızca üretilen HTML gider. Bu yüzden syntax highlighting, markdown işleme ya da grafik hazırlama gibi tarayıcı API'si ve etkileşim gerektirmeyen ağır işleri Server Component'e taşımak, client bundle'ı küçültmenin etkili bir yoludur.1
Detaylı Öğrenmek İçin
Resmi rehber: Next.js'in bundle analizi ve büyük bundle'ları küçültme rehberi.1
Temel okuma: Addy Osmani ve Mathias Bynens'in JavaScript'in maliyetini anlattığı V8 makalesi.2
Konuşma: Stephen Cooper'ın tree shaking,
sideEffects, barrel dosyaları ve CI'da bundle boyutu takibini anlattığı yaklaşık 26 dakikalık konuşma (WeAreDevelopers World Congress 2025).23Konuşma: Abhijeet Prasad'ın build araçlarının ürettiği JavaScript'i küçültmeyi anlattığı 17 dakikalık konuşma (JSNation US 2024).24
Tree shaking pratikte: Smashing Magazine'in tree shaking başvuru rehberi.8
Kaynaklar
Bundle Analyzer, `@next/bundle-analyzer`, `optimizePackageImports` ve ağır işi Server Component'e taşımak.
İndirme ve çalıştırma maliyeti, bundle'ı 50-100 kB üstünde bölme önerisi.
Sayfa başına medyan JavaScript boyutu ve istek sayısı.
Turbopack'in varsayılan bundler olması ve `--webpack` ile geri dönüş.
Rolldown'ın Vite'ın tek bundler'ı olması.
Tree shaking tanımı ve `import`/`export` ile ilişkisi.
ES module şartı, `sideEffects` alanı ve CSS dosyaları.
CommonJS ile ESM farkı, `sideEffects`, pure annotation ve named import.
Büyük başlangıç script'inin etkisi ve `import()` ile bölme.
`next/dynamic`, `ssr: false`, named export ve kütüphaneyi `import()` ile yükleme.
`lazy` imzası, default export şartı, `Suspense` ve üst seviyede tanımlama.
Deneysel Bundle Analyzer'ın duyurusu ve özellikleri.
Vite kurulumu, rapor şablonları ve gzip/Brotli seçenekleri.
Vite projesinde tek komutla bundle raporu.
npm paketlerinin boyutunu, bileşimini ve export'larını analiz eden araç.
Paketleri tarayıcıda kurup bundle'layan boyut aracı.
Barrel dosyalarının araçları neden yavaşlattığı ve modül sayısının maliyeti.
`optimizePackageImports`'un nasıl çalıştığı ve ölçülen kazançlar.
Ayar ve varsayılan olarak optimize edilen kütüphaneler listesi.
Üçüncü parti kullanım oranı ve sayfa başına istek sayısı.
`async`/`defer`, preconnect, lazy load ve self-host.
`next/script` stratejileri ve olay prop'ları.
- 23VideoStephen Cooper: A Practical Guide to Reducing Bundle Size (WeAreDevelopers World Congress 2025)
Tree shaking, barrel dosyaları ve bundle boyutu regresyon testi.
Minification, down-compilation ve bundle boyutunu izleme.
Son güncelleme tarihi: 17 Ekim 2026
