Info World: Modern web teknolojisindeki yedi vahim başarısızlık
Web SQL, Angular 2, Facebook’un Flow’u, Google AMP, çalışma zamanında (runtime) çalışan CSS-in-JavaScript, mikro ön yüzler (micro front ends) ve yalnızca istemci tarafında çalışan tek sayfalık uygulamalar (SPA’lar); hepsi iyi fikirlerdi ancak ölümcül kusurlar barındırıyorlardı. Bu hatalardan ders çıkarabiliriz.
Modern web bir mühendislik harikasıdır; ancak tarihi, uygulama aşamasında sönüp giden parlak fikirlerle doludur. Başarıyla hayata geçen her yeniliğin karşısında, büyük umutlarla başlayıp hüsranla sonuçlanan bir başka teknoloji bulunur. Bu başarısızlıkların her biri, yazılım geliştiricileri olarak bizler için önemli birer ders niteliğindedir.
Görsel: Andrey_Popov / Shutterstock
Yeni teknolojilere karşı adeta karşı konulamaz bir tutkumuz var. Ufukta beliren ışıltılı, yeni framework’lere bakmaya bayılıyoruz; oysa gerçek mimari bilgelik, geride kalan enkazı incelemekten gelir. Felaketle sonuçlanan sürüm geçişlerinden, HTML’in şirketler tarafından adeta ele geçirilmesine; web fiziği gerçeklerinin ve ön yüzün fiziksel sınırlamalarının göz ardı edilmesine kadar, öğrenebileceğimiz pek çok enkaz mevcut.
İşte modern web tarihindeki en vahim uygulama başarısızlıklarından yedisi ve iyi fikirlerimizin aynı kaderi paylaşmaması için öğrenmemiz gereken mimari dersler.
Web SQL: Tek bir tedarikçiye bağımlı, çıkmaz bir yol
İyi Fikir: Güçlü, ilişkisel bir veritabanını doğrudan tarayıcının içine getirmek. Hızlı tepki veren, çevrimdışı çalışma öncelikli (offline-first) web uygulamaları oluşturmak ve tüm verileri, ana veri kaynağı (back-end) ile senkronize etmek.
Ölümcül Kusur: Standart belirleme sürecindeki siyasi çekişmeler. Apple, Web SQL’i destekliyordu ancak bu teknoloji aslında sadece SQLite’ın ham bir sarmalayıcısından (wrapper) ibaretti. Google, Web SQL’i Chrome’a entegre etti; ancak Mozilla ve Microsoft buna karşı çıktı. Çünkü bu teknolojiyi standartlaştırmak, tüm web spesifikasyonunu tek bir C kütüphanesine bağımlı kılmak anlamına geliyordu. Sonuç olarak, Web SQL kullanımdan kaldırıldı.
Ders: Standartlar fikir birliği gerektirir. Web altyapısını tek bir uygulamaya (implementation) bağlamak, o teknolojinin aniden kullanımdan kaldırılmasına davetiye çıkarmaktır. Geliştiriciler Web SQL’i kaybedip hantal IndexedDB ile uğraşmak zorunda kalsalar da, alan nihayet Wasm tabanlı PGLite ve PowerSync gibi daha yeni, yerel çalışma öncelikli (local-first) çözümlerle çok daha verimli bir noktaya evrildi.
Angular 2: Gemileri yakmak
İyi Fikir: Angular’ın başarısının üzerine inşa ederek, tamamen yeniden yazılmış, çok daha iyi bir sürüm ortaya koymak. Hernán Cortéz’in gemilerini yakması, tarihe geçen parlak bir stratejiydi. Peki, yaygın kullanılan bir web çatısı (framework) için aynı şey söylenebilir mi? Pek sayılmaz.
Angular.js, tek sayfalık uygulamaların (SPA) tartışmasız kralıydı; ancak performans darboğazları yaşıyordu. Bir bakıma, çok iyi işleyen ama yamalı bohça misali, zorlama bir yapı gibiydi. Google; sürdürülebilir, kurumsal kullanıma uygun ve yüksek performanslı, bileşen tabanlı bir mimari getirmek istiyordu. Ancak bunu başarabilmek için mevcut yapıyı temelinden söküp atmaları gerekiyordu.
Ölümcül Hata: Yanlış geçiş stratejisi. Google, geriye dönük uyumluluğu tamamen ortadan kaldıran, her şeyi kökten değiştiren bir yeniden yazım süreci duyurdu. Bu durum, büyük ölçekli kurumsal kod tabanları için hiçbir net geçiş yolu bırakmadı.
Bu da kapıyı yeni bir çatının girmesi için ardına kadar açtı. React bu kapıdan içeri girdi ve bir daha da hiç çıkmadı.
Ders: Geçiş sürecini (migration path) asla koparmayın. Zorlu bir geçiş yolu bile olsa, bu, mevcut kullanıcılarınıza değer verdiğinizi ve onların varlığını önemsediğinizi gösterir.
Facebook’un Flow’u: Sera domatesi
İyi Fikir: JavaScript’in, kurumsal ihtiyaçları karşılayabilmesi için tip güvenliğine (type safety) ihtiyacı vardı. Flow, çok az manuel ek açıklama (annotation) ile devasa kod tabanlarını teorik olarak koruyabilecek, ayrıntılı bir tip çıkarımı (type inference) sistemi sunuyordu.
Ne yazık ki bu proje, bir "sera domatesi" gibiydi; Facebook’un kontrollü kurumsal ortamında tasarlanıp geliştirilmişti.
Ölümcül Hata: Flow, Facebook’un kendi iç ortamı için inşa edilmişti. Meta dışındaki dünyada ise Flow; hatalarla dolu olması, ağır bir arka plan sunucusu gerektirmesi, Windows üzerinde çökmesi ve geniş açık kaynak ekosistemini göz ardı etmesiyle nam saldı. Microsoft ise TypeScript ile bu boşluğu ustalıkla doldurdu.
Ders: Açık bir ekosistem ve kusursuz bir geliştirici deneyimi; "ilk olma avantajı" veya "salt teknik üstünlük" gibi faktörlerden her zaman daha değerlidir. Dev bir şirket olsanız dahi, projenizi geniş ve aktif bir kullanıcı kitlesiyle bağlantılı tutun.
Google AMP: Kurumsal bir güç gösterisi
İyi Fikir: Mobil kullanım yaygınlaştıkça, web dünyası taşınabilir cihazlarda düzgün bir kullanıcı deneyimi sunmakta zorlandı. Önceki 15 yıl boyunca geliştirdiğimiz yerleşik yöntemler yetersiz kaldı; sonuçta ağır paketler ve optimize edilmemiş öğelerle dolu, yavaş ve hantal mobil web siteleri ortaya çıktı.
Google AMP (Accelerated Mobile Pages - Hızlandırılmış Mobil Sayfalar), mobil cihazlara sunulan HTML, JavaScript ve görselleri sadeleştiren standart bir yaklaşım olmayı ve evrensel bir CDN (içerik dağıtım ağı) önbelleği kullanmayı hedefliyordu. Google, tüm bunları hayata geçirebilecek güce sahipti.
Temel Kusur: Google, AMP'yi başarılı kılmak için zorlamaya başvurdu. Üstelik teknolojinin kendisi de fazlasıyla katıydı. Google, yayıncıları, arama sıralamalarıyla tehdit ederek, HTML'in kendine has, oldukça kısıtlanmış bir alt kümesini kullanmaya zorladı. Bu, rekabeti engelleyen ve yeniliğin önünü tıkayan bir kabustu.
Ders: Açık web standartları kazanır. "Performans optimizasyonu" kılıfı altında sunulan, kullanıcıyı belirli bir tedarikçiye bağımlı kılan (vendor lock-in) yaklaşımlar, er ya da geç topluluk tarafından fark edilecek, etrafından dolaşılacak ve reddedilecektir.
Küresel ölçekte dev bir şirkette çalışmıyor olabilirsiniz; ancak benzer durumlar küçük ve orta ölçekli işletmelerde de yaşanabilir. Bir kurum, yazılım geliştiricilere katı standartlar dayatmaya kalktığında; bu durum sürtüşmeye, hoşnutsuzluğa ve başkaldırıya yol açabilir. Yazılım dünyasında yukarıdan aşağıya dayatılan kararlar nadiren sorunsuz işler.
Runtime CSS-in-JS: Performans yanılgısı
İyi Fikir: Büyük ölçekli projelerde CSS yönetimi oldukça zordur. Küresel isim alanı çakışmaları (global namespace collisions) ve CSS seçici öncelik (specificity) savaşları, on yıllardır devasa kod tabanlarının baş belası olmuştur. Stil tanımlarını doğrudan JavaScript bileşenlerinin içine yerleştirmek (colocation), adeta bir aydınlanma anı gibiydi. Bu yaklaşım mantığı kapsülledi, kullanılmayan kodları (dead code) ortadan kaldırdı ve dağınık ekiplerin stilleri yönetmesini son derece sezgisel hale getirdi.
Temel Kusur: Temel platformun doğasını göz ardı ettik. Geliştiricilere sunduğu o harika deneyim uğruna, temelden hatalı bir çalışma zamanı (runtime) uygulamasını kabul ettik. Beş yıl boyunca tarayıcıları, sırf render döngüsü sırasında stilleri anlık olarak hesaplayıp sayfaya enjekte edebilmek için devasa JavaScript paketlerini indirmeye zorladık. Tarayıcının zaten yerel olarak ve ışık hızında yaptığı bir işi —stil sayfalarının ayrıştırılması— alıp, bunu tek iş parçacıklı (single-threaded) JavaScript motoruna yaptırdık. Bu durum, ilk yükleme sürelerini ciddi şekilde kötüleştirdi ve mobil cihazların işlemci (CPU) performansını tüketti.
Ders: Kullanıcı performansını asla geliştirici deneyimi uğruna feda etmeyin. Mimari soyutlamalar tarayıcının yerel yetenekleriyle çeliştiğinde, bunun bedelini her zaman son kullanıcı öder. Nihayetinde gururumuzu bir kenara bırakıp şunu hatırlamamız gerekti: Tarayıcılar, yerel CSS'i ayrıştırmak üzere son derece optimize edilmiş durum makineleridir. Bu acı tecrübe; sektörü yeniden CSS Modüllerine, modern yerel CSS özelliklerine ve Tailwind gibi çalışma zamanında (runtime) ek yük oluşturmayan derleyicilere yöneltti.
Mikro Ön Uçlar: Doğru Mimari, Yanlış Yer
İyi Fikir: Mikroservis tarzı ayrıştırmayı ön uca uygulayarak, büyük kuruluşların farklı UI özelliklerinin geliştirilmesini farklı ekiplere yayarak çevikliği artırmalarını sağlamak.
Tek parça halindeki UI'yi bağımsız olarak geliştirilebilen, test edilebilen ve dağıtılabilen ayrı, daha küçük bileşenlere bölmek, sunucu tarafında mikroservislerin sağladığı aynı faydaları vaat ediyordu: özerk ekipler, daha küçük kod tabanları, daha kolay bakım, artımlı güncellemeler. Hepimiz daha özgürce çalışabilir ve daha hızlı hareket edebilirdik. Peki ya zavallı son kullanıcı?
Ölümcül Hata: Dağıtılmış bir arka uç modelini zorla tarayıcıya uyguladık. Gerçekten mantıklı değildi. Mikro ön uçlar organizasyonel bir sorunu çözdü, ancak son kullanıcının cihazında karmaşıklık, büyük bir ek yük ve performans sorunları yarattı. Tutarlı bir uygulama yerine, ekipler aynı sayfaya birden fazla JavaScript paketi, yinelenen bağımlılıklar ve bazen tamamen rekabet eden UI çerçeveleri göndermek zorunda kaldılar. Tarayıcı, dağıtılmış sistemlerin hakemi gibi davranmaya zorlandı; bu da parçalanmış durumlara, performans düşüşüne ve meta-karmaşıklığa yol açtı.
Ders: Conway Yasası, istemci tarafı paketinizin yapısını belirlememeli. Dağıtılmış bir mimari arka uç ölçeklendirme darboğazlarını çözüyor diye, istemci tarafında da olması gerektiği anlamına gelmez. Kurumsal organizasyon şemasındaki bir sorunu çözmek için son kullanıcı deneyimini asla bozmamalısınız. Karmaşıklık getiren bir çözümle flört ediyorsanız, sağduyuya başvurun.
Mikro ön uçlar yerine, gerçekten ihtiyacımız olan şey ECMAScript Modülleri ve modern, derleme gerektirmeyen altyapıydı.
Sadece istemci tarafında çalışan SPA'lar: Dağıtılmış hesaplama yine iş başında
İyi Fikir: Tarayıcıyı, kalın istemci, yerel benzeri bir deneyim sunmak için bir platform olarak kullanın. Durumu yerel olarak, reaktif bir şekilde yönetin.
Ölümcül Hata: Durumu her çoğalttığınızda, dağıtılmış hesaplamanın sorunlarını ortaya çıkarırsınız. Bu, web'de kaçınılmazdır. İstemci, kullanıcının işine yarayacak duruma ihtiyaç duyar. Genel olarak anlaşıldığı üzere tek sayfa uygulamalarında, kullanıcının durumunu işleyen ve bunu JSON aracılığıyla arka uçla senkronize eden bir JavaScript motoru bulunur.
Mimari katmanlardan biri bütünüyle, istemciler ile veri deposu arasındaki JSON mesajlarının dönüştürülmesine ayrılmış durumda. İş mantığının büyük bir kısmı ise istemci tarafında yoğunlaşıyor. İstemci "akıllı", sunucu ise "aptal" konumda.
Ders: Sunucunun var olmasının bir nedeni var. Sektör, son beş yılını devasa meta-çerçeveler (meta-frameworks) inşa ederek geçirdi; oysa geldiğimiz noktada, Next.js ve benzeri tam kapsamlı (full-stack) çerçeveler aracılığıyla yeniden sunucu taraflı işlemeye (server-side rendering) geri dönüyoruz.
Uyarıcı hikâyeler
İnsanı gafil avlayan şey, gelmekte olduğunu gördüğü değil, hiç aklına getirmediği şeydir. Bizi karanlık noktalara sürükleyen genellikle aşırı öz güven ya da dizginlenemez bir hevestir. İleri düzey teknik bilgi ve büyük bir gayret, kusurlu koşullarla birleşebilir. Yazılım projelerinin rayından çıkmasını engellemenin tek yolu, sürekli tetikte olmaktır. Uygulama süreçlerinin, planda öngörüldüğü gibi mi yoksa gerçekte nasıl ilerlediğini sürekli kontrol etmek gerekir.
Bu listede yer alan teknoloji devleri bile böylesine talihsiz sonuçlarla karşılaşıp geride kalabiliyorsa, aynı durumun bizim de başımıza gelebileceğini kabul etmeliyiz. Bu kabullenişin kendisi, sahip olunabilecek en iyi sigorta poliçesidir.
Kaynak: Seven egregious failures of modern web tech - Matthew Tyson / Info World
.