Üçüncü taraf JavaScript'i optimize edin

Milica Mihajlija
Milica Mihajlija

Üçüncü taraf komut dosyaları performansı etkiler. Bu nedenle, bunları düzenli olarak denetlemek ve yüklemek için etkili teknikler kullanmak önemlidir. Bu codelab'de, üçüncü taraf kaynaklarının yüklenmesini nasıl optimize edeceğiniz gösterilmektedir. Aşağıdaki teknikler ele alınmıştır:

  • Komut dosyasının yüklenmesini erteleme

  • Kritik olmayan kaynakların geç yüklenmesi

  • Gerekli kaynaklara önceden bağlanma

Dahil edilen örnek uygulama, üçüncü taraf kaynaklardan gelen üç özelliğin yer aldığı basit bir web sayfası içeriyor:

  • Yerleştirilmiş video

  • Çizgi grafiği oluşturmak için veri görselleştirme kitaplığı

  • Sosyal medya paylaşımı widget'ı

Üçüncü taraf kaynakların vurgulandığı sayfanın ekran görüntüsü.
Örnek uygulamadaki üçüncü taraf kaynakları.

Uygulamanın performansını ölçerek başlayıp ardından uygulama performansının farklı yönlerini iyileştirmek için her tekniği uygulayın.

Performansı ölçün

Öncelikle örnek uygulamayı tam ekran görünümünde açın:

  1. Projeyi düzenlenebilir hale getirmek için Düzenlemek için remiks oluştur'u tıklayın.
  2. Siteyi önizlemek için Uygulamayı Görüntüle'ye, ardından Tam Ekran'a tam ekran basın.

Temel performansı belirlemek için sayfada bir Lighthouse performans denetimi çalıştırın:

  1. Geliştirici Araçları'nı açmak için "Kontrol+Üst Karakter+J" (veya Mac'te "Komut+Option+J") tuşlarına basın.
  2. Lighthouse sekmesini tıklayın.
  3. Mobil'i tıklayın.
  4. Performans onay kutusunu işaretleyin. (Denetimler bölümünde diğer onay kutularının işaretlerini kaldırabilirsiniz.)
  5. Simüle Edilen Hızlı 3G, 4x CPU Yavaşlatma'yı tıklayın.
  6. Depolama alanını temizle onay kutusunu işaretleyin.
  7. Denetleme çalıştır'ı tıklayın.

Cihazınızda denetim yaptığınızda tam sonuçlar değişiklik gösterebilir. Ancak ilk zengin içerikli boyama (FCP) süresinin oldukça yüksek olduğunu ve Lighthouse'un incelenmesi için iki fırsat önerdiğini fark edeceksiniz: Oluşturma işlemini engelleyen kaynakları ortadan kaldırın ve Gerekli kaynaklara önceden bağlanın. (Metriklerin tümü yeşil renkli olsa bile optimizasyonlar iyileşme sağlar.)

Lighthouse denetiminin 2,4 saniyelik FCP değerini ve iki fırsatı gösteren ekran görüntüsü: Oluşturmayı engelleyen kaynakları ortadan kaldırın ve gerekli kaynaklara önceden bağlanın.

Üçüncü taraf JavaScript'i erteleme

Oluşturmayı engelleyen kaynakları ortadan kaldırın denetimi, d3js.org'dan gelen bir komut dosyasını erteleyerek biraz zaman kazanabileceğinizi belirledi:

d3.v3.min.js komut dosyasının vurgulandığı Oluşturmayı engelleyen kaynakları ortadan kaldırın denetiminin ekran görüntüsü.

D3.js, veri görselleştirmeleri oluşturmak için kullanılan bir JavaScript kitaplığıdır. Örnek uygulamadaki script.js dosyası, SVG çizgi grafiğini oluşturmak ve sayfaya eklemek için D3 yardımcı program işlevlerini kullanır. Buradaki işlem sırası önemlidir: script.js, doküman ayrıştırıldıktan ve D3 kitaplığı yüklendikten sonra çalışmalıdır. Bu nedenle, index.html içinde kapatıcı </body> etiketinden hemen önce eklenir.

Ancak, D3 komut dosyası sayfanın <head> öğesine eklendiğinden geri kalan dokümanın ayrıştırılmasını engeller:

Başlığındaki komut dosyası etiketinin vurgulandığı index.html ekran görüntüsü.

Komut dosyası etiketine eklendiğinde iki sihirli özellik ayrıştırıcının engellemesini kaldırabilir:

  • async, komut dosyalarının arka planda indirilmesini ve indirme işlemi tamamlandıktan sonra ilk fırsatta yürütülmesini sağlar.

  • defer, komut dosyalarının arka planda indirilmesini ve ayrıştırma işleminin tamamen tamamlanmasından sonra yürütülmesini sağlar.

Bu grafik sayfanın geneli açısından çok önemli olmadığından ve büyük olasılıkla sayfanın üst kısmında yer almayacağından, ayrıştırıcının engellenmediğinden emin olmak için defer öğesini kullanın.

1. Adım: Komut dosyasını defer özelliğiyle eşzamansız olarak yükleyin

index.html dosyasının 17. satırında <script> öğesine defer özelliğini ekleyin:

<script src="https://d3js.org/d3.v3.min.js" defer></script>

2. Adım: İşlemlerin doğru sırayla yapıldığından emin olun

D3 ertelendiği için script.js, D3 hazır olmadan önce çalışacak ve bu da hatayla sonuçlanacaktır.

defer özelliğine sahip komut dosyaları, belirtildikleri sırada yürütülür. script.js öğesinin D3 hazır olduktan sonra yürütülmesini sağlamak için ona defer ekleyin ve bunu dokümanın <head> kadarına, D3 <script> öğesinin hemen sonrasına taşıyın. Artık ayrıştırıcıyı engellemiyor ve indirme işlemi daha erken başlıyor.

<script src="https://d3js.org/d3.v3.min.js" defer></script>
<script src="./script.js" defer></script>

Üçüncü taraf kaynaklarını geç yükleme

Ekranın alt kısmındaki tüm kaynaklar geç yükleme için iyi adaylardır.

Örnek uygulamada, iframe içine yerleştirilmiş bir YouTube videosu vardır. Sayfanın kaç istek gönderdiğini ve bunların hangilerinin yerleşik YouTube iframe'inden geldiğini kontrol etmek için:

  1. Siteyi önizlemek için Uygulamayı Görüntüle'ye, ardından Tam Ekran'a tam ekran basın.
  2. Geliştirici Araçları'nı açmak için "Kontrol+Üst Karakter+J" (veya Mac'te "Komut+Option+J") tuşlarına basın.
  3. sekmesini tıklayın.
  4. Önbelleği devre dışı bırak onay kutusunu seçin.
  5. Veri Sınırlaması açılır menüsünden Hızlı 3G'yi seçin.
  6. Sayfayı tekrar yükleyin.

DevTools Ağ panelinin ekran görüntüsü.

panelinde, sayfanın toplam 28 istek gönderdiği ve yaklaşık 1 MB sıkıştırılmış kaynak aktardığı görülüyor.

YouTube iframe tarafından gönderilen istekleri tespit etmek için Başlatan sütununda video kimliğini (6lfaiXM6waw) bulun. Tüm istekleri alana göre gruplandırmak için:

  • panelinde bir sütun başlığını sağ tıklayın.

  • Açılır menüde Alanlar sütununu seçin.

  • İstekleri alana göre sıralamak için Alanlar sütun başlığını tıklayın.

Yeni sıralama, Google alanlarına yönelik ek istekler olduğunu ortaya çıkarır. YouTube iFrame'i, komut dosyaları, stil sayfaları, resimler ve yazı tipleri için toplam 14 istek gönderiyor. Ancak kullanıcılar videoyu oynatmak için sayfayı aşağı kaydırmadığı sürece tüm bu öğelere ihtiyaç duymaz.

Kullanıcı sayfanın ilgili bölümüne gelene kadar videoyu geç yüklemeyi bekleyerek sayfanın başlangıçta gönderdiği istek sayısını azaltabilirsiniz. Bu yaklaşım, kullanıcı verilerini kaydeder ve ilk yüklemeyi hızlandırır.

Geç yüklemeyi uygulamanın bir yolu, bir öğe tarayıcının görüntü alanına girdiğinde veya bu görünümden çıktığında sizi bilgilendiren bir tarayıcı API olan Intersection Observer'ı kullanmaktır.

1. Adım: Videonun ilk başta yüklenmesini engelleyin

Video iFrame'sini yavaş yüklemek için önce normal şekilde yüklenmesini engellemeniz gerekir. Video URL'sini belirtmek için src özelliğini data-src özelliğiyle değiştirin:

<iframe width="560" height="315" data-src="https://www.youtube.com/embed/lS9D6w1GzGY" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

data-src, standart HTML öğelerinde ek bilgi depolamanıza olanak tanıyan bir veri özelliğidir. Veri özelliği, "data-" ile başladığı sürece herhangi bir şekilde adlandırılabilir.

src içermeyen iframe yüklenmez.

2. Adım: Videoyu geç yüklemek için Intersection Observer'ı kullanın

Bir kullanıcı kaydırarak videoya geldiğinde videoyu yüklemek için bu işlemin ne zaman gerçekleştiğini bilmeniz gerekir. İşte bu noktada Intersection Observer API devreye girer. Intersection Observer API, izlemek istediğiniz bir öğe görüntüleme alanına girdiğinde veya görüntüleme alanından çıktığında çalıştırılacak bir geri çağırma işlevi kaydetmenize olanak tanır.

Başlamak için yeni bir dosya oluşturun ve dosyayı lazy-load.js olarak adlandırın:

  • Yeni Dosya'yı tıklayın ve dosyaya bir ad verin.
  • Bu Dosyayı Ekle'yi tıklayın.

Komut dosyası etiketini dokümanınızın başlığına ekleyin:

 <script src="/lazy-load.js" defer></script>

lazy-load.js içinde yeni bir IntersectionObserver oluşturun ve çalıştırılacak bir geri çağırma işlevi iletin:

// create a new Intersection Observer
let observer = new IntersectionObserver(callback);

Şimdi observer yöntemine bir bağımsız değişken olarak göndererek observer'e izlenecek bir hedef öğe (bu durumda video iFrame'i) verin:observe

// the element that you want to watch
const element = document.querySelector('iframe');

// register the element with the observe method
observer.observe(element);

callback, IntersectionObserverEntry nesnelerinin listesini ve IntersectionObserver nesnesini alır. Her giriş, bir target öğesi ve boyutlarını, konumunu, görüntü alanına girdiği zamanı ve daha fazlasını açıklayan özellikleri içerir. IntersectionObserverEntry öğesinin özelliklerinden biri isIntersecting'dir. Bu, öğe görüntü alanına girdiğinde true değerine eşit olan bir boole değeridir.

Bu örnekte target, iframe'tır. target görüntü alanına girdiğinde isIntersecting değeri true olur. Bu işlevin nasıl çalıştığını görmek için callback öğesini aşağıdaki işlevle değiştirin:

let observer = new IntersectionObserver(callback);
let observer = new IntersectionObserver(function(entries, observer) {
    entries.forEach(entry => {
      console.log(entry.target);
      console.log(entry.isIntersecting);
    });
  });
  1. Siteyi önizlemek için Uygulamayı Görüntüle'ye, ardından Tam Ekran'a tam ekran basın.
  2. Geliştirici Araçları'nı açmak için "Control+Üst Karakter+J" (veya Mac'te "Command+Option+J") tuşlarına basın.
  3. Konsol sekmesini tıklayın.

Ekranı yukarı ve aşağı kaydırmayı deneyin. isIntersecting değerinin değiştiğini ve hedef öğenin konsola kaydedildiğini görürsünüz.

Kullanıcı kaydırarak videonun konumuna geldiğinde videoyu yüklemek için isIntersecting koşulunu kullanarak bir loadElement işlevi çalıştırın. Bu işlev, değeri iframe öğesinin data-src özelliğinden alır ve iframe öğesinin src özelliği olarak ayarlar. Bu değiştirme işlemi, videonun yüklenmesini tetikler. Ardından, video yüklendikten sonra hedef öğeyi izlemeyi durdurmak için observer üzerinde unobserve yöntemini çağırın:

let observer = new IntersectionObserver(function (entries, observer) {
  entries.forEach(entry => {
    console.log(entry.target);
    console.log(entry.isIntersecting);
  });
});
    if (entry.isIntersecting) {
      // do this when the element enters the viewport
      loadElement(entry.target);
      // stop watching
      observer.unobserve(entry.target);
    }
  });
});

function loadElement(element) {
  const src = element.getAttribute('data-src');
  element.src = src;
}

3. Adım: Performansı yeniden değerlendirin

Kaynakların boyutunun ve sayısının nasıl değiştiğini görmek için Geliştirici Araçları panelini açıp sayfayı tekrar yükleyin. panelinde, sayfanın 14 istek gönderdiği ve yalnızca 260 KB kullandığı görülüyor. Bu, kayda değer bir gelişme.

Ardından sayfayı aşağı kaydırın ve panelini izleyin. Videoya ulaştığınızda sayfanın ek istekler tetiklediğini göreceksiniz.

Gerekli kaynaklara önceden bağlanın

Kritik olmayan JavaScript'i ertelediniz ve YouTube isteklerini yavaş yüklediniz. Artık kalan üçüncü taraf içeriğini optimize etmenin zamanı geldi.

Bir bağlantıya rel=preconnect özelliği eklendiğinde tarayıcı, ilgili kaynak için istek gönderilmeden önce bir alanla bağlantı kurar. Bu özellik, sayfanın ihtiyaç duyduğundan emin olduğunuz kaynakları sağlayan kaynaklarda en iyi şekilde kullanılır.

İlk adımda çalıştırdığınız Lighthouse denetimi, Zorunlu kaynaklara önceden bağlanma bölümünde staticxx.facebook.com ve youtube.com'a erken bağlantılar kurarak yaklaşık 400 ms tasarruf edebileceğinizi önerdi:

staticxx.facebook.com alanının vurgulandığı, gerekli kaynaklara önceden bağlanma denetimi.

YouTube videosu artık yavaş yüklendiğinden, yalnızca sosyal medya paylaşım widget'ının kaynağı olan staticxx.facebook.com kalıyor. Bu alanla erken bağlantı oluşturmak dokümanın <head> öğesine bir <link> etiketi eklemek kadar basittir:

  <link rel="preconnect" href="https://staticxx.facebook.com">

Performansı yeniden değerlendirme

Optimizasyon sonrasında sayfanın durumu burada verilmiştir. Başka bir Lighthouse denetimi çalıştırmak için codelab'in Performansı ölçme bölümündeki adımları uygulayın.

Lighthouse denetiminde 1 saniyelik FCP ve 99 performans puanı gösteriliyor.