İçeriğe geç
Muhammet Şafak
en

Chart.js'i nasıl import ettiğin, ziyaretçiye kaç kilobayt gönderdiğini belirliyor

`chart.js/auto` ile seçmeli `Chart.register()` arasındaki fark, gerçek bir üretim derlemesinde kaç kilobayt?

Bulgu

Seçmeli register, `chart.js/auto` yerine 9,7 kB gzip tasarruf ettiriyor (67,8 → 58,1 kB, %14,3). Asıl büyük düşüş kütüphanenin kendisinde değil, hiç kullanılmayan controller'ları dışarıda bırakmakta: yalnız çubuk grafiği kaydeden bir sayfa 46,0 kB'a iniyor — auto'nun üçte ikisi.

Seçmeli register
58,1 kB -14,3%
chart.js/auto
67,8 kB
Yalnız çubuk
46,0 kB -32,2%
Sayfanın ada maliyeti
65,3 kB

Yöntem

Aynı depo, aynı grafik bileşeni ve aynı içerik dosyasıyla dört ayrı `npx astro build` koşuldu; her koşuda yalnız `chart-render.ts`'in import/register satırları değiştirildi. Ölçülen şey Rolldown'ın ürettiği `dist/_astro/chart-render.*.js` parçasının `gzip -9` boyutudur. Derleme deterministik olduğu için tek koşu yeterli: aynı girdi aynı baytı üretti, dört strateji de iki kez koşulup aynı sonuç doğrulandı.

Yüksek güven Tekrarlı ölçüm, denetimli ortam, ham veri paylaşıldı.
Ölçüm tarihi

46 gün önce ölçüldü

Yayın
Güncelleme

Ortam

Astro
7.1.3
Chart.js
4.5.1
Bundler
Rolldown (Astro 7 varsayılanı)
Node
24.18.0
İşletim sistemi
macOS (Darwin 25.6)
Sıkıştırma
gzip -9

Teknolojiler

Chart.js Astro Rolldown Preact

Tekrarlamak için

npx astro build && gzip -9 -c dist/_astro/chart-render.*.js | wc -c

Bu sitede yıllardır tek bir kural vardı: zorunlu istemci JS yok. Research bölümünü açarken o kuralı bilerek deldim — çok serili bir ölçüm, tooltip’i olmayan bir grafikte okunmuyor. Ama “deldim” ile “önemsedim” arasındaki fark, gönderilen baytı ölçüp ölçmediğinde ortaya çıkıyor.

Chart.js’in dokümantasyonu iki yol gösteriyor. Kısa yol:

import Chart from 'chart.js/auto';

Uzun yol:

import { Chart, BarController, BarElement, CategoryScale, LinearScale } from 'chart.js';
Chart.register(BarController, BarElement, CategoryScale, LinearScale);

İkisi de çalışıyor. Sorum şuydu: aradaki fark, gerçek bir derlemede ölçülebilir bir sayı mı, yoksa mikro-optimizasyon mu?

Neyi ölçtüm

Sentetik bir bundler kurmadım — çünkü ölçmek istediğim şey “Chart.js ne kadar küçülebilir” değil, bu depo ne kadar gönderiyor. O yüzden dört koşunun dördü de sitenin kendi astro build hattından geçti: aynı MDX kaydı, aynı grafik bileşeni, aynı Preact adası. Koşular arasında değişen tek şey src/components/research/chart-render.ts dosyasının ilk on satırıydı.

Chart.js parçasının gzip boyutu, import stratejisine göre

Dördü de aynı grafiği çiziyor. Fark yalnızca hangi controller ve eklentinin pakete girdiğinde.

kB düşük olan iyi Kaynak: astro build çıktısı, dist/_astro/chart-render.*.js, gzip -9

Veri tablosu
astro build çıktısı, dist/_astro/chart-render.*.js, gzip -9
Seri chart.js/autobar+line+tooltip+fillerbar+line, eklentisizyalnız bar
gzip 67,8 kB58,1 kB51,2 kB46 kB

Grafik tarayıcıda çizilir; aşağıdaki tablo aynı veriyi taşır.

Ham (sıkıştırılmamış) boyutlarla birlikte tablo şöyle:

Strateji Ham gzip auto’ya göre
chart.js/auto 204.965 B 69.466 B —
bar + line + Tooltip + Filler bu sitede kullanılan 172.313 B 59.538 B −9.928 B (%14,3)
bar + line, eklentisiz 149.793 B 52.378 B −17.088 B (%24,6)
yalnız bar 134.868 B 47.114 B −22.352 B (%32,2)
Ham boyut ile gzip boyutu aynı yönde ama aynı oranda hareket etmiyor: sıkıştırma, silinen kodun bir kısmını zaten sıkıştırıyordu.

Sayı ne söylüyor

Seçmeli register, auto’ya göre 9,7 kB gzip kazandırdı. Bu, dokümantasyonun “tree-shaking destekleniyor” cümlesinin arkasındaki gerçek rakam — ve tek başına bakıldığında mütevazı: %14,3.

Asıl bilgi ikinci ve üçüncü satırda. Tooltip ile Filler eklentilerini düşürmek 7,0 kB daha götürüyor; çizgi grafiği hiç kullanmayan bir sayfa 5,1 kB daha kazanıyor. Yani maliyetin çoğu kütüphanenin çekirdeğinde değil, kullanılmayan çizim türlerinde. auto’nun yaptığı şey de tam olarak bu: hepsini kaydediyor.

Sayfanın tamamı ne ödüyor

Chart.js parçası tek başına anlamlı değil; ziyaretçi ada hidratlandığında şunları indiriyor:

Parça gzip Ne
chart-render 58,1 kB Chart.js + tema köprüsü
preact 4,9 kB çalışma zamanı çekirdeği
hooks 0,8 kB useRef / useEffect
client 0,8 kB @astrojs/preact istemci köprüsü
ChartIsland 0,6 kB bileşenin kendisi
Toplam 65,3 kB
Ölçüm, tek grafikli bir research sayfasının ada maliyetidir. `signals.module` parçası derlemede üretiliyor ama sayfa onu hiç istemiyor — @astrojs/preact yalnız `data-preact-signals` varsa yüklüyor.

Framework tarafı toplamın %10’undan azı (6,5 kB). Yani Preact yerine React seçmek burada asıl fark yaratmazdı demek yanlış olur — tam tersi: React’in react-dom maliyeti tek başına Chart.js’e yaklaşıyor. Ama bu ayrı bir ölçüm, ayrı bir kayıt.

Ne yaptım

chart-render.ts bu dört satırla açılıyor ve auto girişini hiç kullanmıyor:

import {
  BarController, BarElement, LineController, LineElement, PointElement,
  CategoryScale, LinearScale, Tooltip, Filler,
} from 'chart.js';

Chart.register(
  BarController, BarElement, LineController, LineElement, PointElement,
  CategoryScale, LinearScale, Tooltip, Filler,
);

Legend listede yok: gösterge sunucuda HTML olarak basılıyor. Böylece hem sitenin kendi token’larıyla biçimleniyor hem de JavaScript hiç çalışmasa bile yerinde duruyor — bu sayfadaki grafiğin altındaki “Veri tablosu” katlamasıyla aynı mantık.

İlgili yazılar

Diğer Kayıtlar

Tüm kayıtlar

64 goroutine, dört çekirdekte Mutex ile kanal aynı hızda, ama Mutex'in p99'u beş kat yüksek

Aynı paylaşılan sayaca G goroutine ve P çekirdekle saldırıldığında sync.Mutex, sahip-goroutine kanalı ve tamponlu kanal saniyede kaç işlem yapıyor, beklemenin kuyruk gecikmesi ve adilliği nasıl değişiyor?

Bulgu

64 goroutine ve dört çekirdekte sync.Mutex ile tek yönlü kanal aynı hızda (7,69 ve 7,94 milyon işlem/sn) ama Mutex'in p99 beklemesi 5 kat yüksek. Sekiz çekirdekte Mutex 2,4 ve 4,0 kat hızlı (15,96 milyon işlem/sn; kanallar 6,65 ve 3,97 milyon); oranlar bayraksız hücrelerden.

5 gün önce ölçüldü

Düşük güven

Bir çekirdek Go'da 14.330, PHP-FPM'de 5.152 OAuth2 isteği taşıyor

Her istekte RS256 bearer token doğrulayıp PostgreSQL'e bir satır yazan ya da okuyan aynı API, bir, iki ve dört çekirdekte Go, PHP-FPM ve FrankenPHP worker ile saniyede kaç karma istek taşıyor?

Bulgu

Dört çekirdekte Go 57.321, FrankenPHP 25.659, PHP-FPM 20.606 karma istek taşıdı; çekirdek başına 14.330, 6.415 ve 5.152. Kapasite planına giren sayı bu değil, istek başına uygulama CPU'su: Go 66,8, FrankenPHP 110,7, PHP-FPM 187,7 mikrosaniye. FrankenPHP doyduğunda dört çekirdeğin ancak 2,84'ünü kullanabiliyor — Go 3,83, PHP-FPM 3,87. Darboğaz veritabanı değil: aynı dört çekirdekte PostgreSQL tek başına saniyede 68.212 satır yazıyor, yani en hızlı adayın karma tavanının üstünde.

17 gün önce ölçüldü

Orta güven

Partial index on beş dakikada üç yüz beş kat şişti — ve autovacuum bir kez bile gelmedi

Sürekli churn altındaki bir kuyruk tablosunda partial index'in küçüklüğü kalıcı mı, ve varsayılan autovacuum ayarları ona yetişiyor mu?

Bulgu

Canlı küme yaklaşık 845. saniyeye kadar beş bin satırda sabit dururken partial index 0,125 MB'dan 38,2 MB'a çıktı — üç yüz beş kat. Küçüklüğü canlı satır sayısından geliyor, şişme hızı iş hacminden, ve ikisi arasında hiçbir bağ yok. Composite index oransal olarak daha az şişti (%42) ama mutlak olarak daha çok (+126 MB) ve şişerken çöktü — büyük olasılıkla belleğe sığmadığı için, ki bu ölçümde nedeni ölçülmedi: gecikmesi 0,52 ms'den 61 saniyeye çıktı, kuyruğu 126 bine tırmandı. On beş dakikada 1,75 milyon ölü satır birikti ve autovacuum **bir kez bile koşmadı** — varsayılan eşik tablonun tamamına göre ölçekleniyor (50 + 0,2 × 10 milyon ≈ 2 milyon), churn ise küçük canlı kümede oluyor.

43 gün önce ölçüldü

Yüksek güven

Sitede Ara

Yazı, proje ve sayfalarda arama yapmak için yazmaya başlayın.

Esc ile kapat Pagefind ile güçlendirildi