Azami Hız — Smidge

Cihat Solak
Berkut Teknoloji
Published in
4 min readSep 23, 2021
A lightweight ASP.Net Core library for runtime CSS and JavaScript file management, minification, combination & compression

Net Core projelerinde varsayılan (default) olarak gelen bir bundle (gruplama) işlevi bulunmadığından özel (custom) olarak eklememiz/yapmamız gereken birtakım ufak gereksinimlerimiz bulunmaktadır. Klasik MVC tarafında, framework 4.5 ile gelen ve projemizde kullanılan script/style dosyalarının tek elden yönetimini sağlayan rahmetli 🤶 BundleConfig.cs adında sınıfımız vardı. Şimdiyse yerini alternatifleri aldı. Bu alternatiflerden biri olan Smidge, runtime anında minification (küçültme) ve bundling (gruplama) işlemlerini otomatik olarak gerçekleştiriyor. Runtime anında minification yapılması dezavantaj olarak görünse de projemizin performansını 🚀 ve yüklenme ⏳ hızını arttıracağı aşikârdır.

Bundling (Gruplama)

Özellikle projemizin layout sayfasında ve diğer sayfalarında style ve script referansları eklerken tek tek “<script></script>”, “<style></style>” etiketlerinin kullanıldığına şahit olmuşuzdur. Projenin sürdürülebilirliği açısından pratik bir yöntem değil ve ilerleyen süreçte başımıza bela 🔫 olma olasılığı da bir o kadar yüksektir. Bahsini geçirdiğimiz kütüphane yardımıyla projede kullandığımız CSS ve JS dosyalarını bundling etmemiz projenin akıbeti için fayda sağlayacaktır. Nasıl? Proje de 8–10 CSS dosyası, 10–12 de JavaScript dosyası olduğunu ve bunları bundling işlemine tabii tutmadığımızı varsayarsak, siteye gelecek istekle birlikte tüm dosyaları almak için farklı istekler gerçekleşecektir. 10 CSS + 12 JS = 22 statik dosya için istek gerçekleştirilmiş olacaktır. Burada bundling işleminden faydalanmış olsaydık CSS dosyaları için 1 adet, JS dosyaları için 1 adet olmak üzere toplamda 2 istek de bulunulmuş olacaktı. Bu durumda da tahmin edebileceğiniz üzere performans grafiğimiz 📈 yukarı yönlü hareket edecektir.

Minification (Küçültme)

Bir dosyanın fonksiyonelliğini bozmadan yorum satırlarından, boşluk karakterlerinden arındırılma işlemine denir. Bu sayede CSS ve JS dosyalarının boyutu çok daha düşük olacak, request/response arasında ki veri transferi de bir o kadar artacaktır. Son kullanıcı tabiriyle 🙋🏼 🙋🏼‍♂️ de sayfa hızlı yüklenecektir.

Nasıl Projeye Dahil Edebilirim?

Nuget Package Manager — Smidge

appsettings.json ve startup sınıfına entegrasyon için eklemeler yapıyoruz.

appsettings.json Konfigürasyonu
Startup.cs Konfigürasyonu

Bu aşamadan sonra _ViewImports.cshtml dosyasına TagHelper olarak smidge’i ekliyoruz ve artık hazırız! ⭐️

_ViewImports.cshtml Konfigürasyonu

.Net Core environment ile dosyalarını nasıl paketleyeceğimiz veya küçülteceğimiz konusunda ilgili yazıyı buraya bırakıyorum. Aşağıdaki örnek kod ile konuyu aydınlığa ☀️ kavuşturduğumu düşünüyorum.

{viewname}.cshtml

Bundle işlemi gerçekleştirdiğim JS dosyasını environment (Development, Staging, Production) değişkenlerle farklı ortamlarda farklı durumlar sergilemesini bildirdim. Environment değerler ile aranız kötü ise Net Core: Ortamına Göre Davran adlı içeriğime beklerim. 👨🏼‍💻

Debug Mod (debug=true)

Birden fazla dosyayı bundle ediyor yani birleştiriyoruz fakat bunun production ortamda olmasını istiyoruz. Çünkü development ortamda dosyaların yani kodların birleşmemesi gerekli ki breakpoint ile kodu takip edebilip ya da debug edebileyim. Tam burada imdadımıza yukarıdaki github gist’inden de gördüğünüz debug=“true” attribute yetişiyor. Herhangi bir dosyayı debug=true olarak işaretlersek smidge kütüphanesi birleştirme işlemi gerçekleştirmiyor.

Smidge kütüphanesi ile environment
Environment = Development

Enviroment ortamları belirlediğimizde, development ortamda görüldüğü gibi site ve site2.js tamamen ayrı ayrı gelmektedir. Projemizin Enviroment ortamını production olarak belirtseydik her iki dosya yerine “my-js-bundle.js.v1” isimli bundle edilmiş bir dosya ile karşılaşacaktık.

Bundle etmek istediğimiz dosyaları startup.cs içerisindeki Configure metotunda 👩🏼‍🏫 gerçekleştiriyoruz.

Bundle — Smidge Middleware

Cache — AppData

Smidge kütüphanesi kendi içinde cacheleme mekanizmasını barındırır. Dosyalara bundle işlemi gerçekleştirildiğinde bundle sonucunda bir cache dosyası oluşacak (isim olarak appSettings.json içinde belirlediğiniz isim olacaktır) ve uygulama ayağa kalkacaktır. Sayfayı tekrar refresh yaptığınızda tekrar bir bundle değil cache dosyası okunacaktır. (App_Data/Smidge)

Smidge Ayarları — appsettings.json

Development ortamda da bundle etsin, ben bir göreyim. Ayrıca cache de almasın ben silmekle uğraşmayayım diyorsan, çok şey istemiyorsun 🤷🏼‍♂️ bunun için bir middleware yazılmış.

Bundle With Environment Options — Smidge Middleware

builder.EnableCompositeProcessing(): Normalde debug modda dosyaları birleştirme işlemi gerçekleştirmiyordu, bu ayarla birlikte artık debug modda da birleştirme işlemi yapacak.

ForDebug(): Konfigürasyonun debug mod için geçerli olacağını belirtiyoruz.

EnableFileWatcher(): Bundle içerisinde oluşan dosyalarımı izle, eğer değişiklik olursa cache dosyasını yeniden oluştur.

SetCacheBusterType<AppDomainLifetimeCacheBuster>(): Uygulamam her ayağa kalktığında cache sıfırlansın, yeniden oluşturulsun. Yani cache’in ne zaman bozulacağını belirtiyorum.

CacheControlOptions:

E-Tag: Tarayıcılar sunucudan herhangi bir dosyayı çektiği zaman response olarak sunucu bir tag gönderir. Etag bir token değeridir amacı tarayıcının birden sonraki isteklerinde dosyanın değişip değişmediğidir. Örneğin tarayıcı sunucudan bir resim istiyor sunucu resmi gönderirken responsun headerında da bir e-tag değeri gönderiyor. Tarayıcı bunu headerla beraber kayıt ediyor ve sayfa yeniden yüklendiği zaman tarayıcı bu Etag’ı gönderiyor. Sunucu gelen etagın bir önceki etag ile aynıysa kaynakta bir değişik olmadığını 304 durum kodu ile tarayıcıya bildiriyor. 304 Not Modified, değişiklik olmadığı anlamına gelmektedir. Tarayıcıda dosyada bir değişiklik olmadığını anlayıp cache’den getiriyor. Yani sunucu tarayıcıya 304 dönerek istediğin dosyada herhangi bir değişiklik yok hâlâ geçerli sen bu kaynağı cache’den oku diyor.

CacheControlMaxAge: Tarayıcı cache’inde ilgili kaynağın(resim, video vs.) ne kadar tutulacağının saniye cinsinden değeridir. Yani sunucudan veri gelirken tarayıcı diyecek ki e-tag’ı false ise demek ki ben her zaman sunucudan çekmem gerekiyor ve cacheControlMaxAge’de 0 gelmiş demek ki ben bunu bellekte ya da herhangi bir diskte tutmayacağım diye kontrol sağlıyor.

--

--