JavaScript'e daha fazla bağımlı siteler oluştururken bazen gönderdiğimiz veriler için her zaman kolayca göremediğimiz şekillerde ödeme yaparız. Bu makalede, sitenizin mobil cihazlarda hızlı bir şekilde yüklenmesini ve etkileşimli olmasını istiyorsanız biraz disiplin uygulamanın neden yararlı olabileceğini ele alacağız. Daha az JavaScript yayınlamak, ağ aktarımında daha az süre, kodun sıkıştırmasını kaldırmak için daha az süre ve bu JavaScript'i ayrıştırmak ve derlemek için daha az süre anlamına gelebilir.
Ağ
Çoğu geliştirici, JavaScript'in maliyetini indirme ve yürütme maliyeti açısından düşünür. Kullanıcının bağlantısı ne kadar yavaşsa ağ üzerinden daha fazla JavaScript baytı göndermek o kadar uzun sürer.
Kullanıcının etkin ağ bağlantısı türü aslında 3G, 4G veya kablosuz bağlantı olmayabilir. Bu nedenle bu durum sorun oluşturabilir. Bir kafenin kablosuz ağına bağlıyken 2G hızında bir hücresel hotspot'a bağlanmış olabilirsiniz.
JavaScript'in ağ aktarım maliyetini aşağıdaki yöntemlerle azaltabilirsiniz:
- Yalnızca kullanıcının ihtiyaç duyduğu kodu gönderin.
- Sadeleştirme
- ES5 kodunu küçültmek için UglifyJS'i kullanın.
- ES2015 ve sonraki sürümleri küçültmek için babel-minify veya uglify-es kullanın.
- Sıkıştırma
- Kullanılmayan kodları kaldırma.
- Geliştirici Araçları kod kapsamını kullanarak kaldırılabilecek veya yavaşça yüklenebilecek kod fırsatlarını belirleyin.
- Modern tarayıcılarda zaten bulunan özellikleri derlemekten kaçınmak için babel-preset-env ve browserlist'i kullanın. İleri düzey geliştiriciler, webpack paketlerinin dikkatli bir şekilde analiz edilmesinin gereksiz bağımlılıkları azaltma fırsatlarını belirlemeye yardımcı olduğunu görebilir.
- Kodu çıkarmak için ağaç sallama, Closure Compiler'ın gelişmiş optimizasyonları ve lodash-babel-plugin gibi kitaplık çıkarma eklentileri veya Moment.js gibi kitaplıklar için webpack'ın ContextReplacementPlugin eklentilerine bakın.
- Ağ gezilerini en aza indirmek için kodu önbelleğe alma
- Tarayıcılarda yanıtların etkili bir şekilde önbelleğe alınması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 optimum geçerlilik sürelerini (max-age) belirleyin ve doğrulama jetonları (ETag) sağlayın.
- Hizmet çalışanı önbelleğe alma, uygulama ağınızın dayanıklı olmasını sağlayabilir ve V8'in kod önbelleği gibi özelliklere hızlı erişim sağlayabilir.
- Değişmeyen kaynakları yeniden getirme zorunluluğunu önlemek için uzun süreli önbelleğe alma özelliğini kullanın. Webpack kullanıyorsanız dosya adı karma oluşturma bölümüne bakın.
Ayrıştırma/Derleme
İndirilen JavaScript'in en ağır maliyetlerinden biri, JS motorunun bu kodu ayrıştırması/derlemesi için harcadığı zamandır. Chrome Geliştirici Araçları'nda ayrıştırma ve derleme, Performans panelindeki sarı "Komut Dosyası Yazma" süresinin bir parçasıdır.
Aşağıdan Yukarı ve Çağrı Ağacı sekmeleri, tam ayrıştırma/derleme zamanlarını gösterir:

Peki bu neden önemli?
Kodu ayrıştırmak/derlemek için çok fazla zaman harcamak, kullanıcının sitenizle ne kadar sürede etkileşime geçebileceğini önemli ölçüde geciktirebilir. Ne kadar fazla JavaScript gönderirseniz sitenizin etkileşimli hale gelmesi için bu JavaScript'in ayrıştırılması ve derlenmesi o kadar uzun sürer.
Bayt bazında, JavaScript'in tarayıcının işlemesi, eşdeğer boyutta bir resim veya web yazı tipinden daha pahalıdır. — Tom Dale
JavaScript'e kıyasla, eşdeğer boyutlu resimlerin işlenmesiyle ilgili birçok maliyet vardır (bu resimlerin kodunun çözülmesi gerekir). Ancak ortalama mobil donanımlarda JS'nin bir sayfanın etkileşimini olumsuz yönde etkileme olasılığı daha yüksektir.

Ayrıştırma ve derlemenin yavaş olmasından bahsederken bağlam önemlidir. Burada ortalama mobil telefonlardan bahsediyoruz. Ortalama kullanıcıların telefonlarında yavaş CPU ve GPU'lar, L2/L3 önbelleği olmayabilir ve hatta bellek sınırlaması olabilir.
Ağ özellikleri ve cihaz özellikleri her zaman eşleşmez. Mükemmel bir Fiber bağlantısı olan bir kullanıcının, cihazına gönderilen JavaScript'i ayrıştırmak ve değerlendirmek için en iyi CPU'ya sahip olması gerekmez. Bu durum tam tersi durumda da geçerlidir. Örneğin, ağ bağlantısı kötüyken 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örebilirsiniz. Piyasanın en hızlı telefonları ile ortalama telefonlar arasında kodu ayrıştırma/derleme süresinde 2-5 kat fark vardır.

CNN.com gibi gerçek dünyadaki siteler için ne yapmalıyız?
CNN'nin JS'sini ayrıştırmak/derlemek, üst düzey iPhone 8'de ortalama bir telefonda (Moto G4) yaklaşık 13 saniye sürdüğü hâlde yaklaşık 4 saniye sürer. Bu durum, kullanıcının bu siteyle ne kadar hızlı etkileşim kurabileceğini önemli ölçüde etkileyebilir.

Bu durum, yalnızca cebinizdeki telefon yerine ortalama donanımda (Moto G4 gibi) test yapmanın önemini vurgular. Ancak bağlam önemlidir: Kullanıcılarınızın sahip olduğu cihaz ve ağ koşullarına göre optimizasyon yapın.

Gerçekten çok fazla JavaScript gönderiyor muyuz? Evet, olabilir :)
Mobil cihazlarda JavaScript'in durumunu analiz etmek için HTTP Arşivi'ni (ilk 500.000 site) kullandığımızda, sitelerin% 50'sinde etkileşimli hale gelmenin 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ın getirilmesi ve işlenmesi için gereken süreyi hesaba katarsanız kullanıcıların sayfaların kullanıma hazır olduğunu hissetmeden önce bir süre beklemesi şaşırtıcı değildir. Bu konuda daha iyisini yapabiliriz.
Kritik olmayan JavaScript'i sayfalarınızdan kaldırmak, aktarım sürelerini, CPU'ya yoğun ayrıştırma ve derleme işlemlerini ve olası bellek yükü maliyetlerini azaltabilir. Bu, sayfalarınızın daha hızlı bir şekilde etkileşimli hale gelmesine de yardımcı olur.
Yürütme süresi
Maliyete neden olabilecek işlemler yalnızca ayrıştırma ve derleme değildir. JavaScript yürütme (ayrıştırılan/derlenen kodu çalıştırma), ana iş parçacığında yapılması gereken işlemlerden biridir. Uzun yürütme süreleri, kullanıcıların sitenizle ne kadar sürede etkileşime geçebileceğini de etkileyebilir.
Komut dosyası 50 ms'den uzun süre boyunca yürütülürse etkileşime hazır olma süresi, JS'nin indirilmesi, derlenmesi ve yürütülmesi için gereken sürenin tamamı kadar geciktirilir. — Alex Russell
JavaScript, bu sorunu gidermek için ana iş parçacığının kilitlenmesini önlemek amacıyla küçük parçalara ayrılır. Yürütme sırasında ne kadar iş yapıldığını azaltıp azaltamayacağınızı inceleyin.
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 duraklatılabilir. Bir tarayıcı belleği 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ılmamasını sağlamak için bellek sızıntılarından ve sık sık gerçekleşen gc duraklatmalarından kaçının.
- Uzun süre çalışan JavaScript, çalışma zamanında ana ileti dizisini engelleyerek sayfaların yanıt vermemesi sorununa yol açabilir. İşi daha küçük parçalara bölmek (planlama için
requestAnimationFrame()
veyarequestIdleCallback()
kullanarak), Interaction to Next Paint (INP) metriğini iyileştirmeye yardımcı olabilecek duyarlılık sorunlarını en aza indirebilir.
JavaScript yayınlama maliyetini azaltma modelleri
JavaScript için ayrıştırma/derleme ve ağ aktarma sürelerini yavaş tutmaya çalışırken rota tabanlı parçalara ayırma 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şim için optimize eden bir modeldir:
Bunun ne gibi etkileri olabileceğini görselleştirelim.
V8'in Çalışma Zamanı Çağrı İstatistikleri'ni kullanarak popüler mobil sitelerin ve Progressive Web Uygulamalarının yükleme süresini analiz ederiz. Gördüğümüz gibi, ayrıştırma süresi (turuncuyla gösterilir) bu sitelerin çoğunun zamanının önemli bir kısmını oluşturur:
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şime geçiyor. 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şimi göz ardı ederek 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şturmayı kullanır ve ardından JavaScript nihayet getirildiğinde etkinlik işleyicileri eklemek için "yükseltir".
Bu yöntemin kendi maliyetleri olduğunu unutmayın. 1) Genellikle etkileşimimizi artırabilecek daha büyük bir HTML yanıtı gönderirsiniz, 2) JavaScript işlemeyi tamamlayana kadar deneyimin yarısının aslında etkileşimli olamayacağı tuhaf bir durumda kullanıcıyı bırakabilirsiniz.
Kademeli Bootstrapping daha iyi bir yaklaşım olabilir. Minimum işlevsellik içeren bir sayfa gönderin (yalnızca geçerli rota için gereken HTML/JS/CSS'den oluşur). Daha fazla kaynak geldikçe uygulama, daha fazla özelliği yavaşça yükleyebilir ve daha fazla özelliğin kilidini açabilir.

Görüntülenen içeriğe orantılı kod yükleme, en önemli hedeftir. PRPL ve Progressive Bootstrapping, bu hedefe ulaşmanıza yardımcı olabilecek kalıplardır.
Sonuçlar
İletim boyutu, düşük kaliteli ağlar için kritik öneme sahiptir. Ayıklama süresi, CPU'ya bağlı cihazlar için önemlidir. Bu değerleri düşük tutmak ö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ılı oldu. Alex Russell'ın "Can You Afford It?: Gerçek Dünyada Web Performansı Bütçeleri" başlıklı makaleyi inceleyin.

Mobil cihazları hedefleyen bir site oluşturuyorsanız temsili donanımlarda geliştirme yapmak için elinizden geleni yapın, JavaScript ayrıştırma/derleme sürelerinizi düşük tutun ve ekibinizin JavaScript maliyetlerini takip edebilmesini sağlamak için bir Performans Bütçesi'ni benimseyin.
Daha Fazla Bilgi
- Chrome Geliştirici Zirvesi 2017 - Modern Yüklemeyle İlgili En İyi Uygulamalar
- JavaScript Başlangıç Performansı
- Web performansı krizini çözme — Nolan Lawson
- Bunu karşılayabilir misiniz? Gerçek dünyadaki performans bütçeleri — Alex Russell
- Web çerçevelerini ve kitaplıklarını değerlendirme — Kristofer Baxter
- Sıkıştırma için Cloudflare'ın 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ırmak isteyebilirsiniz.)
- Performans Geleceği — Sam Saccone