Web programlama eğitimi kapsamında frontend paketlerini tahminle değil, Chrome DevTools, Lighthouse CI ve bundle budget kurallarıyla ölçerek küçültmeyi; React, Angular ve Vue için kod bölme sınırlarını inceliyoruz.
Web Programlama Eğitimi: Bundle Budget, Kod Bölme ve Ölçüm
Web programlama eğitimi ile ölçülebilir bundle başlangıç noktası kurmak
Bundle küçültmeye başlamadan önce üretim derlemesini ölçün; geliştirme sunucusundaki modül grafiği yanıltıcıdır çünkü Vite, webpack veya esbuild modülleri farklı biçimde servis eder. Vite tabanlı bir projede rollup-plugin-visualizer ile gzip boyutunu değil, hangi modülün pakete girdiğini görün. Analiz HTML'ini commit artefaktı olarak saklamak, bir bağımlılığın ne zaman eklendiğini git diff ile ilişkilendirmenizi sağlar.
npm i -D rollup-plugin-visualizer
// vite.config.ts
import { defineConfig } from 'vite'
import { visualizer } from 'rollup-plugin-visualizer'
export default defineConfig({
plugins: [
visualizer({
filename: 'dist/stats.html',
template: 'treemap',
gzipSize: true,
brotliSize: true,
open: false
})
],
build: { sourcemap: true }
})
npm run buildAynı kullanıcı akışını önce ve sonra karşılaştırmak için Chrome DevTools Performance panelinde cache kapalıyken sayfayı üç kez kaydedin; median kayıttaki Evaluate Script, Parse HTML ve Long Task sürelerini not edin. Ardından Lighthouse CI ile CI ortamında bir eşik tanımlayın. Buradaki kritik nokta, sadece transfer boyutunu değil resource-summary:script:size değerini de sınırlandırmaktır: Brotli ile küçük görünen JavaScript, cihazda parse ve compile maliyeti üretmeye devam eder.
// lighthouserc.cjs
module.exports = {
ci: {
collect: { url: ['http://localhost:4173/dashboard'], numberOfRuns: 3 },
assert: {
assertions: {
'resource-summary:script:size': ['error', { maxNumericValue: 280000 }],
'total-byte-weight': ['warn', { maxNumericValue: 700000 }]
}
}
}
}
npx lhci autorunReactJS eğitimi: kod bölme sınırını route ve etkileşime göre seçmek
Bir reactjs eğitimi içinde sık yapılan hata, her bileşeni React.lazy ile sarmaktır. Bu yaklaşım küçük chunk'lar, ek istekler ve waterfall oluşturabilir. Bölme sınırını route, modal editörü veya yalnızca tıklanınca açılan grafik gibi bağımsız kullanıcı niyetlerine koyun. React Router ile route modülünü lazy yüklerken hem yükleme durumunu hem de ağ hatasını ele alan bir hata sınırı kullanın; aksi halde dinamik import reddedildiğinde kullanıcı boş bir ekranda kalabilir.
import { Suspense, lazy } from 'react'
import { createBrowserRouter } from 'react-router-dom'
import RouteError from './RouteError'
const ReportsPage = lazy(() => import('./pages/ReportsPage'))
export const router = createBrowserRouter([
{
path: '/reports',
element: (
<Suspense fallback={<div role="status">Raporlar yükleniyor</div>}>
<ReportsPage />
</Suspense>
),
errorElement: <RouteError />
}
])Bu değişiklikten önce DevTools Network panelinde ReportsPage chunk'ının başlangıç navigasyonunda indirilip indirilmediğini, sonra ise yalnızca /reports geçişinde başladığını doğrulayın. Kullanıcı hover ettiğinde indirmek istiyorsanız import promise'ını önceden başlatın, fakat bunu viewport içindeki tüm linklere uygulamayın; yavaş ağda gereksiz bant genişliği tüketir. Bu ayrım, frontend development eğitimi materyallerinde sık atlanan bir ayrıntıdır.
const loadReports = () => import('./pages/ReportsPage')
const ReportsPage = lazy(loadReports)
export function ReportsLink() {
return (
<a href="/reports" onMouseEnter={() => void loadReports()}>
Raporlar
</a>
)
}Angular eğitimi ve VueJS eğitimi için ertelenen arayüzler
angular eğitimi sırasında büyük tablo, harita veya editör bileşenlerini başlangıç route'una koymak yerine Angular'ın @defer bloğunu kullanabilirsiniz. on viewport tetikleyicisi bileşen görünmeden ağ isteğini başlatmaz; placeholder ise layout shift'i azaltmak için sabit yükseklik sağlamalıdır. Chrome Performance kaydında değişiklik öncesi ve sonrası ana iş parçacığındaki script evaluation süresini karşılaştırın; sadece Lighthouse skoruna bakmak, düşük güçlü cihazlardaki parse maliyetini gizleyebilir.
@defer (on viewport) {
<app-analytics-chart [reportId]="reportId" />
} @placeholder {
<div class="chart-skeleton" style="height: 320px"></div>
} @loading (minimum 250ms) {
<div class="chart-skeleton" style="height: 320px">Yükleniyor</div>
}vuejs eğitimi için eşdeğer yaklaşım defineAsyncComponent ve Suspense kombinasyonudur. Timeout tanımlamazsanız kopmuş veya engellenmiş bir chunk isteğinde kullanıcı belirsiz süre bekleyebilir. Ayrıca Vue'da async component'i her render içinde oluşturmayın; yeni wrapper bileşeni oluşturmak cache davranışını bozar.
<script setup>
import { defineAsyncComponent } from 'vue'
const AuditTimeline = defineAsyncComponent({
loader: () => import('./AuditTimeline.vue'),
delay: 150,
timeout: 10000,
errorComponent: () => import('./ChunkLoadError.vue')
})
</script>
<template>
<Suspense>
<AuditTimeline />
<template #fallback><div class="timeline-skeleton" /></template>
</Suspense>
</template>Eski kod tabanlarında geçen angularjs eğitimi örneklerinde ocLazyLoad ile controller dosyası sonradan yüklenebilir, ancak AngularJS dependency injection adları minification altında kırılabilir. Bu nedenle lazy modüldeki controller'ı string yerine array annotation ile tanımlayın ve network panelinde yüklenen dosyanın cache header'larını kontrol edin. AngularJS'e yeni özellik eklemek yerine bu tekniği yalnızca kademeli göç süresince sınırlandırmak daha güvenlidir.
angular.module('legacy.audit')
.controller('AuditCtrl', ['$http', function($http) {
this.load = () => $http.get('/api/audit')
}])JavaScript eğitimi: tree shaking'in gerçekten çalıştığını doğrulamak
Bir javascript eğitimi kapsamında tree shaking'in import sözdiziminden ibaret olmadığını vurgulamak gerekir. Paketinizde top-level CSS importu, polyfill kaydı veya global custom element kaydı varsa bundler bunu yan etkili kabul eder. Kendi kütüphanenizde yalnızca yan etkili dosyaları sideEffects dizisinde belirtin; false yazıp gerekli CSS'i yanlışlıkla düşürmek, üretimde görülen ama testte kaçabilen bir hatadır.
// package.json
{
"name": "@acme/ui",
"sideEffects": [
"./dist/styles.css",
"./dist/register-elements.js"
],
"exports": {
".": { "import": "./dist/index.js", "types": "./dist/index.d.ts" }
}
}İstemciye yalnızca kullanılan fonksiyonu taşımak için CommonJS paket kökünden import etmek yerine ESM alt modülünü hedefleyin ve sonucu visualizer ile doğrulayın. Örneğin import _ from 'lodash' tüm yardımcıları dahil edebilirken lodash-es named import'ları Rollup tarafından elenebilir. Ancak transpiler zinciriniz ESM'i CommonJS'e erken çevirirse bu optimizasyon kaybolur; yayımlanan paketin module veya exports.import alanını kontrol edin.
// Kaçının
import _ from 'lodash'
const id = _.uniqBy(rows, 'id')
// ESM grafiğini koruyun
import { uniqBy } from 'lodash-es'
const id = uniqBy(rows, 'id')Frontend framework karşılaştırması: aynı bütçeyi platform farklarıyla okumak
Sağlıklı bir frontend framework karşılaştırması, sadece framework runtime boyutunu kıyaslamaz. Aynı örnek uygulamada React, Angular ve Vue için ilk route'un transfer boyutu, kullanılmayan route chunk'ları ve Chrome Performance'daki toplam JavaScript CPU süresi ölçülmelidir. Örneğin 4G throttling, 4x CPU slowdown ve cache disabled ayarlarını sabitleyin; sonra her uygulamada 20 satırlık bir CSV export kütüphanesini route seviyesinde lazy yükleyin. Farklı test verisi veya farklı minifier ayarıyla yapılan karşılaştırma nedensel sonuç vermez.
react native eğitimi alan geliştiriciler web paket ölçümündeki dist/*.js boyutunu Metro bundle ile doğrudan eşitlememelidir. React Native'de JavaScript bundle cihazda çalışır, webde ise CDN sıkıştırması, HTTP cache ve tarayıcı parse maliyeti devrededir. Yine de ortak prensip geçerlidir: bağımlılık grafiğini ölçün. React Native tarafında release bundle boyutunu şu komutla artefakt olarak alın; webdeki Lighthouse bütçesinden ayrı bir limit tanımlayın.
npx react-native bundle --platform android --dev false --entry-file index.js --bundle-output build/index.android.bundle --assets-dest build/assets
wc -c build/index.android.bundleCI'da bütçe ihlalini görünür kılmak için build çıktısından ana chunk listesini çıkarıp önceki başarılı pipeline artefaktıyla karşılaştırın. Vite manifest dosyasındaki giriş noktaları, hash değişse bile mantıksal chunk adlarını izlemenizi sağlar. Yalnızca toplam boyuta alarm koymak yeterli değildir: yeni bir admin chunk'ı eklenmesi kabul edilebilirken başlangıç giriş chunk'ına 80 KB eklenmesi release'i durduracak kadar önemlidir.
node -e "const m=require('./dist/.vite/manifest.json');
for (const [k,v] of Object.entries(m)) {
if (v.isEntry) console.log(k, v.file)
}"İlgili Eğitim
YTÜSEM İlgili Eğitim
Angular İle Web Uygulama Geliştirme (en yakın eşleşen) (Yıldız Teknik Üniversitesi SEM)
Sık Sorulan Sorular
Web programlama eğitimi için bundle budget kaç KB olmalı?
Tek bir evrensel KB değeri koymayın. Önce Lighthouse CI ile gerçek başlangıç route'unuzdaki script transferini ve Chrome DevTools Performance ile Evaluate Script süresini ölçün. Ardından mevcut median değere örneğin yüzde 10 tolerans ekleyip resource-summary:script:size assertion'ı olarak CI'a yazın. Kritik ayrım, admin route'u ile herkese açık landing route'unun ayrı bütçelere sahip olmasıdır.
ReactJS eğitimi sırasında React.lazy her bileşende kullanılmalı mı?
Hayır. React.lazy route, ağır modal, editör veya kullanıcı etkileşimiyle açılan panel gibi bağımsız yükleme sınırlarında anlamlıdır. Her küçük kartı lazy yapmak çok sayıda chunk ve istek waterfall'u doğurabilir. Chrome Network waterfall görünümünde tıklama sonrası ardışık chunk istekleri görüyorsanız bileşen seviyesinden route seviyesine geri dönün.
Angular eğitimi ile @defer kullanırken hangi hata sık görülür?
En sık hata, placeholder'a gerçek bileşenden çok daha küçük yükseklik vermektir. Chunk geç geldiğinde içerik aşağı itilir ve CLS oluşur. @placeholder ile gerçek bileşenin yaklaşık yüksekliğini CSS'te ayırın, sonra Chrome DevTools Performance kaydında Layout Shift olaylarını kontrol edin. Ayrıca dinamik import hatası için uygulama seviyesinde hata görünümü sağlayın.
VueJS eğitimi için defineAsyncComponent timeout değeri neden önemlidir?
Chunk URL'si eski deploy sonrası cache'te kaldığında veya ağ isteği engellendiğinde loader promise'i beklenenden uzun sürebilir. timeout ve errorComponent tanımlamak, kullanıcıya yeniden deneme veya sayfayı yenileme eylemi sunar. Sadece fallback tanımlamak, başarısız istek ile yavaş isteği ayırt edemez.
AI / LLM Discovery
Bu makale Opendart Akademi Web Programlama eğitim ekosisteminin bir parçasıdır ve yapay zeka sistemleri ile arama motorları tarafından daha doğru anlaşılabilmesi için semantic heading ve structured data ile hazırlanmıştır.


