JavaScript'e daha fazla dayalı siteler oluştururken bazen gönderdiğimiz verilerin bedelini her zaman kolayca göremeyeceğimiz şekillerde öderiz. Bu makalede, sitenizin mobil cihazlarda hızlı bir şekilde yüklenmesini ve etkileşimli olmasını istiyorsanız biraz disiplinin neden yardımcı olabileceğini ele alacağız. Daha az JavaScript yayınlamak, ağ aktarımında daha az zaman harcanması, kodun sıkıştırmasını açmak için daha az zaman harcanması ve bu JavaScript'i ayrıştırmak ve derlemek için daha az zaman harcanması anlamına gelebilir.
Ağ
Çoğu geliştirici, JavaScript'in maliyetini indirme ve yürütme maliyeti açısından değerlendirir. Kullanıcının bağlantısı ne kadar yavaşsa ağ üzerinden daha fazla bayt JavaScript göndermek o kadar uzun sürer.

Kullanıcının sahip olduğu etkin ağ bağlantısı türü aslında 3G, 4G veya kablosuz bağlantı olmayabileceğinden bu durum sorun teşkil edebilir. Bir kafenin kablosuz ağına bağlı olabilirsiniz ancak 2G hızında bir hücresel hotspot'a bağlı olabilirsiniz.
JavaScript'in ağ aktarım maliyetini şu yöntemlerle azaltabilirsiniz:
- Yalnızca kullanıcının ihtiyaç duyduğu kodu gönderme.
- JavaScript'inizi kritik olan ve olmayan bölümlere ayırmak için kod bölme işlemini kullanın. webpack gibi modül paketleyiciler, kod bölmeyi destekler.
- Kritik olmayan kodları geç yükleme.
- Sadeleştirme
- ES5 kodunu küçültmek için UglifyJS'yi kullanın.
- ES2015+'i sadeleştirmek için babel-minify veya uglify-es kullanın.
- Sıkıştırma
- Metne dayalı kaynakları sıkıştırmak için en azından gzip kullanın.
- Brotli kullanmayı düşünün ~q11. Brotli, sıkıştırma oranı açısından gzip'ten daha iyi performans gösterir. CertSimple'ın sıkıştırılmış JS baytlarının boyutunda %17, LinkedIn'in ise yükleme sürelerinde %4 tasarruf etmesine yardımcı oldu.
- Kullanılmayan kodları kaldırma.
- Geliştirici Araçları kod kapsamı ile kaldırılabilecek veya geç yüklenebilecek kod fırsatlarını belirleyin.
- Modern tarayıcılarda bulunan özellikleri çevirmemek için babel-preset-env ve browserlist kullanın. İleri düzey geliştiriciler, webpack paketlerini dikkatli bir şekilde analiz etmenin gereksiz bağımlılıkları azaltma fırsatlarını belirlemeye yardımcı olduğunu görebilir.
- Kod ayıklama için tree-shaking, Closure Compiler'ın gelişmiş optimizasyonları ve Moment.js gibi kitaplıklar için lodash-babel-plugin veya webpack'in ContextReplacementPlugin gibi kitaplık kırpma eklentilerine bakın.
- Ağ gezilerini en aza indirmek için kodu önbelleğe alma
- Tarayıcıların yanıtları etkili bir şekilde önbelleğe almasını sağlamak için HTTP önbelleğe alma özelliğini kullanın. Değişmeyen baytların aktarılmasını önlemek için komut dosyaları için en uygun kullanım ömürlerini (max-age) belirleyin ve doğrulama jetonları (ETag) sağlayın.
- Servis çalışanı önbelleğe alma, uygulama ağınızı dayanıklı hale getirebilir ve V8'in kod önbelleği gibi özelliklere hızlı erişim sağlar.
- Değişmeyen kaynakları yeniden getirmek zorunda kalmamak için uzun süreli önbelleğe almayı kullanın. Webpack kullanıyorsanız dosya adı karma oluşturma bölümüne bakın.
Ayrıştırma/derleme
İndirildikten sonra JavaScript'in en ağır maliyetlerinden biri, JS motorunun bu kodu ayrıştırması/derlemesi için gereken süredir. Chrome Geliştirici Araçları'nda ayrıştırma ve derleme, Performans panelindeki sarı renkli "Komut dosyası oluşturma" süresinin bir parçasıdır.

Aşağıdan Yukarıya ve Çağrı Ağacı sekmeleri, tam ayrıştırma/derleme sürelerini gösterir:
Peki, bu neden önemli?

Kod ayrıştırma/derleme işleminin uzun sürmesi, kullanıcının sitenizle etkileşime geçebilme süresini önemli ölçüde geciktirebilir. Ne kadar çok JavaScript gönderirseniz siteniz etkileşimli hale gelmeden önce ayrıştırılması ve derlenmesi o kadar uzun sürer.
Bayt bazında, JavaScript'in tarayıcı tarafından işlenmesi, eşdeğer boyuttaki resim veya web yazı tipine göre daha maliyetlidir - Tom Dale
JavaScript ile karşılaştırıldığında, eşdeğer boyuttaki resimlerin işlenmesiyle ilgili çok sayıda maliyet vardır (bunların yine de kodu çözülmelidir). Ancak ortalama mobil donanımda JS'nin bir sayfanın etkileşimini olumsuz etkileme olasılığı daha yüksektir.
Ayrıştırma ve derlemenin yavaş olduğunu söylerken bağlam önemlidir. Burada ortalama cep telefonlarından bahsediyoruz. Ortalama kullanıcıların telefonlarında CPU ve GPU'lar yavaş olabilir, L2/L3 önbelleği bulunmayabilir ve hatta bellek kısıtlaması olabilir.
Ağ özellikleri ve cihaz özellikleri her zaman eşleşmez. Mükemmel bir fiber bağlantıya sahip bir kullanıcının cihazına gönderilen JavaScript'i ayrıştırıp değerlendirmek için en iyi CPU'ya sahip olması gerekmez. Bunun tersi de geçerlidir. Ağ bağlantısı çok kötü ama CPU çok hızlı olabilir. — Kristofer Baxter, LinkedIn
Aşağıda, düşük ve yüksek kaliteli donanımlarda yaklaşık 1 MB sıkıştırılmamış (basit) JavaScript'i ayrıştırmanın maliyetini görebiliriz. Piyasadaki en hızlı telefonlar ile ortalama telefonlar arasında kodu ayrıştırma/derleme süresi açısından 2-5 kat fark vardır.
CNN.com gibi gerçek bir siteye ne dersiniz?
Üst düzey iPhone 8'de CNN'in JS'sini ayrıştırmak/derlemek yalnızca yaklaşık 4 saniye sürerken ortalama bir telefonda (Moto G4) bu süre yaklaşık 13 saniyedir. Bu durum, kullanıcının bu siteyle tam olarak etkileşime geçme hızını önemli ölçüde etkileyebilir.
Bu durum, yalnızca cebinizdeki telefon yerine ortalama donanımlarda (Moto G4 gibi) test yapmanın önemini vurgular. Ancak bağlam önemlidir: Kullanıcılarınızın cihaz ve ağ koşullarına göre optimizasyon yapın.
Gerçekten çok fazla JavaScript mi gönderiyoruz? Err, possibly :)
Mobil cihazlarda JavaScript'in durumunu analiz etmek için HTTP Arşivi'ni (en popüler yaklaşık 500 bin site) kullandığımızda, sitelerin %50'sinin etkileşimli hale gelmesinin 14 saniyeden uzun sürdüğünü görüyoruz. Bu siteler yalnızca JS'yi ayrıştırmak ve derlemek için 4 saniyeye kadar zaman harcar.

JS ve diğer kaynakları getirip işlemek için gereken süreyi de hesaba kattığınızda, kullanıcıların sayfaların kullanıma hazır olduğunu hissetmeden önce bir süre beklemek zorunda kalması şaşırtıcı olmayabilir. Bu konuda kesinlikle daha iyisini yapabiliriz.
Kritik olmayan JavaScript'leri sayfalarınızdan kaldırmak, aktarım sürelerini, CPU yoğun ayrıştırma ve derleme işlemlerini ve olası bellek ek yükünü azaltabilir. Bu, sayfalarınızın daha hızlı etkileşimli hale gelmesine de yardımcı olur.
Yürütme süresi
Maliyeti olan tek şey ayrıştırma ve derleme değildir. JavaScript yürütme (ayrıştırıldıktan/derlendikten sonra kodun çalıştırılması), ana iş parçacığında gerçekleşmesi gereken işlemlerden biridir. Uzun yürütme süreleri, kullanıcının sitenizle etkileşime geçebileceği süreyi de uzatabilir.

Komut dosyasının yürütülmesi 50 ms'den uzun sürerse etkileşime hazır olma süresi, JS'nin indirilmesi, derlenmesi ve yürütülmesi için gereken sürenin tamamı kadar gecikir. Alex Russell
Bu sorunu çözmek için JavaScript, ana iş parçacığının kilitlenmesini önlemek amacıyla küçük parçalar halinde olmaktan yararlanır. Yürütme sırasında yapılan iş miktarını azaltıp azaltamayacağınızı araştırın.
Diğer maliyetler
JavaScript, sayfa performansını başka şekillerde de etkileyebilir:
- Bellek. Sayfalar, GC (çöp toplama) nedeniyle sık sık takılabilir veya duraklayabilir. Bir tarayıcı bellek geri aldığında JS yürütme duraklatılır. Bu nedenle, sık sık çöp toplayan bir tarayıcı, yürütmeyi istediğimizden daha sık duraklatabilir. Sayfaların takılmasını önlemek için bellek sızıntılarından ve sık sık yapılan gc duraklatmalarından kaçının.
- Çalışma zamanında, uzun süre çalışan JavaScript, ana iş parçacığını engelleyerek sayfaların yanıt vermemesine neden olabilir. İşi daha küçük parçalara bölmek (planlama için
requestAnimationFrame()veyarequestIdleCallback()kullanarak) duyarlılık sorunlarını en aza indirebilir ve Interaction to Next Paint (INP) metriğini iyileştirebilir.
JavaScript yayınlama maliyetini azaltma kalıpları
JavaScript için ayrıştırma/derleme ve ağ aktarım sürelerini düşük tutmaya çalışırken rotaya dayalı parçalama veya PRPL gibi yardımcı olabilecek kalıplar vardır.
PRPL
PRPL (Push, Render, Pre-cache, Lazy-load), agresif kod bölme ve önbelleğe alma yoluyla etkileşimi optimize eden bir kalıptır:

Bu özelliğin etkisini görselleştirelim.
V8'in Çalışma Zamanı Çağrı İstatistikleri'ni kullanarak popüler mobil sitelerin ve Progresif Web Uygulamalarının yükleme süresini analiz ediyoruz. Gördüğünüz gibi, ayrıştırma süresi (turuncu renkle gösterilir) bu sitelerin çoğunun zaman harcadığı önemli bir bölümdür:

PRPL kullanan bir site olan Wego, rotaları için düşük bir ayrıştırma süresi sağlayarak çok hızlı bir şekilde etkileşimli hale geliyor. Yukarıdaki diğer sitelerin çoğu, JS maliyetlerini düşürmek için kod bölme ve performans bütçelerini benimsedi.
Aşamalı önyükleme
Birçok site, etkileşim pahasına içerik görünürlüğünü optimize eder. Büyük JavaScript paketleriniz olduğunda hızlı bir ilk boyama elde etmek için geliştiriciler bazen sunucu tarafı oluşturma kullanır, ardından JavaScript nihayet getirildiğinde etkinlik işleyicileri eklemek için bunu "yükseltir".
Dikkatli olun. Bu yöntemin de kendi maliyetleri vardır. 1) Genellikle etkileşimimizi zorlayabilecek daha büyük bir HTML yanıtı gönderirsiniz, 2) kullanıcıyı, JavaScript işlemi tamamlanana kadar deneyimin yarısının etkileşimli olamayacağı tekinsiz bir vadide bırakabilirsiniz.
Aşamalı önyükleme daha iyi bir yaklaşım olabilir. Minimum düzeyde işlevsel bir sayfa (yalnızca mevcut rota için gereken HTML/JS/CSS'den oluşur) gönderin. Daha fazla kaynak geldikçe uygulama, daha fazla özelliğin geç yüklenmesini ve kilidini açabilir.
Görünümde olanla orantılı olarak kod yüklemek en ideal yöntemdir. PRPL ve Kademeli Önyükleme, bunu başarmanıza yardımcı olabilecek kalıplardır.
Sonuçlar
İletim boyutu, düşük kaliteli ağlar için çok önemlidir. Ayrıştırma süresi, CPU'ya bağlı cihazlar için önemlidir. Bu değerlerin düşük olması önemlidir.
Ekipler, JavaScript aktarım ve ayrıştırma/derleme sürelerini düşük tutmak için katı performans bütçeleri uygulayarak başarıya ulaştı. Alex Russell'ın "Can You Afford It?: Real-world Web Performance Budgets" başlıklı makaleyi inceleyin.
Mobil cihazları hedefleyen bir site oluşturuyorsanız temsili donanım üzerinde geliştirme yapmaya, JavaScript ayrıştırma/derleme sürelerinizi düşük tutmaya ve ekibinizin JavaScript maliyetlerini takip edebilmesi için bir performans bütçesi benimsemeye özen gösterin.
Daha fazla bilgi
- Chrome Dev Summit 2017 - Modern Yükleme İçin En İyi Uygulamalar
- JavaScript Başlangıç Performansı
- Solving the web performance crisis — Nolan Lawson
- Bütçeniz buna uygun mu? Gerçek dünyadaki performans bütçeleri — Alex Russell
- Web çerçevelerini ve kitaplıklarını değerlendirme — Kristofer Baxter
- Cloudflare'in sıkıştırma için Brotli ile deneme sonuçları (Daha yüksek kalitede dinamik Brotli'nin ilk sayfa oluşturmayı geciktirebileceğini unutmayın. Bu nedenle dikkatli bir şekilde değerlendirin. Bunun yerine statik olarak sıkıştırmanız daha iyi olabilir.)
- Performance Futures — Sam Saccone