Blazor + WebAssembly

Blazor + WebAssembly

Merhabalar, bu yazıda Blazor hakkında konuşacağız. Blazor Server ve Blazor Web Assembly’nin ne olduklarını, nasıl çalıştıklarını ve bizlere neler kazandırdıklarını inceleyeceğiz.

Öncelikle Blazor, Microsoft tarafından geliştirilen .NET kullanarak bir SPA(Single Page Application) oluşturmamıza olanak sağlayan framework’tür diyebiliriz. Blazor’ın detaylarına girmeden önce SPA kavramının ne olduğunu ele alalım.

Geleneksek web uygulamalarının nasıl çalıştığını hatırlayalım. Geleneksel web uygulamaları yani MPA(Multi Page Application) diye adlandırılan uygulamalarda, kullanıcı bir web sayfasını görüntülemek istediğinde, bir sayfadan başka bir sayfaya geçtiğinde sürekli sunucu ile doğrudan etkileşim halindedir. Kullanıcı bir sayfaya ulaşmak ister daha sonra kullanıcının bu isteği sunucuya ulaşır, sunucuda geriye ilgili sayfayı render edip gönderir. Render etmekten kasıt sunucunun bir sayfanın HTML ve CSS çıktısını istemciye göndermesidir. Burada yük sunucudadır. ASP.NET’de geliştirdiğimiz Web Forms ve MVC gibi uygulamalar bu mantıkta çalışmaktadırlar. Her yeni istekte tüm sayfa yeniden yüklendiği için sunucuya ekstra yük binmiş olur aynı zamanda bu tekrar tekrar sayfayı render etme işlemi gecikmeye sebep olmaktadır. İşte başta bu nedenler olmak üzere geleneksel uygulamalarda yaşanan bazı olumsuzluklar SPA’ların doğuşunun asıl sebebi olmuştur.

SPA’lar routing(yönlendirme) işleminin MPA’larda olduğu gibi sunucuda değilde client-side da yani istemcide yapıldığı web uygulamalarıdır. Kullanıcı her yeni sayfaya ulaşmak istediğinde sayfa url’i değişir ama sayfa yenilenmez. Tek bir sayfa üzerinde sadece ilgili alan güncellenir. Tüm yapı değil sadece değişmesi gereken alan değişir. Bu sayede sürekli sunucuya gitme zahmetinden kurtulmuş oluruz. Sürekli sunucuya gitmediğimiz için hız konusunda önemli kazanımlar elde ederiz. Hızın artması kullanıcı deneyiminide doğrudan arttırmaktadır. Bu gibi artılar bizleri SPA kullanımına itmiştir. Bu doğrultuda javascript ve typescript tabanlı başta Angular, React ve Vue js olmak üzere bazı frameworkler ve kütüphanelerden yararlanmaktayız. İşte Microsoft’ta bizlere javascript ve typescript kullanmadan doğrudan C# kullanarak bir SPA geliştirmemizi sağlayacak Blazor’ı ortaya çıkarmıştır.

Blazor ile .NET de C# ve Razor kullanarak interaktif SPA’lar geliştirebileceğiz. Bu sayede .NET için geliştirilmiş kütüphaneleri Blazor ile istemci tarafında kullanabileceğiz. Sadece C# yazarak hiçbir eklenti veya tool kurmadan tüm modern tarayıcılarda projemizi çalıştırabileceğiz. Blazor’ın ismi de bu amaç doğrultusunda oluşmuştur diyebiliriz. Browser+Razor kelimelerinin birleşimi ve birazda değişimi sonucu Blazor ismi ortaya çıkmıştır.

Blazor kullanarak iki tip uygulama geliştirebileceğiz. Bunlar Blazor Server ve Blazor Web Assembly. Bu iki çeşit uygulama da Single Page Application geliştirmemize olanak sağlamaktadır. Aralarındaki fark ise Blazor Server’ın server side rendering ile Blazor Web Assembly’nin ise client side rendering ile çalışmasıdır.

Blazor Server

Blazor’ın bu versiyonunda yazdığımız tüm kodlar sunucuda işlenmektedir. İşlenen bu kodlar tarayıcıya iletilmektedir. Blazor Server, Blazor’ın sunucuda host edilen türüdür. Sunucu ile istemci arasındaki bağlantı ise SignalR ile sağlanmaktadır.

SignalR gerçek zamanlı uygulamalar geliştirmek için oluşturulmuş .NET de kullandığımız bir kütüphanedir. SignalR, sunucu ile istemci arasında dinamik olarak oluşturulan bir bağlantı kurarak veri akışını bu bağlantı üzerinden sağlar. Böylece istemci tarafında yapılan değişiklik anında sunucuya ulaşır aynı şekilde sunucu tarafındaki değişikliklerde tarayıcıya gösterilebilir. Bir gerçek zamanlı chat uygulaması SignalR kullanımına örnektir. Sayfa yenilemeden mesaj alıp gönderebilmek SignalR kullanımıyla mümkün olmaktadır. SignalR bu işlemleri gerçekleştirirken websocket protokolünü kullanır. Websocket istemci ile sunucu arasında gerçek zamanlı iletişim sağlamak için tasarlanmıştır. Websocket aktif bir TCP bağlantısı ile çift yönlü iletişim sağlayabilen bir protokoldür.

İşte Blazor Server da sunucu ile istemci arasındaki veri akışı SignalR’ın bu şekilde kullanımı ile sağlanır. UI güncellemeleri, event handling, ve JavaScript çağrıları SignalR üzerinde gerçekleşir.

Blazor Server

Yukarıdaki görsel Blazor Server’ın çalışma mantığını özetlemektedir.

Blazor Server’ın aksine uygulamamızın kodlarının tarayıcıya indirilip işlemlerin sunucuda değilde istemcide gerçekleştirildiği Blazor’ın bir diğer hosting modeli ise Blazor WebAssembly’dir. Blazor WebAssembly’nin ne olduğuna geçmeden önce WebAssembly’nin ne olduğuna bakalım.

WebAssembly

WebAssembly kısaca WASM, 2015 yılında teknoloji devleri Google, Microsoft, Mozilla ve Apple firmalarının bir araya gelerek başlattıkları bir projedir. WASM, web uygulamaları için native yapıya yakın performans vaat eden bir binary formattır. WASM bizlere tarayıcılarda C, C++ ve Rust gibi dillerde yazmış olduğumuz kodları çalıştırabilme imkanı sunmaktadır. Görüntü işleme, video ve müzik düzenleme gibi yüksek performansa ihtiyaç duyulan durumlarda WASM gereklilik haline gelmiştir.

WASM binary bir yapıya sahip olduğu için boyut olarak daha küçüktür. Binary formata sahip olduğu yani derlenmiş bir halde olduğu için çalıştırılmaya hazırdır yani optimize edilmesine gerek yoktur. Bu yüzden Javascripte göre kodun işlenmesi çok daha hızlı gerçekleşmektedir. Günümüzde tüm modern tarayıcılar WASM’ı desteklemektedir. Eğer yüksek performansa ihtiyaç duyduğumuz bir durum varsa WASM bu noktada bizlere yardımcı olmaktadır. Bize yüksek performansta çalışma sağlayan bir dilde kodu yazarız daha sonra bu kodu tarayıcıda çalıştırmak istediğimizde WASM binary formatına çeviririz ve bunu tarayıcıda çalıştırırız. Böylece javascript kullanmadan dilediğimiz dilde yazdığımız kodu tarayıcıda çalıştırabilme fırsatı yakalamış oluruz.

WASM bir derleme hedefidir. Yani doğrudan WASM kodu yazmayız. İhtiyaç doğrultusanda yüksek seviye bir dil kullanarak kodu yazarız. Bu yazdığımız kod WASM binary koduna derlenir. Derlenmiş bu binary data tarayıcıda çalıştırabilir.

WebAssembly

Yukarıdaki görselde görebileceğiniz gibi bir C kodunu tarayıcıda çalıştırmak istediğimizi düşünelim. WASM dan önce bu işlem mümkün değilde çünkü tarayıcılar sadece javascriptten anlıyorlardı. WASM bize bunu mümkün kıldı. C ile yazdığımız kodu WASM binary koduna çevirmek için Emscripten kullanabiliriz. Emscripten C kodunu WASM binary koduna dönüştürmemizi sağlamaktadır. C ile yazdığımız hello.c isimli dosyamız Emscriptin ile derlendikten sonra hello.wasm haline dönüşmektedir. Artık C ile yazdığımız kod tarayıcıda çalışabilir hale gelmiştir. Görselde de görüldüğü gibi dikkat ederseniz eğer WASM kodunu javascript ile kullanmaktayız. Javascript kullanarak WASM kodunu sisteme dahil etmekteyiz.

WebAssembly.instantiateStreaming(fetch("hello.wasm"), importObject).then(
(results) => {
// Do something with the results!
}
);

Yukarıdaki kod parçacığı hello.wasm isimli dosyamızı sisteme javascript kullanarak nasıl dahil edeceğimizi göstermektedir.

WASM kodunun ne olduğunun tam olarak daha net anlaşılabilmesi için aşağıdaki görseli bırakıyorum.

WAT ve WASM

Yukarıdaki görsel de bir faktoriyel hesabı yapan C kodunun binary hali yani WASM formatı gösterilmiştir. Bu binary hali görebileceğiniz gibi anlaşılmadığı için WASM binary formatının bir de text hali bulunmaktadır. Bu text format ise WAT(WebAssembly Text format) olarak geçmektedir. Bir C kodunun hem WAT hem de WASM olarak neyi ifade ettiğini anlamamızda yukarıdaki görsel fayda sağlamaktadır. Bu görsel ile aslında ne kadar yazması pek kolay gözükmesede WAT formatı ile de kod yazıp bu kodu WASM binary koduna çevirebilmekteyiz.

WASM’ın ne olduğunu bizlere sağladığı avantajları ve nasıl bir formatta olduğunu gördük. WASM’ın güzelliklerini anlamış olabiliriz ama başka bir dilde yazdığımız kodu WASM formatına dönüştürme ve bunu tarayıcıda çalıştırma işi biraz meşakatli gelmiş olabilir.

İşte Blazor WebAssembly bizi bu zahmetten kurtarıyor. Biz sadece C# kodu yazıyoruz. Derleme işlemini, tarayıcıda çalıştırma işlemini her şeyi Blazor WASM uygulaması bizim yerimize gerçekleştiriyor. Arka planda yapılan işlemleri düşünmeden bizim yaptığımız tek şey C# kodu yazmak.

Haydi şimdi de Blazor WebAssemblyi biraz daha yakından tanıyalım.

Blazor WebAssembly

Blazor WASM C# kodu kullanarak tarayıcıda çalışan uygulamalar oluşturmamızı sağlayan bir platformdur. Blazor WASM ile yazdığımız kodlar tarayıcıya indirilir ve burada çalışır. Projenin ihtiyaç duyduğu tüm dll’lerde buraya dahildir.

Yazdığımız .NET kodunun tarayıcıda çalışabilmesini mümkün kılan ise biraz önce bahsettiğimiz WebAssembly’dir. Blazor, WebAssembly kullanarak C# kodunu doğrudan tarayıcıda çalıştırabilir. Tüm dosyalar tarayıcıya indirildiği için uygulamanın ilk açılışı biraz gecikmeye sebep olabilir ama artık her şey tarayıcıda olduğundan sunucuya gitme maliyetinden kurtulduğumuz için sonraki işlemlerde hız konusunda önemli avantajlar yakalamış oluruz.

Blazor WebAssembly

Yukarıdaki görsel ile Blazor WebAssembly de tüm işlemlerin tarayıcıda nasıl gerçekleştiğini görmekteyiz.

Peki yazdığımız kodlar nasıl WebAssembly koduna derleniyor? Önceki satırlarda WebAssembly’den bahsederken örnek olarak bir C kodundan gitmiştik ve bir C kodunu WebAssembly koduna çevirmek için Emscriptten kullanabileceğimizi söylemiştik. Blazor da bu işlemi .NET bizim yerimize gerçekleştirmektedir.

Peki yazdığımız kodlar nasıl WebAssembly koduna çevrilmektedir?

Blazor WebAssembly uygulamaları, WebAssembly uygulayan bir .NET Intermediate Language (IL) yorumlayıcısı kullanılarak tarayıcıda çalışır. Bu işlem gerçekleştirilirken mono derleyicisinden faydalanılır, .NET kodu yorumlanan bir kod olduğu için, uygulamalar genellikle sunucu tarafına göre daha yavaş çalışır. İşte buradaki performans sorununu önüne geçmek için WASM koduna dönüştürme işleminde AOT derlemesi kullanılır.

  • AOT (Ahead-of-Time) derleme, bir programın derlenmesi sırasında tüm kodun derlenerek çalışır hale getirilmesidir.​ AOT derleme programın runtime da derlenmesini önler. Bu sayede programın çalışması daha hızlı olur. AOT derlemesi runtime da .NET assemblylerini WebAssembly binary formatına dönüştürür yani yorumlama yapmaz. AOT yazdığımız kodları doğrudan tarayıcı tarafından yürütülebilen WebAssembly’de derlediği için performans sorununu giderir.

Blazor WebAssembly de AOT derlemesi kullanma işlemi ilk başlarda mevcut değildi .NET 6 ile birlikte bu özelllik kullanıma sunuldu. Yapılacak tek şey ise aşağıdaki kod bloğunu proje dosyasına eklemek.

<PropertyGroup>
<RunAOTCompilation>true</RunAOTCompilation>
</PropertyGroup>

Yukarıdaki kod bloğunu proje dosyasına eklediğimizde artık Blazor projemiz AOT derlemesi kullanacak ve .NET kodunu doğrudan WebAssemblye derleyerek performans sorununun önüne geçecektir.

Blazor WebAssembly uygulaması bizlere PWA(Progressive Web Apps) geliştirme imkanıda sunmaktadır. Visual Studio üzerinden bir Blazor WebAssembly uygulaması oluştururken Visual Studio bizlere aşağıda gibi bir seçenek sunar.

PWA

Bu seçeneği seçtiğimizde Blazor WebAssembly projemize Progressive Web Application desteği eklemiş oluruz.

Progressive Web App (PWA), web uygulamalarına mobil uygulamalardaki kullanıcı deneyimini kazandırmayı amaçlayan modern tarayıcılar tarafından desteklenen bir web uygulamasıdır.

Blazor WebAssembly uygulamasını oluştururken PWA seçeneğini seçtiğimizde projemizde bazı yeni dosyalar eklenir. Bunlardan biri manifest.json dosyasıdır.

Manifest dosyası tarayıcılara web uygulaması hakkında bilgi veren bir json dosyasıdır. PWA ile uygulama geliştirip mobil tarayıcıda uygulamayı ziyaret ettiğimizde bize uygulamayı ana ekrana kısayol eklemek ister misiniz gibi bir soru sormaktadır. Evet dediğimizde mobil de ana ekrana web uygulamasının bir kısayolu eklenir. Bu kısayolun ismi, ikonu vb. bilgileri işte bu manifest dosyasında yer alır. Dahası da var. Ana ekrana eklediğimiz ikona tıkladığımızda tarayıcıda açılan uygulama belirttiğimiz yazı ile, belirttiğimiz arka plan ile tıpkı mobil uygulamalarda olduğu gibi başlayabilir. Tanım, renk, başlık vb. pek çok özelliği işte bu manifest dosyasında tanımlayabilmekteyiz. Böylece kullanıcı hiçbir şekilde bir mobil marketten uygulama indirmeden bir web uygulamasını tıpkı bir mobil uygulamaymış gibi tecrübe edebilir. Mobil uygulamaların kullanımının her geçen gün arttığını ve önemini düşündüğümüzde kullanıcılara oluşturduğumuz web uygulamaları için mobile yakın kullanıcı deneyimide sunmak bizi pazarda öne çıkaracaktır.

Buradaki bir diğer önemli dosya ise service-worker.js dosyasıdır.

Service Worker, web sitesinden bağımsız olarak arka planda çalışabilen scriptlerdir. Yaptığı iş ise bir proxy’nin yaptığı işe benzemektedir. PWA ile geliştirdiğimiz uygulamamızda internet erişimimiz varken bir istek attığımızda service worker burada araya girerek isteğimizi alır. Eğer kullanıcı online ise istek için backende gider ve oradan cevabı döner ama eğer kullanıcı offline ise bu durumda ilgili bilgiyi cache den getirir. Böylece uygulamamız offline durumda da erişilebilir olmuş olur. Şimdi akıllara peki internet erişimi olmadığı durumlarda bana gelen verinin güncelliği nasıl mümkün olabilir gibi sorular gerebilir. Service worker listener yardımı ile bazı eventleri dinleyebilir. Örnek olarak get isteği yaptığımızı düşünelim. Bu durum için service worker “fetch” işlemlerini dinler ve bu işlem sonucunda dönen dataları kullanarak var olan dataları yenileriyle günceller. Bu şekilde kendini güncel tutmuş olur. Bunlara ek olarak post vb. olaylarıda dinleyerek online olunduğunda ilgili bilgileri iletebilir. Service worker’ların arka planda çalıştığını unutmamak gerekir yani biz web sayfasından doğrudan erişip bana bu datayı cache den getir diyememekteyiz.

Buraya kadar Blazor Server ve Blazor WebAssembly den bahsettik. Yazıyı ikisinin de temel olarak artıları ve eksilerini anlatarak noktalayalım.

Blazor Server

Pozitif Yönleri

  • İlk açılışta tüm dosyalar tarayıcıya indirilmediği için oldukça hızlıdır.
  • Ayrı bir frontend ve backend oluşturmamıza gerek olmadığı için kullanması pratiktir.
  • Tarayıcıların WebAssembly destekleyip desteklememesi Blazor Server’ı ilgilendirmediği için tarayıcı bağımsızdır.

Negatif Yönleri

  • Offline destek vermek istediğimizde yeterli değildir.
  • Tüm sayfayı yenilemese bile SignalR bağlantısındaki veri akışının yoğun olduğu zamanlarda gecikmeye sebep olabilir.
  • Her kullanıcı sunucu ile ayrı bir websocket bağlantısı oluşturduğu için ölçeklemek ve kontrol etmek zor olabilir.
  • Sunucuya ihtiyaç vardır.

Blazor WebAssembly

Pozitif Yönleri

  • Uygulama ilk açıldığında tüm dosyalar tarayıcıya yüklendiği için ilk açılış biraz uzun sürebilir ama sonrası çok hızlıdır.
  • İlk açılış sonrası çok hızlı olduğu için güçlü bir kullanıcı deneyimi sunar.
  • Progressive Web App desteği sunar.
  • Kullanıcılar internet erişimleri olmadığında bile uygulamayı kullanabilirler.
  • Server a ihtiyaç yoktur bu yüzden bir CDN yardımı ile uygulama deploy edilebilir.

Negatif Yönleri

  • Tüm dosyalar uygulama ilk açıldığında tarayıcıya yüklendiği için burada yaşanabilecek gecikme kullanıcı deneyimi açısından can sıkıcı olabilir.
  • Modern tarayıcıların hepsinde WebAssembly desteklenirken IE 11 gibi hala eski tarayıcıları kullanan bir müşteri kitlemiz varsa bu tarayıcılarda WebAssembly desteklenmemektedir.

Bu yazımızda Blazor’ın ne olduğundan, Blazor’ın serverda host edilen modeli olan Blazor Server’dan ve Blazor’ın istemci tarafında host edilen modeli olan Blazor WebAssembly’den bahsedip WebAssembly konusunu biraz daha detaylı olarak inceledik.

Burada anlatılan konular Doğuş Teknolojinin youtube kanalında da anlatılmıştır. Buraya tıklayarak veya aşağıdaki link ile ilgili yayına erişebilirsiniz.

Bir sonraki yazılarda görüşmek üzere.

İyi çalışmalar.

Yorum bırakın