Alpine.js: Yeni Nesil jQuery Alternatifi
Bundan çok değil, daha birkaç yıl önce jQuery ve bootstrap ile harikalar yaratırken, artık günümüzde SPA’lerin de yaygınlaşması ile kendimizi React, Vue, Angular arasında seçim yaparken buluyoruz. Bu 3 framework de JavaScript bazlı bir uygulama geliştirmek için ideal çözümler sunuyor ve yaygın olarak kullanılıyor. Peki sadece küçük bir sayfada JavaScript ile bir şeyler yapmak istediğimizde ne olacak? Örneğin statik bir web sayfasında, e-bülten için abonelik formu oluşturmak istediğimizde hâlâ React mi kullanacağız? jQuery kütüphanesinin dahi 31.4 kB yer kapladığı JavaScript ekosisteminde, küçük işler için daha düşük boyutlu kütüphane kullanımı şart. Bu nedenle Vue ve Angular’dan ilham alan geliştiriciler Alpine.js’i üretti.
Alpine.js nedir?
Alpine.js, Vue veya React gibi reaktif ve deklaratif bir framework’tür. Farkı ise diğer popüler framework’lerin aksine 7.6kB boyutunda alan kaplamasıdır. Bu sayede küçük işler için kolaylıkla uygulanabilir.
Başlangıçta bu bilgi tek başına bir anlam ifade etmeyebilir. Bu nedenle Alpine.js’i test etmek için aşağıdaki gibi reaktif bir input elemanı oluşturdum. Bu işlem için <script> etiketi ile kütüphanenin url’ini vermeniz ve aşağıdaki gibi sadece 4 satır eklemeniz yetiyor. Geri kalanını Alpine.js hallediyor:
Daha sonra aynı örneği benzer şekilde diğer popüler JS kütüphaneleri ile deneme yaptığımda aşağıdaki gibi bir tablo beni karşıladı. (Not: Svelte, Ember veya Angular2 gibi diğer build gerektiren kütüphaneleri eklemedim. Çünkü onları da eklediğinizde Web Assembly ile derleyebileceğiniz C# veya Lua gibi diğer dilleri de eklemeniz gerekebilir. O zaman konu çok dağılacaktır.)
Daha sonra oluşan kodlardaki karakter sayılarını bash’deki wc komutu ile ölçtükten sonra, sort komutu ile azdan-çoğa doğru sıralayarak görüntüledim:
Oluşan bu verileri Google Sheets üzerinde grafiğe aktardım:
Grafiğe baktığımda aslında severek ReactJS geliştirdiğim halde bu tarz basit işler için çok daha fazla kodlama gerektirdiğini gördüm (324 karakter). React’i bırakıp hiç kütüphane kullanmadan denediğinizde ise (Vanilla grafiği), Vue’den biraz daha fazla miktarda kod yazmanız gerekiyor (182 karakter/161 karakter). Dolayısıyla vanilla JS ile yazmak yerine Vue ile yazmak daha mantıklı gibi görünüyor. En ilgi çekici kısım ise Angular1’in Alpine’i geçerek neredeyse jQuery’nin yarısı sayıda karakter ile bu işi halledebilmesi oldu (70 karakter ile yazıldı). Grafiği analiz ederken farkedeceğiniz üzere en yüksek ile en düşük bar’ı karşılaştırdığımızda Angular1’in neredeyse 5 katı kod yazarak ReactJS’te aynı işi yapabiliyorsunuz.
Peki durum böyle iken web sayfasının boyutu ne kadar oluyor? Bunu ölçümlemek için farklı JS kütüphaneleri ile yazılan sayfaları teker teker Chrome üzerinde açarak, network sekmesinden transfer edilen byte bilgisini inceledim.
Görüldüğü gibi ReactJS diğerlerine göre çok fazla network paketi kullandı. Bunun sebebi, JSX kodu kullanımında babel transpiler’ı gerektiği için babel.min.js’i eklememden dolayı kaynaklanıyor. Derlenerek çok daha az bir boyuta indirgenebilir ama daha önce bahsettiğim nedenlerden dolayı derleme işlemini gerçekleştirmedim. Daha sonra React’i hariç tutarak diğer kütüphanelerin payload miktarlarını grafiğe aktardım:
Görüldüğü üzere hiçbir JS kütüphanesi kullanmadan Vanilla halinde yazdığınızda sayfa boyutu 451 byte gibi çok küçük bir miktar haline geliyor. Grafikteki ikinci en yüksek bar ise 7.9 KB’lık boyutu ile AlpineJS oluyor. JQuery veya Vue ise Alpine’in 4 katı kadar bundle size içererek 32 KB’da işi tamamlıyorlar. Grafiğin en yüksek bar’ı olan Angular1 ise, 60 KB’lık boyutundan dolayı önceki grafikteki en iyi konumunu burada en kötüye çekmiş durumda.
Bu payload grafiği, yüksek hızlı 4G veya fiber ağlarını düşündüğünüzde anlamsız gelebilir. Ancak örnek olarak oy sayımının web sayfası üzerinden alınması gibi tüm ülke coğrafyasında kullanılabilecek bir uygulama düşünüldüğünde, GPRS veya EDGE gibi diğer yavaş ağları da desteklemeniz oldukça önem arz edecektir.
İki grafiği de ele aldığınızda, hem sayfa büyüklüğü hem de kodlama kolaylığı olarak AlpineJS oldukça başarılı görünüyor. Kodlama tarzı da Vue ile oldukça benzer. Hatta Vue geliştiricisi Evan You da Alpine’i öven bir tweet atmıştı:
Bana kalırsa AlpineJS’in oldukça iyi olduğunu düşünüyorum. Vue’nün çok ağır geleceği basit sayfalar için önemli bir boşluğu dolduruyor. Diğer geliştiricilerin VueJS’in güzel yerlerinden ilham alarak böyle bir kütüphaneyi üretmiş olmasından mutluluk duyuyorum.
Vue ile benzer yapısı ve oldukça deklaratif olmasından dolayı Alpine, birçok basit bileşeni oluşturmak için rahatlıkla kullanılabilir. İsterseniz bu durumu örnekler ile gerçekleştirelim:
Reaktif bir input alanının kodlanması
Reaktivite denildiğinde ilk akla gelen örnek, bir input alanına değer yazıldığında eş zamanlı olarak span gibi bir elemana ilgili değerin aktarılmasdır. Şimdi yazının ilk kısımlarında yaptığımız Alpine örneği görüntüleyelim ve açıklayalım:
Görüldüğü üzere <script>
etiketi haricinde sadece 4 satır ile reaktif bir input elemanı yapılabiliyor. Bu örneği açıklamak gerekirse:
- x-data: İçerideki elemanlara aktarılacak verinin belirtilmesini sağlar. Alpine.js, verilen data nesnesi ile birlikte yeni bir bileşen oluşturur. Bileşenin alt elemanları ise bu bilgiyi kullanarak belirli işlemleri gerçekleştirirler. Buradaki örnekte ise basılacak mesaj metni için bir
msg
değeri kullanılmaktadır. - x-model: İlgili verinin, belirtilen elemana iki yönlü olacak şekilde bağlanmasını sağlar (two-way data binding). Bu sayede hem eleman veriyi değiştirir, hem de veri değiştiğinde ilgili elemanın değeri de otomatik olarak güncellenmiş olur. Dolayısıyla
<input>
iledata
elemanı birbiri ile senkronize edilmiş hale gelir. Sadece input değil, checkbox, radio button, textarea, select, ve multiple select gibi diğer elemanları da destekler. Ayrıca ilgili değişikliğin gecikmeli olarak yansıtılabilmesi içinx-model
ile birliktedebounce
özelliği de verilebilir. Bu sayede site içi arama gibi işlemlerde sunucuya sürekli istek gönderilmesinden dolayı oluşan sunucunun aşırı yüklenmesi gibi bir durumun önüne geçilebilir. Milisaniye cinsinden değer alır. Örnek kullanım:<input x-model.debounce.750="search">
- x-text: İlgili verinin tek yönlü bir şekilde bağlanmasını sağlar. Bağlı olduğu veri değiştiğinde, ilgili elemanın
innerText
özelliğini değiştirir.
Şimdi diğer bir bileşen olan dropdown’ı yapalım.
Dropdown bileşeni yapımı
Dropdown gibi göster/gizle bileşenleri tüm uygulamaların bir vazgeçilmezini oluşturuyor. Örneğin aşağıdaki gibi bir yorum alanı içerisinde gizlemek istediğiniz kısımlar için bir “Spoiler göster” butonu yapabilirsiniz:
Kodu çalıştırdığınızda butona tıklandığı anda gizlenen içeriğin görüntülenmesi/gizlenmesi sağlanacaktır:
Kodu açıklayalım:
- @click:
x-on:click
yerine kısaltma olarak kullanılır. Tıklama anında yapılacak eylemi belirtilir. Buradaopen
değişkeninetrue
değeri atanmaktadır. - x-show: Belirtilen değişkene göre ilgili elemanı gizlemek için CSS özelliğine
display: none
değerini atar. Eğer belirtilen değer true isedisplay: none
değeri kaldırılır. - @click.away: Belirtilen eleman haricinde sayfada herhangi bir yere tıklandığında ilgili işlemin yapılmasını sağlar. Bu örnekte, sayfanın herhangi bir bölümüne tıklandığında spoiler’ın gizlenmesi sağlanmaktadır.
Tab bileşeni yapımı
Sekmeli bir yapıda içeriği sunan tab bileşenleri, Alpine.js ile aşağıdaki gibi yapılabilir.
Kodu çalıştırdığınızda aşağıdaki gibi bir ekran sizi karşılayacaktır:
Adres çubuğunda da değişiklik olduğunu farketmişsinizdir. Bu sayede sadece tab değil sayfalama (pagination/routing) işlemlerini de kolaylıkla gerçekleştirebiliriz.
Sonuç olarak
Hem hafifliği, hem de basit yazımı AlpineJS, küçük bileşen bazlı uygulamalar için tam bir biçilmiş kaftan. Özellikle TailwindCSS gibi bir stil aracı ile birleştiğinde kolaylıkla birçok uygulamayı çıkarabiliyorsunuz. Daha fazla örnek için alpine/examples, alpinejs-playground inceleyebilirsiniz. Ayrıca birçok örneğin de yer aldığı Alpine Toolbox sayfasına da gidebilirsiniz Bir sonraki yazıda görüşmek üzere…