Vue.js Uygulama Performans Optimizasyonu — Lazy loading Vuex Modülü

Mert DEMİR
Berkut Teknoloji
Published in
5 min readSep 8, 2021

Vuex Modelinin İki Farklı Tipi

Daha ileri gitmeden ve Vuex modüllerini lazy loading yapmadan önce bilmeniz gereken önemli bir şey var. Bir Vuex modülünü kaydetmenin olası yollarının neler olduğunu, bunların artı ve eksilerinin neler olduğunu anlamanız gerekir.

Statik Vuex modülleri, Store başlatma sırasında bildirilir. Açıkça oluşturulmuş statik modül örneği:

// store.js
import { userAccountModule } from './modules/userAccount'
const store = new Vuex.Store({
modules: {
user: userAccountModule
}
})

Yukarıdaki kod, statik modül userAccountModule ile yeni bir Vuex Store oluşturacaktır. Statik modüllerin kaydı silinemez ve yapıları (state değil!) Store başlatma işleminden sonra değiştirilemez.

Bu sınırlamalar modüllerin çoğu için bir sorun olmayacak ve hepsini tek bir yerde tanımlamak, verilerle ilgili tüm şeyleri tek bir yerde tutmak gerçekten yararlı olsa da, bu yaklaşımın bazı dezavantajları vardır.

Diyelim ki uygulamamızda özel bir Vuex modülüne sahip Admin Dashboard var.

// store.js
import { userAccountModule } from './modules/userAccount'
import { adminModule } from './modules/admin'
const store = new Vuex.Store({
modules: {
user: userAccountModule,
admin: adminModule
}
})

Böyle bir modülün oldukça büyük olabileceğini hayal edebilirsiniz. Kontrol paneli, kullanıcıların sadece küçük bir kısmı tarafından ve kısıtlı bir uygulama alanında (/admin yolu altında diyelim) kullanılacak olsa da, statik Vuex modüllerinin merkezi kaydı nedeniyle, kodunun tamamı ana pakette bundle edilecektir.

Tüm modüllerimiz tek bir dosyada (store.js içinde) toplanımıştır

Bu kesinlikle bizim istediğimiz bir durum değil. Bu modülü yalnızca /admin yolunda(route) yüklemek için bir yola ihtiyacımız var. Tahmin edebileceğiniz gibi statik modüller ihtiyacımızı karşılayamaz. Tüm statik modüllerin Vuex Store oluşturma anında kaydedilmesi gerekir, bu nedenle daha sonra kaydedilemezler.

Dinamik modüllerin bize yardımcı olabileceği yer burasıdır!

Statik modüllerin aksine dinamik modüller Vuex Store oluşturulduktan sonra kaydedilebilir. Bu kullanım, uygulama başlatılırken dinamik modül indirmemize gerek olmadığı ve onu farklı kod yığınlarında paketleyebileceğimiz veya gerektiğinde lazy loading yapabileceğimizin anlamına gelir.

İlk önce dinamik olarak kayıtlı adminmodülü ile önceki kodun nasıl görüneceğini görelim.

// store.js
import { userAccountModule } from './modules/userAccount'
import { adminModule } from './modules/admin'
const store = new Vuex.Store({
modules: {
user: userAccountModule,
}
})store.registerModule('admin', adminModule)

adminModule nesnesini doğrudan store modül özelliğine geçirmek yerine, registerModule yöntemiyle Store oluşturduktan sonra kaydettik.

Dinamik kayıt, modülün kendisinde herhangi bir değişiklik gerektirmez, bu nedenle herhangi bir Vuex modülü statik veya dinamik olarak kaydedilebilir.

Tabii ki mevcut haliyle bu dinamik olarak kayıtlı modül bize bir avantaj sağlamıyor.

code-splitted Vuex modules

Sorunumuza geri dönelim. Artık admin modülünü dinamik olarak nasıl kaydedeceğimizi bildiğimize göre, kodu /admin route paketine koymayı kesinlikle deneyebiliriz.

Şu an üzerinde çalıştığımız uygulamayı anlamak için bir soluklanalım :)

// router.js
import VueRouter from 'vue-router'
const Home = () => import('./Home.vue')
const Admin = () => import('./Admin.vue')
const routes = [
{ path: '/', component: Home },
{ path: '/admin', component: Admin }
]
export const router = new VueRouter({ routes })

Router.js’de lazy loading şeklinde yüklenen iki tane code-splitted route var. Yukarıda gördüğümüz kod ile admin Vuex modülümüz store.js’deki statik içe aktarma nedeniyle hala ana app.js paketindedir.

Bunu düzeltelim ve bu modülü sadece /admin rotasına giren kullanıcılara yükleyelim, böylece diğerleri gereksiz kodu indirmesin.

Bunu yapmak için admin modülünü store.js içine yüklemek yerine /admin route bileşenine yükleyeceğiz.

// store.js
import { userAccountModule } from './modules/userAccount'export const store = new Vuex.Store({
modules: {
user: userAccountModule,
}
})// Admin.vue
import adminModule from './admin.js'
export default {
mounted () {
this.$store.registerModule('admin', adminModule)
},
beforeDestroy () {
this.$store.unregisterModule('admin')
}
}

Neler olduğuna bir göz atalım!

Monte edildikten hemen sonra Admin.vue (/admin route) içindeki admin Store’u içe aktarıyor ve kaydediyoruz. Kodun ilerleyen kısımlarında, aynı modülün birden fazla kaydını önlemek için kullanıcı yönetici panelinden çıktıktan sonra modülün kaydını kaldırıyoruz.

Şimdi admin modülü store.js yerine Admin.vue içine aktarıldığından, Admin.vue ile birlikte paketlenecektir!

Önemli Not: SSR modunu kullanıyorsanız, modülü mounted edilmiş hook kaydettiğinizden emin olun. Aksi takdirde, beforeDestroy hook sunucu tarafında değerlendirilmediği için bellek sızıntılarına neden olabilir.

Artık route özel modüllerimizi uygun paketlere dağıtmak için dinamik Vuex modül yapısını nasıl kullanacağımızı biliyoruz. Biraz daha karmaşık kullanım durumuna bir göz atalım.

Lazy loading Vuex Modülü

Diyelim ki Home.vue da hizmetlerimiz hakkında olumlu görüşler göstermek istediğimiz referanslar bölümümüz var. Kullanıcı web sitemize girdikten hemen sonra bunları göstermek istemiyoruz. Bunları yalnızca kullanıcı isterse görüntülemek çok daha iyi bir seçimdir. Görüş sayfasına geldikten sonra altına referansları yükleyecek ve gösterecek olan “Show Testimonials(Görüşleri Göster)” butonunu ekleyebiliriz.

Görüş verilerini depolamak için bir Vuex modülüne daha ihtiyacımız var. Adını testimonialsc diyelim. Modül, daha önce eklenen görüşleri göstermekten ve yenilerini eklemekten sorumlu olacaktır. Şu anlık uygulama detaylarını bilmemize gerek yok.

Görüşler modülünün SADECE kullanıcı düğmeyi tıkladığında gösterilmesini istiyoruz. Bu işlevi elde etmek için dinamik modül kaydı ve dinamik içe aktarmadan nasıl yararlanabileceğimizi görelim. Testimonials.vue, Home.vue içindeki bir bileşendir(component).

Kodu hızlıca gözden geçirelim.

Kullanıcı Görüşleri Göster buttonuna tıkladığında getTestimonials() methodu çağrılır. getTestimonialsModule() işlevi testimonials.js çağırmaktan sorumludur.

Dinamik içe vuex store sayesinde testimonials.js içeriği, yalnızca getTestimonialsModule fonksiyonu çağrıldığında yüklenir.

Admin panelinden çıkmamız gerektiğinde, beforeDestroy yaşam döngüsünde önceden kayıtlı modülün kaydını siliyoruz, böylece bu route’a tekrar girersek tekrardan store yüklenmeyecektir.

Özet

Çoğu kullanım durumu için statik Vuex modül yapısı yeterli olsa da, dinamik yapıyı kullanmak isteyebileceğimiz bazı durumlar vardır.

Modüle yalnızca belirli bir route da ihtiyaç duyuluyorsa, ana pakete yüklenmemesi için onu dinamik olarak uygun route bileşenlerine kaydedebiliriz.

Modüle yalnızca bazı etkileşimlerden sonra ihtiyaç duyulursa, modülü lazy loading’e uygun bir yöntemle yüklememiz gerekir.

Kaynakça

--

--

Mert DEMİR
Berkut Teknoloji

Software Engineering => {#JavaScript #Vuejs #Nuxtjs #Jest}