AngularJS ile uygulamalarımızı yazarken, uygulamamızın en performanslı şekilde çalışması için yapmamız gereken bir takım ayarlar bulunuyor. AngularJS’ in yapısı, geliştiricilere olabildiğince esnek bir yapı sunmak üzere kurgulanmış, fakat geliştirme bitip, uygulamamızı production’ a aldığımızda, ince ayarlar yapmalıyız. Aşağıdaki listede bu ayarlardan ve kendi edindiğim tecrübelerden bahsedeceğim.

Disabling Debug Data

AngularJS default olarak, Dom node larına binding ve scope hakkında bilgiler ekler. Bu bilgiler nelerdir ? ne biçimdedir ? Örnek bir angular uygulamasının DOM’ undan alınmış ekran görüntüsünü paylaşıyorum.
angularjs dom

Görüldüğü üzere AngularJS’ in https://docs.angularjs.org/api/ng/provider/$compileProvider ‘ ı işlerini yürütürken, DOM’ a bir takım bilgiler eklemiş. Bu bilgiler kimin ne işine yarıyor ? Hemen açıklayalım.

AngularJS ile uygulama geliştirirken, uygulamanızı test etmeniz için geliştirilen araçlar bulunmaktadır. Bu araçlar;

https://github.com/angular/protractor

https://github.com/angular/batarang

Bu araçlar çalışırken, uygulamanızı test edebilmek için yukarıdaki ekran görüntüsünde gördüğümüz elementlere eklenmiş ng-isolate-scope vb. class lara ihtiyaç duyuyor.

Peki ne yapmamız gerekiyor ?

Tabiki bahsi geçen debug data’ sını, uygulamamızı kullanıcılarımıza sunduğumuzda yani production’ a aldığımızda kapamamız gerekiyor. Bu sayede DOM ekstradan dolmamış olacak ve işlemler daha kolay akıp gidebilecek.

Bunu yapabilmek için aşağıdaki js kodunu, uygulamanıza eklememiz gerekiyor.

Dikkat : kodu incelerseniz, myApp adındaki objenin config metodunun kullanıldığını göreceksiniz. Burdaki myApp değişkeni, angular uygulamanızı oluştururken set ettiğiniz ana modülün değişkenidir. Yani sizin kodunuzda bu kısım değişiklik gösterecektir. Örneğin kodunuz şu şekilde olmalıdır.

Bu şekilde uygulamamızı çalıştırdığımızda, debug data’ nın artık eklenmediğini görüyoruz.
angularjs no debug data

Peki uygulamamızı production ortamımıza gönderdik yani web sitemizi açtık diyelim, ve bir sebepten ötürü debug data’ ya ihtiyacımız var. JS kodlarımız artık serverdan geldiği için, kodta değişiklik yapamayız. İşte bu durumda tarayıcımızın console’ unu açıyoruz ve aşağıdaki kodu yapıştır enter tuşuna basıyoruz. Tarayıcımız web sitemizi, hiçbir kod değişikliği yapmamıza rağmen debug data ile sıfırdan açıyor. Ve Debug yapmaya başlıyoruz 🙂

“NG-CLASS yerine NG-STYLE” Kullanın

Mümkün olduğunca ! ng-class yerine ng-style directive’ ini kullanın.
Neden ? örnek vererek gösterelim;
Öncelikle http://ansukla.github.io/ng-perf/demo-app/index.html#/ng-class adresine girin ve Flip color butonuna tıklayıp, sayfadaki elementlerin renginin değişmesi için geçen süreyi takip edin, ardından http://ansukla.github.io/ng-perf/demo-app/index.html#/ng-style adresine girip aynı işlemi yapın ve geçen süreyi gözleyin. ng-style uygulanan örnekte renk değiştirme işlemi çok çok çok daha kısa sürede bitiyor değil mi 🙂

Şimdi inceleyelim;

Butona bastığımızda flipColor metodu çalışıyor, metodun yaptığı iş nedir ?

Her tıklandığında, negative değerini tersine çevirmek ve negative değerine göre color’ ın değerini red yada green yapmak.

Peki bu değer DOM’ da her iki örnekte de nasıl kullanılıyor ?

ng-class ile kullanımı;

ng-class directive’ i her td elementi için scope’ taki negative değerini izliyor ve negative değerine göre red yada green class’ ını element’ e ekliyor. Yani class ekleme çıkartma işlemi var.

ng-style ile kullanımı;

Hiçbir class ekleme çıkartma işlemi yok. flipColor metodunda color değeri anlık olarak değiştiriliyor du ya, işte ng-class directive’ i de bunu dinliyor ve color değişkenin değerini css color ataması olarak element’ e uyguluyor.

İki kullanım arasındaki bu farkın ne kadar büyük bir hız farkı yarattığını bu şekilde görmüş olduk.

Sizde kendi uygulamalarınızda, eğer iş akışınıza uygunsa ng-style kullanabilirsiniz.

 

“NG-BIND, Expression Bind ve One Time Bind’ dan daha hızlıdır”

Ve sıra geldi data binding’ e 🙂

Bildiğimiz üzere model’ i view’ a yansıtmanın yani asıl ismiyle söyleyeyim data-binding’ in Angular’ da 2 yolu var.

Expression ( {{burayaModelIsmiGelecek}} ) ile yada attribute ile (ng-bind=”burayaModelIsmiGelecek”)

Expression ise sürekli ve one-time-data-binding olmak üzere kendi içinde 2 ye ayrılıyor. Sürekli diye bir kavram yok aslında. Bu benim verdiğim bir isim oldu. AngularJS’ de default olarak, sürekli bir data-binding vardır. Model’ deki değişiklikler view’ a anlık olarak yansır. Lakin expression içinde modelin başına “::” ifadesini koyduğunuzda, bu model view’ a sadece 1 defa yansır. One-time-binding ile ilgili detaylı bilgiye https://docs.angularjs.org/guide/expression#one-time-binding adresinden ulaşabilirsiniz.

Kısa bir bilgilendirmenin ardından konumuzu toparlayalım 🙂

Şimdi 3 adet linke tıklayacaksınız, hepsinde bind edilen data aynı fakat bind edilme biçimleri yukarıda anlattığım gibi birbirinden farklı, ve bind süresini takip edin, bariz fark göreceksiniz.

ng-bind metodu ile : http://ansukla.github.io/ng-perf/demo-app/index.html#/ng-bind

expression bind ( {{bindEdilecekModelIsmiBurayaGelir}} ) ile : http://ansukla.github.io/ng-perf/demo-app/index.html#/expression-bind

expression bind ama 1 kere : http://ansukla.github.io/ng-perf/demo-app/index.html#/bind-once

Ben size şimdi sonuçları vereyim;

ng-bind ile ortalama 172 milisaniyede bind işlemi gerçekleşti.

expression ile 312 milisaniye, one time bind ile ise 314 milisaniye.

Yani, datanızı ng-bind ile bind ederseniz, neredeyse %100′ e yakın bir performans artışı elde ediyorsunuz.

Peki sebebi nedir ?

Benim tahminim, ng-bind directive’ i Angular tarafından, expression bind’ e göre daha az işlem ile gerçekleştiriliyor. Çünkü adı üzerinde ng-bind. Bu directive’ in içinde sadece model olabilir ve doludur değildir vb. ufak kontrolden sonra direk olarak view’ a basılır. İşlem bu kadar basit. Lakin expression öyle değil. Çünkü Expression’ ın içinde yazan, yazanlar model de olabilir, 2 + 2 de olabilir. Kısaca expression olabilir! Bu da Angular’ ın expression’ ın içini okuduğunda pek çok kontrolden geçirdiği, geçirmesi gerektiği anlamına geliyor. E haliyle bu durum zamandan yiyor.

Öyleyse, klasik bind işlemlerini ng-bind ile yapmak en karlısı 🙂

 

“$watch yerine $watchCollection kullanın”

Öncelikle şunu belirteyim, bu başlığın ismi aslında , “$watch kullanmayın” olabilirdi 🙂 Lakin madem kullanacaksın, öyleyse ekonomiğini kullan oldu 🙂

Normalde $watch metodu hızlıdır taki true parametresi alana kadar. Çünkü true parametresi aldığında deep checking yapar ve izlediği modelin tüm property’ lerini kontrol eder. Bu konuda en iyi örneği http://stackoverflow.com/a/29189252/2597746 adresindeki anlatımda bulabilirsiniz. İhtiyacınıza göre kullanın 🙂

 

“ng-model-options a gözatmadan yola çıkmayın”

Modelleriniz default olarak, en esnek ayarlar ile çalışır. Herşey tık tık anlık gerçekleşir. Lakin öyle durumlar olurki bu hız baş döndürür ve önünü almanız gerekir. https://docs.angularjs.org/api/ng/directive/ngModelOptions adresinden, seçeneklere baktığımızda işe yarar argümanlar görüyoruz. updateOn ve debounce gibi. Bu argümanları en çok hangi durumlarda kullanacaksınız ? Örnekleyelim;

Sayfanızda bir arama input’ u var ve kullanıcı input’ taki değeri değiştirdikçe autocomplete destekli arama yapıyor. Lakin hiçkimse 10 parmak yazacak kadar klavye’ ye hakim değilse, istediğini tek seferde düzgünce yazamaz ve şöyle düşünün, kullanıcı input’ taki text’ i saniyede birkaç kere değiştiriyor, yanlış yazıyor siliyor, fakat siz bu yanlışların düzelmesini beklemeden backend’ e sorgu gönderilmesine izin veriyorsunuz. YANLIŞ! Bu tarz inputların debounce değerini en az 500 verin ve kullanıcı input’ u değiştirmeyi bıraktıktan yarım saniye geçtikten sonra model update edilmiş sayılsın ve işlemleriniz devam etsin.

 

“ng-show yerine ng-if kullanın ama ng-if’ in de istediğiniz işi doğru yaptığından emin olun”

ng-show, element’ i render eder ve gözükmemesi gereken bir case olmuşsa, CSS display değerini none yapar ve element DOM’ da kalır.

ng-if ise element gözükmemesi gerekiyorsa DOM’ dan siler. Gözükmesi gereken case yaşandıysa tekrar yaratır. Bu böyle devam eder.

Tabiki DOM bizim için çok değerli ve düşünün ki çok büyük bir data setimiz var, 10.000 küsür kayıt. Gözükmemesi gereken kayıtlar DOM’ da durursa bize ağırlık yaratır. ng-if bu kayıtları DOM’ dan silerek bize büyük performans sağlar. Lakin bazı case ler var, benimde deneyimlediğim, bu case lerde ng-show kullanmaktan başka çare yok. Başlıktada bahsettiğim gibi, önce test yapın ardından ng-if’ i tercih edin.

 

“console.time() ile süreleri ölçün”

Metodlarınız çalışırken geçen süreyi ölçmek çok önemlidir. Bir işi birden farklı şekilde yapabilirsiniz, ve hangisini tercih etmeniz gerektiğini, harcadıkları zamanı ölçerek seçebilirsiniz.

https://developer.mozilla.org/en-US/docs/Web/API/Console/time adresinden de inceleyebileceğiniz gibi console.time() gibi güzel bir API var.

Nasıl kullanılıyor ?

Metodunuzun başına ve sonuna eklerseniz, işlem süresini console’ da yazar.

 

“Yavaş gerçekleşen işlemlerde Native Javascript yada lodash kullanın”

Örneğin klasik bir takım işler için Angular’ ın dahili bir metodunu kullanıyorsunuz ama işler beklediğinizden yavaş gerçekleşiyor, MÜMKÜNDÜR, OLABİLİR. Çünkü herkes için yazılmıştır, daha fazla parametre alır, daha fazla kontrol yapar vs vs vs. Ve sonuç olarak yavaştır. Bu durumda o işlemi yapan kendi metodunuzu yazın yada https://lodash.com/ adresinden ulaşabileceğiniz, JavaScript’ te en klasik işleri ve daha fazlasını daha performanslı gerçekleştiren kütüphaneyi kullanın.

 

“Destroy’ u takip edip, eventleri öldürmeyi ihmal etmeyin”

Özellikle event kuran directive’ lerinizde mutlaka yapmanız gereken bir işlemdir.

Bir directive’ iniz var, kullanılmaya başlandığı anda bir event kuruyor. Tıklama, şıklama vb. Fakat bir süre sonra directive’ in kullanılmadığı bir sayfaya geçmenize ve directive’ in artık sayfanızdan silinmesine rağmen, eventleri duruyor !

İşte bu tarz directive’ lerinizin mutlaka destroy eventi de olmalı ve gerekli cleanup işlemlerini yapmalı.

Örnek;

Bakın yukarıdaki directive’ in window’ un resize olması event’ ine bağlı olarak çalışan onResize metodu var. Lakin bu directive sayfadan silindikten sonra bu event neden dinlenmeye devam etsin ki ? İşte bu yüzden $scope.$on(‘$destroy’, cleanUp); ile directive yok edildiğinde cleanUp metodunu çalıştırıyoruz, bu metod da “off” metodu ile event’ i öldürüyor.

destroy sadece directive ler için değil controller lar içinde geçerlidir. Diyelim ki her 5 saniyede yapılması gereken bir işi, interval kurarak yapıyorsunuz, ama başka sayfaya geçtiniz, controller’ ınız değişti ve o interval’ in çalışması gerekmiyor artık. https://docs.angularjs.org/api/ng/service/$interval#example adresindeki örnekte gösterildiği gibi, interval’ i öldürebilirsiniz.

 

Konu Sürekli Güncellenecektir.

Leave A Comment

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir