JavaScript Başlangıç Optimizasyonu

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.

Ç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.

Bir tarayıcı kaynak istediğinde, bu kaynağın getirilmesi ve ardından sıkıştırmasının kaldırılması gerekir. JavaScript gibi kaynaklar, yürütülmeden önce ayrıştırılmalı ve derlenmelidir.

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.
    • JavaScript'inizi kritik ve kritik olmayan bölümlere ayırmak için kod bölme özelliğini kullanın. Webpack gibi modül birleştirme araçları kod bölme özelliğini destekler.
    • Kritik olmayan kodun geç yüklenmesi.
  • Sadeleştirme
  • Sıkıştırma
    • Metne dayalı kaynakları sıkıştırmak için en azından gzip kullanın.
    • Brotli ~q11 kullanmayı düşünün. Brotli, sıkıştırma oranı açısından gzip'ten daha iyi performans gösterir. Bu sayede CertSimple, sıkıştırılmış JS baytlarının boyutunda %17, LinkedIn ise yükleme sürelerinde %4 tasarruf sağladı.
  • Kullanılmayan kodları kaldırma.
  • 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.

ALT_TEXT_HERE

Aşağıdan Yukarı ve Çağrı Ağacı sekmeleri, tam ayrıştırma/derleme zamanlarını gösterir:

ALT_TEXT_HERE
Chrome DevTools Performans paneli > Alttan Yukarıya. V8'in Çalışma Zamanı Çağrı İstatistikleri etkinleştirildiğinde, Ayıklama ve Derleme gibi aşamalarda harcanan süreyi görebiliriz

Peki bu neden önemli?

ALT_TEXT_HERE

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.

ALT_TEXT_HERE
JavaScript ve resim baytlarının maliyetleri çok farklıdır. Görüntüler genellikle kod çözme ve rasterleştirme sırasında ana iş parçacığının engellenmesine veya arayüzlerin etkileşimli hale gelmesine engel olmaz. Ancak JS, ayrıştırma, derleme ve yürütme maliyetleri nedeniyle etkileşimi geciktirebilir.

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.

ALT_TEXT_HERE
Bu grafikte, farklı sınıflardaki masaüstü ve mobil cihazlarda 1 MB'lık bir JavaScript paketinin (~250 KB sıkıştırılmış) ayrıştırma süreleri vurgulanmaktadır. Ayrıştırma maliyetine bakıldığında, sıkıştırılmış verilerden elde edilen değerler dikkate alınır.Örneğin, yaklaşık 250 KB sıkıştırılmış JS, yaklaşık 1 MB kod olarak sıkıştırılı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.

ALT_TEXT_HERE
Yukarıdaki ayrıştırma sürelerinde, Apple'ın A11 Bionic çipinin performansı, daha ortalama Android donanımındaki Snapdragon 617 ile karşılaştırılmıştır.

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.

ALT_TEXT_HERE
Google Analytics, gerçek kullanıcılarınızın sitenize hangi mobil cihaz sınıflarıyla eriştiği hakkında bilgi sağlayabilir. Bu sayede, kullandıkları gerçek CPU/GPU kısıtlamalarını anlama fırsatı elde edebilirler.

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.

ALT_TEXT_HERE

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.

ALT_TEXT_HERE

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() veya requestIdleCallback() 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:

ALT_TEXT_HERE

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:

ALT_TEXT_HERE

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.

ALT_TEXT_HERE
Paul Lewis tarafından yazılan Progressive Bootstrapping

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.

ALT_TEXT_HERE
Aldığımız mimari kararlar uygulama mantığı için bize ne kadar JS "başarı alanı" bırakabilir?

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