Yazılara dön

Bu portföy nasıl çalışıyor

Build sırasında üretilen statik sayfalar, hak ettiği anda yüklenen adalar ve hareketi tercihe bırakan bir arayüz. Aldığım kararlar ve nedenleri.

viteperformanserişilebilirlik

Bu siteyi kurarken tek bir kural koydum: ziyaretçinin tarayıcısı, içeriği görmek için benim yazdığım JavaScript'e ihtiyaç duymasın. Geri kalan her karar bunun sonucu.

Çerçeve değil, ada

Sayfanın kendisi bir çerçeveyle kurulmadı. İçeriğin tamamı Vite ile derlenirken HTML olarak yazılıyor; tarayıcıda çalışan kod var olan DOM'u zenginleştiriyor, yeniden üretmiyor. Ağır kütüphaneler yalnızca hak ettikleri anda, ada olarak yükleniyor:

  • İlk yükte (~44 kB gzip) sayfanın kendi mantığı, yumuşak kaydırma ve beliriş animasyonları var.
  • Amblem önce düz 2D canvas'ta çiziliyor. WebGL sürümü (~152 kB gzip) ancak ziyaretçi azaltılmış hareket istemiyorsa ve veri tasarrufu kapalıysa, ilk boyamadan sonra geliyor.
  • Proje penceresi React ile yazıldı ve yalnızca bir projeye tıklandığında yükleniyor (~111 kB gzip).

Bu ayrımın bedelini kimin ödediği önemli. Eski bir telefondan, kötü bir bağlantıyla giren biri ilk 44 kB'ı alıp sayfanın tamamını okuyor. Geri kalanı, isteyen ve kaldırabilen cihaz için.

Sayfalar build sırasında yazılıyor

npm run build iki şey yapıyor. Önce Vite paketleri üretiyor, sonra kendi prerender adımım her sayfayı gerçek HTML olarak diske yazıyor:

bash
npm run build
# vite build  → dist/assets/*
# prerender   → index.html, en.html, yazilar.html, yazilar/*.html,
#               sitemap.xml, feed.xml, robots.txt, 404.html

Yani dist/ klasöründeki her adres, JavaScript hiç çalışmasa bile okunabilir metin döndürüyor. Tarayıcıda çalışan betik yalnızca hâlihazırda ekranda olanı zenginleştiriyor: mobil menü, kaydırma ile beliren bölümler ve dil değiştirme.

Statik üretimin en sevdiğim yan etkisi: kırılabilecek daha az şey var. Sunucu tarafında API yok, gizli anahtar yok, veritabanı yok.

Hareket bir tercih

Ana ekrandaki amblem — monogramımın ekstrüde edilmiş, turuncu krom hâli — önce düz bir 2D canvas üzerinde çiziliyor; WebGL sürümü sonradan, yalnızca izin verilirse geliyor. Üzerinden geçen tarama ışını, değdiği yüzeyi ısıtıyor ve altındaki tel yapıyı görünür kılıyor. WebGL bağlamı açılamazsa 2D sürüme geri dönülüyor — yani hiçbir cihazda boş bir kutu kalmıyor. Her iki sürüm de aynı üç kurala uyuyor:

  • Görünür alandan çıktığında çizmeyi bırakıyor
  • Sekme arka plana alındığında duruyor
  • prefers-reduced-motion: reduce ayarında hiç başlamıyor; WebGL yükseltmesi de yapılmıyor

Ayrıca köşesinde bir duraklat düğmesi var. Bir animasyonu durdurmak isteyen birinin sistem ayarlarına gitmek zorunda kalmaması gerektiğini düşünüyorum.

İki dil, iki gerçek adres

Türkçe ve İngilizce içerik ?lang= gibi bir parametreyle değil, ayrı adreslerle sunuluyor: / ve /en. Her sayfa kendi canonical adresini ve karşılıklı hreflang bağlantılarını taşıyor. Dil değiştirme bağlantıları JavaScript kapalıyken de çalışıyor, çünkü altlarında gerçek bağlantılar var.

Bu bölüm

Yazılar da aynı boru hattından geçiyor. content/writing/ altındaki Markdown dosyaları derleme sırasında okunuyor, HTML'e çevriliyor ve statik sayfa olarak yazılıyor. Markdown çevirici projenin kendi içinde; kod blokları dâhil her karakter, herhangi bir etiket üretilmeden önce kaçırılıyor.

Buraya yazacaklarım çoğunlukla üzerinde çalıştığım şeylerin notları olacak: zafiyet analizleri, araç geliştirirken karşılaştığım problemler ve laboratuvar çalışmalarından çıkan gözlemler.