Teklif al
Performans & SEO

Astro ile hızlı web sitesi: kendi sitemizde neden kullandık

Hız tartışması tek bir soruya iner: çıktı, soran herkes için aynı mı? Aynıysa sayfa build'de yazılabilir; değilse cevabı istek anında biri üretir. Karar yüzey başına veriliyor, şirket başına değil.

Algoriel 10 dk okuma
Astro ile hızlı web sitesi: kendi sitemizde neden kullandık
Bu yazıda
  1. Astro’nun hızı nereden geliyor
  2. Bu siteyi Astro ile kurduk, müşteri sistemlerini kurmuyoruz
  3. Sayfa kim baktığını bilmek zorunda mı
  4. Sınır yüzey başına çizilir
  5. İçeriğin değişmesi sayfayı dinamik yapmaz
  6. Koşul bozulunca hız okuma yolundan gelir
  7. Kararı veren dört soru
  8. Astro’nun doğru cevap olduğu yer

Astro ile hızlı web sitesi önceden derlenmiş bir sitedir: sayfanın HTML’i istek gelmeden build sırasında yazılır ve her ziyaretçiye aynı dosya gider. Karar çerçeve adıyla değil yüzey başına verilir; aynı ürünün bir yarısı önceden yazılabilirken öbür yarısı istek anında üretilir. Vipkurum’da hangi kiracının içeriğinin döneceğini isteğin geldiği alan adı belirler; orada önceden yazılabilecek ekran yok.

Sitesini yenilemek isteyen herkese aynı tavsiye gidiyor: şu çerçeveye geç, hızlanırsın. Oysa çerçeve seçimi bu kararın son adımı. İlk adım çok daha dar bir soru: çıktı, soran herkes için aynı mı? Cevap evetse sayfa build sırasında yazılabilir ve ziyaretçi geldiğinde ortada üretilecek bir şey kalmaz. Cevap hayırsa derleyici sayfayı kimin açacağını bilemez, dolayısıyla cevabı istek anında birinin üretmesi gerekir.

Astro’nun hızı nereden geliyor

Astro bir bileşeni build sırasında sunucuda HTML’e derler ve orada bırakır. Çerçeve çalışma zamanı tarayıcıya varsayılan olarak hiç gitmez. Bir bileşenin tarayıcıda da çalışması isteniyorsa bu açık bir istemci yönergesiyle söylenir; tarayıcıda çalışacak bileşenler tek tek işaretlenir. Sonucu şudur: bir sayfanın taşıdığı JavaScript, o sayfadaki bileşen sayısıyla değil işaretlenmiş bileşen sayısıyla orantılıdır. Bu sitedeki sayfaların çoğunda işaretlenmiş tek bir bileşen yok.

İkinci karar çıktı biçiminde veriliyor. Bu sitenin yapılandırması çıktıyı statik olarak sabitler: her sayfa istek gelmeden, build anında diskteki bir HTML dosyasına yazılır. Ziyaretçi geldiğinde çalışan bir sunucu şablonu yoktur. Dosya zaten durur; sunucunun tek işi onu göndermektir. Alternatifi, sayfayı her istekte sunucuda üretmekti; o yol ancak sayfanın isteği tanıması gerekiyorsa bir işe yarar.

Üçüncüsü, çerçevenin nereye gireceğini biz söylüyoruz. Bu sitede Preact tek bir yola daraltılmış durumda: teklif formunun bulunduğu yol. Kod tabanındaki tek istemci yönergesi orada duruyor. Formun dışındaki hiçbir sayfa Preact paketi çekmiyor, çünkü formun dışında adım adım ilerleyen, girdiyi hatırlaması gereken başka bir yüzey yok.

Bu, sitenin JavaScript’siz olduğu anlamına gelmiyor. İlk boyamadan önce çalışıp tema tercihini uygulayan koruma, gezinme çekmecesi, mega menü, bölüm animasyonu ve çerez bandı elle yazılmış, sayfaya gömülü davranış parçaları. Her biri tek iş yapıyor; hiçbiri bir çerçeve çalışma zamanı ya da uygulama iskeleti taşımıyor.

Bu siteyi Astro ile kurduk, müşteri sistemlerini kurmuyoruz

Bu bloğun üzerinde durduğu site Astro, TypeScript ve Preact ile kurulu. Aynı üçlü hiçbir müşteri sistemimizde kullanılmadı; Astro’yu hizmet olarak da satmıyoruz.

Müşteri işlerinin altyapısı tek: Laravel, MySQL ve Redis; arayüzde Inertia ile Tailwind. Masadan çıkan her telefon uygulaması React Native (Expo) ile kuruluyor ve ofis paneliyle aynı Laravel uygulamasına bağlanıyor. Proje başına yeni yığın seçmiyoruz; yıllarca bakılabilecek tek yığın seçiyoruz. Uzman bir çalışma zamanı ancak problem zorladığında devreye giriyor: görüntü işleme için Python ve OpenCV gibi.

Ayrım, iki yüzeyin iki ayrı soruyu cevaplamasından çıkıyor. Vipkurum’da hangi kiracının içeriğinin döneceği isteğin geldiği alan adında belli oluyor; çıktı kiracıya göre değişiyor. AlgoKlima’da kayıt teknisyenin telefonunun yerel kuyruğuna yazılıyor; kaydın ne zaman ve kimden geldiği çalışma zamanında belirleniyor. Build zamanının bu iki soruya verebileceği bir cevap yok. Astro’yu oraya taşımak sorunun yerini değiştirmekten öte bir şey yapmaz.

Bu sitede aynı sorular hiç sorulmuyor. Hizmet sayfası kim açarsa açsın aynı, vaka çalışması aynı, bu yazı aynı. İki dil de adres önekiyle ayrılıyor ve iki dilin sayfaları da aynı biçimde önceden yazılıyor. Çıktı sabit olduğu için sayfa önceden yazılabiliyor. Aynı sitede oturum, sepet ya da kişisel bir kayıt olsaydı bu satırların hiçbiri geçerli olmazdı.

Sayfa kim baktığını bilmek zorunda mı

Önceden derlemenin tek koşulu var: çıktı, soran herkes için aynıdır. Koşul bozulduğu anda build’in elinden bir şey gelmez, çünkü derleyici sayfayı kimin açacağını bilemez. Aşağıdaki üç durum koşulu üç ayrı yerden bozuyor.

Birincisi çok kiracılılık. Vipkurum çatısındaki 7 kurum kendi alan adı ve markasıyla tek çekirdek üstünde çalışıyor; hangi ders programının, öğrenci kaydının ve ödeme satırının döneceğini isteğin kendisi belirliyor. Bir kurumun ekranını önceden yazmak, öbür kurumların kayıtlarını da aynı build’e koymak demek olurdu; kurumların bilgisini ayrı tutan sınır buna izin vermiyor.

İkincisi kaydın ilk nerede yazıldığı. AlgoKlima’nın saha uygulamasında teknisyen kazan dairesinde, kapsama dışında kayıt açıyor. Kayıt önce telefonun yerel kuyruğuna yazılıyor; bağlantı dönünce kuyruk oluşturulma sırasına göre boşalıyor ve sahadan gelen değişiklikle ofisten gelen değişiklik çakışma çözümüyle tek kayıtta birleşiyor. Sıra kuralının kendisi çalışma zamanına ait bir bilgi.

Üçüncüsü talebin tipi. Diotek’te keşif randevusu ile servis çağrısı aynı formdan geçmiyor. Keşif mekânı merkeze alıyor, servis kurulu cihazı; talep tipi akışı en baştan ayırıyor ve hangi akışın açılacağı ziyaretçinin ne istediğine bağlı. Formun kendisi tek bir HTML dosyası olabilir, ama arkasındaki dallanma isteği okumadan seçilemiyor.

Üç işte de çerçeve tartışması hiç açılmadı. Sorulan şey şuydu: istek anındaki cevabı kim üretecek. Bu soruya cevabı olan bir Laravel uygulaması hazırda varken ikinci bir çerçeve eklemek, hız kazandırmadan bakım yükü ekliyor.

Sınır yüzey başına çizilir

Karar tek tek yüzeylerde veriliyor ve iki cevap aynı ürünün içinde yan yana durabiliyor.

Çatalca Merkez Kasap’ta basılı menünün yerini QR ile açılan bir menü sayfası aldı. Sayfa masadaki herkese aynı görünüyor: fiyat listesi ziyaretçiye göre değişmiyor, arkasında sipariş, ödeme ya da stok katmanı yok. Menü bölümlere ayrılmış ve her bölümün kendi adresi var; farklı masa veya vitrin QR’ları aynı sayfanın farklı noktasına iniyor, bölümler arası geçiş yeni bir sayfa isteği açmıyor.

Şu an inşa ettiğimiz QRVizit aynı ürünün içinde iki cevabı birden taşıyor. Basılı QR kodun açtığı tanıtım sayfası, kodu okutan herkese aynı içeriği gösteriyor. Ama o içerik sahibinin panelinden değişiyor ve panel kimin giriş yaptığını bilmek zorunda. Ürünün bir yarısı önceden yazılabiliyor, öbür yarısı yazılamıyor; bu yüzden tek bir üründe iki render kararı yan yana duruyor.

Spektrumun öbür ucunda Vipkurum duruyor: dönen içerik hem isteğin geldiği alan adına hem de giren kişinin rolüne göre belirleniyor. Öğretmen, veli ve yönetici aynı kayda farklı yetkiyle bakıyor. Burada önceden yazılabilecek tek bir ekran bile yok.

YüzeyÇıktı kime göre değişirRender kararıKanıt
QR menü sayfası — bölümleri ayrı adreslenen tek sayfaKimseye göre değişmez; fiyat listesi masadaki herkese aynı, arkasında sipariş/ödeme/stok katmanı yokÖnceden hazırlanabilir: menü bir kez açılır, bölüm geçişi yeni sayfa isteği açmaz; fiyat değişimi baskı değil sayfa güncellemesiÇatalca Merkez Kasap
QR kartvizit — tanıtım sayfası + sahibinin paneli (şu an inşa ediliyor)Tanıtım sayfası kodu okutan herkese aynı; panel kimin giriş yaptığını bilmek zorundaAynı üründe iki cevap: sayfa istek anında ama Redis önbelleğinden sunuluyor, panel her koşulda istek anındaQRVizit
Çok kiracılı kurum paneli — ders programı, öğrenci, ödemeİsteğin geldiği alan adına ve giren kişinin rolüne göreYalnız istek anında: önceden yazmak bütün kiracıların bütün kayıtlarını önceden yazmak olurduVipkurum
Tahmin + arşiv + iklim özeti sayfalarıZiyaretçiye göre değişmez; takvimle değişirLaravel tarafında üretilir; her tarih–konum kırılımı kendi kalıcı adresinde yayınlanırGünlük Hava Durumu

Tablonun okunma biçimi şu: ikinci sütun cevabı verir, üçüncü sütun onun sonucudur. Şirket adı hiçbir satırda karara girmiyor; aynı müşterinin iki yüzeyi iki ayrı satırda durabilir.

İçeriğin değişmesi sayfayı dinamik yapmaz

Sık gelen bir itiraz var: içerik sürekli güncelleniyorsa sayfa statik kalamaz. Kalabilir. Belirleyici soru güncelleme sıklığı değil, çıktının kime göre değiştiği. Günde birkaç kez tazelenen bir sayfa herkese aynı görünüyorsa hâlâ yayındır; ayda bir değişen bir ekran kişiye özelse baştan durumdur.

Günlük Hava Durumu tek sitede üç ayrı değişme hızı taşıyor. 15 günlük tahmin sürekli tazelenip üzerine yazılıyor. Tarihi geçen gün, bir kez yazılan ve bir daha değişmeyen arşiv satırına dönüşüyor. İklim özeti ayrı bir kaynaktan gelmiyor; o arşivden hesaplanıyor ve arşiv büyüdükçe kendini yeniliyor. Üçü de takvimle değişiyor, hiçbiri kim baktığına göre değişmiyor.

Aynı sitede her tarih–konum kırılımı kendi kalıcı adresinde duruyor. Arşiv büyüdükçe site derinleşiyor ama sayfa yapısı yeniden kurgulanmıyor. Adres kalıcılığı, içerik tazeliğinden bağımsız bir karar: bir adres bir kez yayınlandıysa içeriği tazelenebilir, yeri değişemez. Bu ayrımı baştan yapmayan sitelerde arşiv büyüdükçe adresler kayıyor ve her kayma dışarıdan gelen bağlantıyı kırıyor.

Çatalca’da aynı ayrım daha küçük ölçekte görünüyor. Fiyat değiştiğinde sayfa güncelleniyor ve aynı QR kod, yeni baskı gerekmeden güncel menüyü açıyor. İçerik değişmiştir, ama çıktı masadaki herkese hâlâ aynıdır. Basılı menüde değişikliğin bedeli yeni bir baskıydı; burada bedel bir sayfa güncellemesi.

Bu kuralın işlemediği yer de belli. İçerik takvimle değil, ziyaretçinin kendi ürettiği kayıtla değişiyorsa ortada yayın değil durum vardır ve bölümün kuralı geçerliliğini yitirir. Kendi kaydını gören bir ekran, ne kadar seyrek güncellenirse güncellensin önceden yazılamaz.

Koşul bozulunca hız okuma yolundan gelir

Koşul bozulduğunda hızdan vazgeçilmiyor; hız başka bir yerden çıkarılıyor. İstek anında üretilen bir sayfada kazanç, render’ı öne çekmekten değil, tekrarlanan okumayı ucuzlatmaktan geliyor.

Devraldığımız SsangYong kurumsal sitesinde katalog okumaları Redis önbelleğinden karşılanıyor. Aynı sorgu her sayfa açılışında MySQL’e düşmüyor; veritabanı yalnızca veri değiştiğinde devreye giriyor. Sayfa hâlâ istek anında üretiliyor, ama üretimin pahalı kısmı her ziyaretçi için tekrarlanmıyor.

Aynı işte araç görselleri tek bir adlandırma ve klasör düzenine taşındı. Hangi modelin hangi dosyayı kullandığı artık kod okunmadan görülüyor. Dağınık duran görseller sayfa yükünün büyük bölümünü taşıyordu ve bu yük, çerçeveye hiç dokunulmadan hafifletildi.

Mevcut çatının dışına da çıkılmadı. Laravel, Tailwind ve jQuery seti korundu, çalışan bölümlere dokunulmadı; okuma yolu için bir önbellek katmanı devreye girdi, başka bir şey girmedi. Gerekçe şu: bakımı marka tarafı sürdürecekti ve çatıyı değiştiren bir bağımlılık, o haftaki işimizi kolaylaştırırken siteyi sahibinin elinden alırdı. Devralınan bir sistemde belirleyici soru, bizden sonra sistemi kimin sürdüreceğidir.

Aynı kurguyu kendi ürünümüzde de kuruyoruz. QRVizit’te ziyaretçinin gördüğü sayfanın içeriğini Redis’te önbelleğe alıyoruz; aynı kod tekrar tekrar okutulsa da her okutma MySQL’e inmiyor, kayıtlar MySQL’de duruyor. Koşul bozulan bir yüzey, sistem mimarisi çalışmasında masaya ilk koyduğumuz Laravel, MySQL ve Redis yığınına taşınıyor.

Kararı veren dört soru

Kendi yüzeyinizi yerleştirmek için dört soru yeter. Sıra da önemli: birincisi cevaplanmadan diğerleri anlamsız kalıyor.

Birincisi, çıktı kim baktığına göre değişiyor mu. Değişiyorsa yüzey önceden derlenemez ve tartışma burada biter. Vipkurum’da hangi kurumun içeriğinin döneceğini istek belirliyor; hiçbir çerçeve seçimi bu gerçeği değiştirmiyor.

İkincisi, içerik yayın takviminde mi yoksa veri akışında mı değişiyor. Bunlar ayrı sorular. Günlük Hava Durumu’nda tahmin takvimle tazeleniyor; AlgoKlima’da kayıt sahadaki teknisyenin hareketiyle oluşuyor. Birincisi önceden yazılabilir bir yayın, ikincisi baştan durum. Aynı sitede ikisi birden bulunabiliyor ve o zaman karar her ekran için ayrı veriliyor.

Üçüncüsü, bu yüzey kaç yıl yaşayacak. Bir sezon sürecek kampanya sayfasıyla yıllarca ayakta kalacak bir kurumsal vitrin aynı kararı hak etmiyor; ikinci durumda yığını ileride kim devralacaksa onun tanıyacağı bir yapı seçiyoruz.

Dördüncüsü, bakımı kim yaşayacak. Bakım maliyetini yalnız müşteriye anlatmıyoruz: 5 kendi ürünümüz var, 3’ünü şu an inşa ediyoruz ve yayında olanların bakımını kendimiz taşıyoruz. AlgoKlima bunlardan biri; çevrimdışı kuyruk gibi kuruluş kararlarının yıllar içinde ne getirdiğini kendi üzerimizde görüyoruz. Devraldığımız bir sistemdeyse cevabı bizim değil, sahibinin ekibi veriyor.

Dört sorunun cevabı bir arada okunuyor. Birinci soru yüzeyi ikiye ayırıyor; kalan üçü, ayrıldığı tarafta ne kadar dayanacağını söylüyor. Bir yüzey birinci soruda önceden derlenebilir tarafta kalıp üçüncü ve dördüncü soruda zorlanıyorsa render kararı doğrudur; eksik olan, o yüzeyi kimin sürdüreceğine dair plandır.

Astro’nun doğru cevap olduğu yer

Astro bu sitede doğru cevap ve gerekçesi koşulun sağlanması. Sitedeki hiçbir sayfanın çıktısı ziyaretçiye göre değişmiyor. Hizmet sayfaları, vaka çalışmaları ve bu yazı içerik yayınlıyor; hiçbiri durum taşımıyor. Aynı koşulun sağlandığı her yerde önceden derleme kazanıyor: kurumsal vitrin, dokümantasyon, kampanya sayfası, blog.

Koşul bozulduğunda yeni çerçeve aramıyoruz. Kim baktığını bilmesi gereken yüzey, müşteri sistemlerinin zaten üstünde çalıştığı yığına taşınıyor. Vipkurum’da kurumların bilgisini ayıran şey veri modelinin kendisi; o sınırı build zamanına taşımak mümkün olsaydı bile doğru olmazdı.

Bu yazının kendisi de kuralın örneği. Metin build sırasında HTML’e yazıldı; siz açtığınızda sunucuda çalışan bir şablon yoktu ve gördüğünüz dosya, başka herkese giden dosyayla aynı. Aynı kuralı bir kurum panelinde uygulamaya kalksaydık, iş ilk giriş ekranında dururdu.

İki yaklaşım arasında bir sıralama yok; soruyu yüzeyin kendisi soruyor. Tek bir çerçeveyi bütün yüzeylere uygulamak da ayakta duran bir sistemi hız gerekçesiyle yeniden yazmak da, soruyu duymadan verilmiş cevaptır.

Kural tek cümleye sığıyor: çıktı herkes için aynıysa sayfayı önceden yaz, değilse istek anında üret. Web yazılım işlerimizde bu ayrımı her projede baştan kuruyoruz ve ayrım, çerçeve adı geçmeden önce çizilmiş oluyor.

Temel çıkarımlar

  • Önceden derlemenin tek koşulu çıktının soran herkes için aynı olmasıdır; hız bu koşulun sonucudur, gerekçesi değil.
  • Astro, TypeScript ve Preact yalnız bu pazarlama sitesinin kendi yığınıdır; hiçbir müşteri sisteminde kullanılmadı.
  • Statik ile istek anında üretim kararı yüzey başına verilir: şu an inşa ettiğimiz QRVizit'te tanıtım sayfası önceden yazılabilirken panel kimin giriş yaptığını bilmek zorundadır.
  • İçeriğin sık güncellenmesi sayfayı dinamik yapmaz; belirleyici olan çıktının takvimle mi ziyaretçiyle mi değiştiğidir.
  • Koşul bozulduğunda yeni çerçeve aranmaz; yüzey Laravel, MySQL ve Redis yığınına taşınır ve hız orada tekrarlanan okumayı ucuzlatmaktan gelir.

Bu yazıda sık sorulanlar

  • Astro JavaScript göndermiyorsa bu sitedeki menü ve animasyonlar nasıl çalışıyor?

    Astro tarayıcıya çerçeve çalışma zamanını göndermez; bileşenler build sırasında HTML'e derlenir ve bir bileşenin tarayıcıda çalışması açık bir istemci yönergesi ister. Site yine de JavaScript'siz değildir: tema koruması, gezinme çekmecesi, mega menü, bölüm animasyonları ve çerez bandı elle yazılmış küçük davranış parçalarıyla çalışır. Algoriel'in kendi sitesinde tek istemci yönergesi teklif formunun bulunduğu yoldadır; Preact yalnız orada yüklenir.

  • Sayfanın çıktısı ziyaretçiye göre değişince neden önceden derlenemiyor?

    Önceden derleme, sayfayı istek gelmeden yazmak demektir; bunun tek koşulu çıktının soran herkes için aynı olmasıdır. Vipkurum'da hangi kiracının içeriğinin döneceği ancak isteğin geldiği alan adında belli olur; bu sayfaları önceden yazmak, bütün kiracıların bütün kayıtlarını önceden yazmak olurdu — kiracı izolasyonunun tam tersi. AlgoKlima'da kayıt teknisyenin telefonundaki yerel kuyruğa yazılır; build zamanının bu soruya verecek bir cevabı yoktur.

  • Aynı ürünün bir yarısı statik, öbür yarısı istek anında üretilebilir mi?

    Evet; karar şirkete ya da ürüne değil yüzeye verilir. Şu an inşa ettiğimiz QRVizit'te ikisi yan yana duruyor: tanıtım sayfası kodu okutan herkese aynı içeriği gösterdiği için önceden yazılabilir; yönetim paneli kimin giriş yaptığını bilmek zorunda olduğu için istek anında Laravel tarafında üretilir. Aynı ürünün iki yüzeyi iki ayrı render kararı taşır.

  • İçeriği sık güncellenen bir sayfa statik kalabilir mi?

    Kalabilir; içeriğin değişmesi sayfayı dinamik yapmaz, çünkü belirleyici soru güncelleme sıklığı değil çıktının kime göre değiştiğidir. Günlük Hava Durumu ziyaretçiye göre değil takvimle değişir: tahmin tazelenip üzerine yazılır, tarihi geçen gün bir daha değişmeyen arşiv satırına döner, iklim özeti de ayrı bir kaynaktan değil o arşivden hesaplanır. Her tarih–konum kırılımı kendi kalıcı adresini taşır; adres kalıcılığı içerik tazeliğinden bağımsız bir karardır.

  • Çerçeveyi değiştirmeden, devralınan bir sitede hız nereden kazanılır?

    Devralınan bir sitede hız çoğu zaman çerçeveden değil, okuma yolundan ve varlık düzeninden kazanılır. SsangYong kurumsal sitesinde katalog okumaları Redis önbelleğinden karşılanıyor; MySQL yalnız veri değiştiğinde devreye giriyor. Araç görselleri tek adlandırma ve klasör düzenine taşındı, çünkü sayfa yükünü taşıyan şey çoğu zaman çerçeve değil dağınık varlık düzenidir. Laravel, Tailwind ve jQuery setinin dışına çıkılmadı; bakımı marka tarafı sürdürecekti.

Yazar hakkında

Algoriel

Uzaktan çalışan web yazılım ajansı

İşletmelere özel web ve mobil yazılım geliştiriyoruz. Blogda, yazılım yaptırırken ve yayından sonra karşınıza çıkan soruları cevaplıyoruz.

Etiketler:
  • astro
  • performans
  • önceden derleme
  • statik site
  • web yazılım

İnşa edilecek bir sisteminiz mi var?

Kurmak istediğiniz bir sistem varsa teklif formundan anlatabilirsiniz.