JavaScript Uygulamalarında Performans — Bölüm 2

Oğuz Kılıç
7 min readOct 18, 2022

--

JavaScript uygulamalarında yaşanan performans problemleri ve nedenleri üzerine bir inceleme

Photo by Talia Cohen on Unsplash

JavaScript Uygulamalarında Performans” başlığıyla ilk yazımı Ekim 2021'de yazmıştım. Aradan geçen 1 yılın ardından yazının gecikmiş ikinci bölümüyle devam ediyorum. Bu yazının daha iyi anlaşılabilmesi için önce ilk yazıyı okumanızı tavsiye ediyorum. Aşağıdaki bağlantıdan ilk yazıya ulaşabilirsiniz.

Bu yazı, performans problemlerinin tespit ve takip edilmesi gibi yaşadığımız problemlerin çözümüne ulaşmamıza katkı sağlayabilecek bazı konuları içerir.

Gözlemlenebilirlik

Performansı iyileştirmenin ilk aşaması uygulama performansına ait doğru metrikleri gözlemleyebilmektir. Uygulamamızın çıktılarını inceleyerek elde ettiğimiz bilgilerle mevcut durum hakkında yorum yapabiliriz. Bu nedenle uygulamamızın gözlemlenebilir olması büyük bir öneme sahiptir. Özellikle basit sistemleri yönetmek çok daha kolayken, karmaşık sistemleri yönetebilmek için sistem üzerinde daha fazla kontrole sahip olmak isteriz.

Üzerinde çalıştığımız sistemde gözlemleyemediğimiz karanlık bölgeler istemeyiz.

Observability vs Monitoring

Konuya devam etmeden önce bu iki konuyu kısaca özetlemek istiyorum. İzleme, gözlemlenebilirliği artırmak için yaptığımız bir eylemi ifade eder. Gözlemlenebilirlik ise, sistemin bir özelliği olarak ifade edilir. Örneğin, bir sistemin zaman içindeki performansını izlemeniz bir gözlemleme eylemidir. İzleme araçlarıyla ilgili verileri toplar, analiz eder ve ön görülerimizi ortaya koyarız. Gözlemlenebilirlik dediğimizde daha bütünsel bir anlayışı ifade etmeye çalışıyoruz.

CPU, Memory, Network trafiği gibi bizi ilgilendiren tüm koşulları izleyebilmemiz, çalışan uygulamamızın anlık davranışlarını doğru yorumlamamıza yardımcı olacaktır.

Bir uygulamanın gözlemlenebilir olarak kabul edilebilmesi için birçok kriter bulunuyor. Oldukça detaylı bir konu olduğu için detaya girmem pek mümkün değil ancak buraya kadarki bölümde konunun temel mantığını kavramış olmalıyız.

İçinde bulunduğumuz durumu “performans” başlığı ekseninde ele alırsak bir web uygulamasının gözlemlenebilir metriklerinin neler olduğunu anlamamız oldukça önemli. Bu metriklerin bazıları doğrudan son kullanıcıyı etkilerken, bazıları sistem kaynaklarının kullanımını etkiler. Hangi metriklerin bizim için hayati olduğunu, hangi metriklerin daha az hayati olduğunu ve bu metrikler için kabul edilebilir alt ve üst limitleri belirlememiz gerekli.

Ulaşılabilir performans hedefleri belirleyin

Web performansını iyileştirmek için ön yüz geliştiriciler olarak Google’ın Core Web Vitals metriklerini referans alıyoruz genellikle. Bunun nedeni bu skorların SEO için önemli olması ve PageRank algoritmasında sıralamaya etki eden sinyallerden biri olması. Web Vitals için bir ürünün doğrudan 100 puanı hedeflemesi çok doğru bir yaklaşım olmayabilir.

Birçok ürün için bu hedefe ulaşmak oldukça yorucudur. Web uygulamanızı ziyaret eden hedef kitleyi analiz edip, hedef kitlenin çoğunlukla kullandığı teknolojileri (tarayıcı, cihaz, internet bağlantı hızı vb) göz önünde bulundurarak bir performans skoru hedeflemesi yapmak çok daha gerçekçi olacaktır.

Hedef kitle analizi yapın

Ziyaretçilerinizin büyük bir bölümü 4G bağlantı hızlarıyla ve modern tarayıcılar ile web sitenize erişiyorsa performans optimizasyonunuzu bu doğrultuda yapmanız daha ulaşılabilir bir hedef olur. SpeedTest’in mobil ve sabit internet için ülke bazlı sunduğu raporları inceleyebilirsiniz.

Kaynak: speedtest

Analytics verilerinizi doğru yorumlayarak öncelikle hedef kitle analizini yapmalı, ardından destek vereceğiniz tarayıcı, cihaz ve bağlantı hızlarını önceliklendirmelisiniz. Tüm tarayıcılara ve tüm cihaz tiplerine destek vermek zorunda değilsiniz çünkü bu durum sizi ürün üzerinde kullanacağınız teknolojiler, pratikler ve kullanıcı deneyimi konusunda zamanla kısıtlamaya başlayacaktır.

Bu nedenle bazı ürünlerin lite versiyonları oluşturularak bağlantı hızı düşük olan kullanıcılara gösterilebiliyor veya ürün üzerindeki bazı özellikler kullanıcının erişim şekline göre dinamik olarak değişkenlik gösterebiliyor. Tarayıcılar bu tür bilgilere erişmek için geliştiricilere API desteği sunuyor. Bu sayede ürünü ziyaret eden kullanıcılara bağlantı hızlarına göre farklı deneyimler sunabilirsiniz. Örneğin görsellerin kalitesini erişim tipine göre artırmak-azaltmak gibi farklı deneyimler geliştirebilirsiniz.

Web performans metriklerinin ölçülmesiyle ilgili geçen yıl bir konferansta konuşma yapmıştım. Bu konuşmamda Web Vitals metriklerinin neden önemli olduğu, nasıl iyileştirilebileceği ve nasıl takip edileceğiyle ilgili bazı bilgiler vermiştim. Yazının sonundan ilgili videoyu izlemenizi tavsiye ederim. Çünkü birçok geliştirici bu metrikleri gözlemlerken yanlış stratejiler izliyor ve nihayetinde elde edilen şey ekipleri tatmin etmiyor. Bu nedenle ziyaretçilerinizi analiz etmeniz gerektiğinin altını tekrar çiziyorum.

Performans metriklerinizin kontrolünü CI/CD süreçlerinize entegre edin

Yapılan performans iyileştirmelerinin zamanla daha kötüye gitme eğilimi gösterdiğini hepimiz biliyoruz. Bunun birçok nedeni bulunuyor. Hızlı feature delivery, yapılan geliştirmenin etkilerinin geliştiriciler tarafından öngörülememiş olması, kullanılan kütüphanenin negatif etkileri gibi birçok konu performan düşüşüne neden olabilir.

lighthouse ci

Performans skorlarınızın denetimini CI/CD süreçlerinize entegre ederek son kullanıcı ile buluşturacağınız her geliştirmenin performansınızı etkileyip etkilemediğinden emin olabilirsiniz. Geliştirici ekiplerinin yoğun gündemi, son kullanıcıya ulaştırması gereken değişikler ve sıkışık teslimat tarihleri uygulama performansınızda zaman ve maliyet açısından telafisi zor sorunlara yol açabilir.

Gerçek zamanlı performans takibi yapın

Yaptığınız bir geliştirmenin performansa olan etkileri zamanla ortaya çıkabilir. Yazdığınız kodlardan kaynaklı olmayan farklı dış etkenler de performans metriklerinizi olumsuz yönde etkileyebilir. Performansın anlık seyrini izleyebilmek ve metriklerimizin kabul edilebilir oranların altına indiği durumlarda haberdar olmak adına uyarı mekanizmasına sahip olmak bu nedenle çok önemlidir. Sentry gibi araçlarla gerçek zamanlı web performansınızı izleyebililir, kendi metriklerinizi oluşturarak yine gerçek zamanlı olarak takip edebilirsiniz.

sentry - real time peformance monitoring

Elbette Sentry gibi araçlar kullanmak yerine daha farklı çözümler kullanabilirsiniz. Ben geliştirdiğim web uygulamalarında ssr render süresi dahil diğer birçok performans metriğini toplayıp bir time series database’e (prometheus gibi) yazıyorum ve verileri görselleştirmek için Grafana kullanıyorum. Diğer bir alternatif yöntem ise toplanan metrikleri Google Analytics üzerinde depolamak ve görselleştirmek olabilir. Uygulamanızın takip etmek isteyebileceğiniz farklı metriklerini toplamak, kaydetmek ve görselleştirmek oldukça hayati öneme sahip. Herhangi bir problemle karşılaştığınızda problemi analiz etmek için ilk bakacağınız ekranlar burası. 🧐

En yakın arkadaşınız “Loglar”

Performans problemlerinin ve daha birçok farklı problemin analizini yaparken ilk başvurduğumuz yer log takibi yaptığımız ekranlardır. Elbette log yönetimini doğru yapmak, gerekli olmayan, hassas verileri işlememek önemlidir. Uygulama üzerinde doğru bir log mekanizması inşaa edilmesi saatlerce debugging yapmanızı engelleyebilir.

Temel amacımız runtime’da olup biteni kayıt altına almak. Logları kaydetmek için ve üzerinde hızlı analizler yapabilmek için Logstash, Splunk veya Datadog gibi araçlardan faydalanıyoruz. Bu araçları seçerken bazı kriterleri göz önünde bulundurmamız gerekiyor. Bu tarz araçlardan ilk beklentilerimiz arama deneyiminin ve hızının mükemmel olması, detaylı analytics verileri sunması, on-prem bir araç değilse fiyatlandırma, ölçeklenebilirlik ve güvenlik gibi temel konular olmalı.

Ön yüz uygulamalarında log oluşturmak için ilk akla console.log(); metodunun geldiğini biliyorum ancak bunun bazı performans sorunlarına yol açtığını kendi deneyimlerimle de tecrübe ettim. Winston ve Morgan kütüphanelerini birlikte kullanarak daha işlevsel ve performanslı şekilde loglarınızı oluşturabilirsiniz.

Maalesef tamamen ön yüz uygulamasına dönüşmüş birçok üründe hata yönetimi ve loglama yeterince üstünde düşünülen ve pratiğe dökülen bir konu değil. Bu nedenle geliştiricilerin saatlerce kodları adeta kazıyarak problem tespit etmeye çalıştığına şahit oldum. En iyi pratikleri öğrenmeniz ve uygulamanız, yaşayabileceğiniz problemlerde size fazlasıyla yardımcı olur. Daha fazla detay için yazının sonunda New Relic tarafından yayınlanan bir white paper’ı ekledim.

Memory Leak problemlerini nasıl tespit edebileceğinizi öğrenin

Bir önceki yazıda JavaScript’te memory leak konusuna değinmiştik. Memory leak’i tespit etmek bazen kolay bazense oldukça zor olabiliyor. Öncelikle V8 engine’in belleği nasıl yönettiğini anlamamız, ardından yazdığımız kodu bu perspektiften yorumlamamız gerekiyor. Normal koşullarda GC’nin bu durumu çözmesi gerektiğini düşünürüz ancak GC(garbage collection), memory leak’i tamamen çözemez çünkü çalışma prensibi gereği kullanımda olmadığını bildiği şeyleri çöp olarak toplar. Yani bir nesnenin başka bir nesneye referansı olup olmadığına bakar ve referansı olmayan nesneleri çöp olarak toplar. Elbette GC’nin tüm bu süreçte ki ek kaynak tüketimini de unutmamak gerekli.

instana profiler

Bir memory leak meydana geldiğinden şüpheleniyorsanız heapdump gibi bir araçla heap snapshot’ını alıp Chrome DevTools ile analize başlayabilirsiniz. İçinizden production ortamında nasıl yapabiliriz gibi güzel bir soru geçiyor olabilir. Instana gibi bazı monitoring araçları platforma özel sundukları profiler ile production ortamından anlık snapshot almanızı sağlayabilir. Ancak bu metriklerin gerçek zamanlı toplanması, uygulamanız üzerinde önemli miktarda latency artışına neden olacağı için kısa süreli kullanımlar dışında önemli bir dezavantaj yaratacaktır.

Memory Leak tespitinde faydalanabileceğimiz, benim de kullandığım bir araç olan Clinic.js oldukça kullanışlı bir seçenek. AutoCannon’la biraz HTTP trafiği simüle edip yük altında heap snapshot’ı alabilirsiniz ve bu çıktı üzerinde detaylı incelemelerinizi yapabilirsiniz.

clinic heap profiler

Clinic.js’in birkaç farklı özelliği daha var. Node.js performans problemlerini incelerken size fazlasıyla yardımcı olacak bir araç. Tabi ben yine de Chrome DevTools’u detaylı analizler ve debugging için nasıl daha etkin kullanabileceğinizi öğrenmeniz gerektiğini düşünüyorum.

Node paketlerinin kontrolsüz geçişine dikkat

Kullandığımız kütüphanelerin popülerliği ve sundukları harika özellikler bazen göz alıcı olabiliyor. Ancak çok az kişi kullandığı kütüphanenin dokümantasyonunu detaylıca inceliyor ve çalışma şeklini kavrayıp eksik olduğu noktaları bilerek kullanıyor.

You shall not, PASS!

JavaScript uygulamalarının günümüzdeki gerçekliği bizi sayısız node paketiyle uğraşmaya itiyor. Tam olarak ne yaptığını bilmediğimiz uzaktan bakınca pek de zararlı görünmeyen yüzlerce mikro organizma gibiler adeta. Böyle bir gerçeklikte güvenlik, performans gibi kaygıların ortaya çıkması da gayet olası. CI/CD süreçlerimize mutlaka snyk gibi bir ürünü güvenlik kaygılarımızı gidermek adına dahil etmemiz gerekli.

Üzerinde çalıştığımız ürünlere node paketlerini dahil ederken daha bilinçli hareket etmeli, gerçekten ihtiyacımız olup olmadığını değerlendirmeli ve mutlaka paketin arka planda tam olarak ne yaptığını anlamamız gerekli.

--

--

Oğuz Kılıç

developer @trendyol, ex @eBay, sci-fi addict. JavaScript, Frontend, Software Architecture