JavaScript Başlangıç Optimizasyonu

Addy Osmani
Addy Osmani

JavaScript'e daha fazla bağımlı olan siteler oluşturdukça, bazen gönderdiğimiz istekler için her zaman kolayca göremediğimiz şekillerde ödeme yaparız. Bu makalede, sitenizin mobil cihazlarda hızlı bir şekilde yüklenmesi ve etkileşimli olması için biraz disiplinin neden yardımcı olabileceğini ele alacağız. Daha az JavaScript sunulması ağ iletiminde daha az süre, kodda sıkıştırma açma için daha az zaman harcanması ve bu JavaScript'in ayrıştırılıp derlenmesi için daha az zaman anlamına gelebilir.

Çoğu geliştirici JavaScript'in maliyetini indirme ve yürütme maliyeti olarak değerlendirir. Kablo üzerinden daha fazla baytlık JavaScript göndermek, kullanıcının bağlantısı ne kadar yavaşsa o kadar uzun sürer.

Bir tarayıcı kaynak isteğinde bulunduğunda, söz konusu kaynağın getirilmesi ve ardından sıkıştırmasının açılması gerekir. JavaScript gibi kaynaklar söz konusu olduğunda, bunların çalıştırılmadan önce ayrıştırılması ve derlenmesi gerekir.

Kullanıcının etkili ağ bağlantısı türü aslında 3G, 4G veya Wi-Fi olmayabileceğinden bu bir sorun olabilir. Kahve dükkanındaki kablosuz ağa bağlıyken 2G hızlarında bir hücresel hotspot'a bağlı olabilirsiniz.

JavaScript'in ağ aktarım maliyetini aşağıdakiler aracılığıyla azaltabilirsiniz:

  • Yalnızca kullanıcının ihtiyaç duyduğu kodu gönderme.
    • JavaScript'inizi kritik ve önemsiz olarak bölümlere ayırmak için kod bölme özelliğini kullanın. Webpack gibi modül paketleyiciler kod bölmeyi destekler.
    • Kritik olmayan kodu geç yükleme.
  • Küçültme
  • Sıkıştırma
    • Metin tabanlı 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ında gzip'ten daha iyi performans gösterir. Bu çözüm, CertSimple'ın sıkıştırılmış JS baytları boyutundan %17 tasarruf etmesine ve LinkedIn'in yükleme sürelerinde %4 tasarruf etmesine yardımcı oldu.
  • Kullanılmayan kodları kaldırma
  • Ağ seyahatlerini en aza indirmek için önbelleğe alma kodu.
    • Tarayıcıların yanıtları etkili bir şekilde önbelleğe almasını sağlamak için HTTP önbelleğe almayı kullanın. Değişmeyen baytların aktarılmasını önlemek için komut dosyaları (max-age) ve doğrulama jetonları (ETag) için en uygun ömürleri belirleyin.
    • Service Worker önbelleğe alma işlemi, uygulama ağınızı dayanıklı hale getirebilir ve V8'in kod önbelleği gibi özelliklere istekli erişim sağlayabilir.
    • Değiştirilmemiş kaynakları yeniden getirmek zorunda kalmamak için uzun süreli önbelleğe alma özelliğini kullanın. Webpack kullanıyorsanız dosya adı karma oluşturma bölümünü inceleyin.

Ayrıştır/Derle

İndirildikten sonra, JavaScript’in en ağır maliyetlerinden biri, JS motorunun bu kodu ayrıştırması/derlemesi için geçen süredir. Chrome Geliştirici Araçları'ndaki ayrıştırma ve derleme, Performans panelindeki sarı renkli "Komut Dosyası" süresinin bir parçasıdır.

ALT_TEXT_HERE

Aşağıdan Yukarıya ve Çağrı Ağacı sekmeleri, tam olarak Ayrıştırma/derleme zamanlamalarını gösterir:

ALT_TEXT_HERE
Chrome DevTools Performans paneli > Aşağıdan Yukarıya gidin. V8’in Çalışma Zamanı Arama İstatistikleri etkin durumdayken, Ayrıştırma ve Derleme gibi aşamalarda harcanan zamanı görebiliriz.

Peki, bu neden önemlidir?

ALT_TEXT_HERE

Kodu ayrıştırmak/derlemek için uzun bir süre harcamak, bir kullanıcının sitenizle etkileşim kurma süresini önemli ölçüde uzatabilir. Ne kadar çok JavaScript gönderirseniz siteniz etkileşimli hale gelmeden önce kodu ayrıştırmak ve derlemek o kadar uzun sürer.

Bayt cinsinden bayt, JavaScript'in tarayıcı tarafından işlemesi, eşdeğer boyutlu resim veya Web Yazı Tipine göre daha pahalıdır - Tom Dale

JavaScript'e kıyasla, eş değer boyutlu resimlerin işlenmesinin sayısız maliyeti vardır (bu resimlerin kodları yine de çözülmelidir). Ancak ortalama mobil donanımlarda JS'nin, sayfanın etkileşimini olumsuz şekilde 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 ana iş parçacığını engellemez veya kodu çözülürken ve pikseller oluşturulurken arayüzlerin etkileşimli olmasını engellemez. 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 cep telefonlarından bahsediyoruz. Ortalama kullanıcıların, CPU ve GPU'ları yavaş olan, L2/L3 önbelleği olmayan, hatta bellek kısıtlamalı telefonları olabilir.

Ağ özellikleri ile cihaz özellikleri her zaman eşleşmez. Mükemmel bir Fiber bağlantısına sahip bir kullanıcı, cihazına gönderilen JavaScript'i ayrıştırıp değerlendirecek en iyi CPU'ya sahip olmayabilir. Bu tersi durumda da geçerlidir... Bir berbat ağ bağlantısı, ancak çok hızlı bir CPU. — Kristofer Baxter, LinkedIn

Aşağıda, düşük ve ileri teknoloji donanımlarda yaklaşık 1 MB'lık sıkıştırılmış (basit) JavaScript'in ayrıştırma maliyetini görebilirsiniz. Pazardaki en hızlı telefonlar ile ortalama telefonlar arasında kodu ayrıştırma/derleme süresi 2-5 kat farklıdır.

ALT_TEXT_HERE
Bu grafikte, farklı sınıflardaki masaüstü ve mobil cihazlarda 1 MB'lık bir JavaScript paketi (~250 KB'lık gzip'le sıkıştırılmış) paketinin ayrıştırma süreleri gösterilmektedir. Ayrıştırma maliyeti hesaplanırken dikkate alınması gereken sıkıştırılmış rakamlardır.Örneğin, ~250 KB gzip biçiminde sıkıştırılmış JS, sıkıştırarak yaklaşık 1 MB'lık koda açılır.

CNN.com gibi gerçek bir siteye ne dersin?

İleri teknoloji iPhone 8'de CNN'nin JS'sini ayrıştırmak/derlemek için yaklaşık 4 saniye sürer. Ortalama bir telefonda (Moto G4) bu süre yaklaşık 13 saniyedir. Bu, bir kullanıcının bu siteyle ne kadar hızlı etkileşimde bulunabileceğini önemli ölçüde etkileyebilir.

ALT_TEXT_HERE
Yukarıda, daha ortalama bir Android donanımda Apple'ın A11 Bionic çipinin performansını Snapdragon 617 ile karşılaştıran ayrıştırma zamanlarını görüyoruz.

Bu, yalnızca cebinizde taşıyabileceğiniz 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ı için optimizasyon yapın.

ALT_TEXT_HERE
Google Analytics, gerçek kullanıcılarınızın sitenize erişirken kullandığı mobil cihaz sınıfları ile ilgili bilgi sağlayabilir. Bu da, çalıştıkları gerçek CPU/GPU kısıtlamalarını anlama fırsatları sağlayabilir.

Gerçekten çok fazla JavaScript mi gönderiyoruz? Evet, büyük olasılıkla :)

Mobil cihazlarda JavaScript'in durumunu analiz etmek için HTTP Arşivi'ni (ilk 500 bin site) kullanarak sitelerin% 50'sinin etkileşimli hale gelmesinin 14 saniyeden uzun sürdüğünü görebiliriz. Bu siteler, JS'yi ayrıştırmak ve derlemek için 4 saniyeye kadar zaman harcıyor.

ALT_TEXT_HERE

JS ve diğer kaynakları getirme ve işleme için gereken süreyi hesaba katın ve sayfaların kullanıma hazır olduğunu düşünmeden önce kullanıcıların bir süre beklediklerinin şaşırtıcı bir etkisi yoktur. Burada kesinlikle daha iyisini yapabiliriz.

Sayfalarınızdan kritik olmayan JavaScript'i kaldırmak iletim sürelerini, CPU'yu yoğun olarak ayrıştırma ve derlemeyi ve olası bellek ek yükünü azaltabilir. Bu, sayfalarınızın daha hızlı etkileşime geçmesine de yardımcı olur.

Yürütme süresi

Sadece ayrıştırıp derlemek gibi bir maliyeti yoktur. JavaScript yürütme (kodun ayrıştırıldıktan/derlendikten sonra çalıştırılması), ana iş parçacığında gerçekleşmesi gereken işlemlerden biridir. Uzun yürütme süreleri, bir kullanıcının sitenizle ne kadar kısa sürede etkileşime girebileceğini de belirler.

ALT_TEXT_HERE

Komut dosyası 50 ms'den uzun süre çalışıyorsa etkileşim süresi, JS'yi indirmek, derlemek ve yürütmek için gereken tamamen süreye göre ertelenir. Alex Russell

Bu sorunu ele almak için JavaScript, ana iş parçacığıyla kilitlenmeyi önlemek üzere küçük parçalar halinde olmaktan faydalanır. Yürütme sırasında yapılan iş miktarını azaltıp azaltamayacağınızı keşfedin.

Diğer maliyetler

JavaScript, sayfa performansını başka şekillerde etkileyebilir:

  • Bellek. Sayfalar, GC (çöp toplama) nedeniyle sık sık duraksayabilir veya duraklayabilir. Bir tarayıcı belleği geri kazandığında, JS yürütmesi duraklatılır. Böylece, sıklıkla çöp toplayan bir tarayıcı yürütmeyi istediğimizden daha sık duraklatabilir. Sayfaların duraksız kalmasını sağlamak için bellek sızıntılarından ve sık sık gc duraklatmalarından kaçının.
  • Çalışma sırasında, uzun süre çalışan JavaScript, ana iş parçacığını engelleyerek yanıt vermeyen sayfalara neden olabilir. İşleri daha küçük parçalara ayırmak (planlama için requestAnimationFrame() veya requestIdleCallback() kullanarak), yanıt verme sorunlarını en aza indirerek Sonraki Boyamayla Etkileşim'i (INP) iyileştirmeye yardımcı olabilir.

JavaScript yayınlama maliyetini azaltmak için modeller

JavaScript için ayrıştırma/derleme ve ağ iletim sürelerini yavaş tutmaya çalışırken, rotaya dayalı öğme 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 optimizasyon yapan bir kalıptır:

ALT_TEXT_HERE

Bu durumun yaratabileceği etkiyi görselleştirelim.

V8’in Çalışma Zamanı Çağrı İstatistiklerini kullanarak popüler mobil sitelerin ve Progresif Web Uygulamalarının yükleme süresini analiz ediyoruz. Gördüğümüz gibi, ayrıştırma süresi (turuncu renkte gösterilmiş), bu sitelerin çoğunun vakit geçirdiği yerlerin önemli bir kısmıdır:

ALT_TEXT_HERE

PRPL kullanan bir site olan Wego, çok hızlı bir şekilde etkileşimli hale gelerek rotaları için düşük ayrıştırma süresi elde etmeyi başarıyor. Yukarıdaki diğer sitelerin çoğu, JS maliyetlerini düşürmek için kod bölme ve performans bütçelerini kullandı.

Progresif Önyükleme

Birçok site, etkileşimin pahalı olması karşılığında 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ırlar. Daha sonra, JavaScript sonunda getirildiğinde etkinlik işleyicileri eklemek için bunu "yeni sürüme geçirin".

Dikkatli olun, bunun kendi maliyetleri vardır. 1) Genelde etkileşimimizi artırabilecek büyük bir HTML yanıtı gönderirsiniz, 2) JavaScript'in işlenmesi tamamlanana kadar kullanıcıyı deneyimin yarısının gerçekte etkileşimli olamayacağı ürkütücü bir ortamda bırakabilirsiniz.

Progresif Önyükleme daha iyi bir yaklaşım olabilir. Minimum düzeyde işlevsel bir sayfa (yalnızca mevcut yol için gereken HTML/JS/CSS'den oluşan) gönderin. Daha fazla kaynak geldikçe uygulama geç yüklenebilir ve daha fazla özelliğin kilidini açabilir.

ALT_TEXT_HERE
Progresif Önyükleme, Paul Lewis

Görünenlerle orantılı olarak yükleme kodu oluşturmak önemli bir hedeftir. PRPL ve Progresif Önyükleme, bunu başarmanıza yardımcı olabilecek kalıplardır.

Sonuçlar

İletim boyutu, alt uç ağlar için kritik öneme sahiptir. Ayrıştırma süresi, CPU'ya bağlı cihazlar için önemlidir. Bunları önemsiz tutun.

Ekipler, JavaScript iletim ve ayrıştırma/derleme sürelerini düşük tutmak için katı performans bütçeleri kullanarak başarıya ulaştı. Alex Russell'ın "Can You Afford It?: Real-world Web Performance Budgets" (Gerçek Dünya Web Performansı Bütçeleri) başlıklı makaleyi inceleyin.

ALT_TEXT_HERE
Verilen mimari kararların JS'nin ne kadar "boşluk alanı" oluşturacağını göz önünde bulundurmak uygulama mantığını göz önünde bulundurmak faydalı olacaktır.

Mobil cihazları hedefleyen bir site oluşturuyorsanız, temsili donanım kullanarak geliştirmek 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 kullanın.

Daha Fazla Bilgi