Üçüncü taraf JavaScript'i optimize edin

Milica Mihajlija
Milica Mihajlija

Üçüncü taraf komut dosyaları performansı etkiler. Bu nedenle, bunları düzenli olarak denetlemeniz ve yüklemek için verimli teknikler kullanmanız ö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

Eklenen örnek uygulamada, üçüncü taraf kaynaklarından gelen üç özellik içeren basit bir web sayfası bulunur:

  • Video yerleştirme

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

  • Sosyal medya paylaşımı widget'ı

Üçüncü taraf kaynaklarını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. (Denetim bölümündeki diğer onay kutularının işaretini 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 gereken iki fırsat önerdiğini fark edeceksiniz: Oluşturma işlemini engelleyen kaynakları ortadan kaldırın ve Gerekli kaynaklara önceden bağlanın. (Tüm metrikler yeşil olsa bile optimizasyonlar yine de iyileştirmeler sağlar.)

2,4 saniyelik FCP'yi ve iki fırsatı gösteren Lighthouse denetiminin ekran görüntüsü: Oluşturma işlemini 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şturmaya yönelik 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. Burada 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> içine dahil edildiğinden, belgenin geri kalanının ayrıştırılması engellenir:

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 işlevinin D3 hazır olduktan sonra yürütülmesini sağlamak için defer öğesini ekleyin ve D3 <script> öğesinin hemen sonrasına, belgenin <head> bölümüne 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 işaretleyin.
  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 yapılan istekleri tanımlamak için Başlatıcı 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üden Alan adları 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 isteklerin olduğunu gösteriyor. 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 aşağı kaydırmadığı sürece bu öğelerin tümüne 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.

Yavaş yüklemeyi uygulamanın bir yolu, bir öğe tarayıcı görüntü alanına girdiğinde veya görüntü alanından çıktığında sizi bilgilendiren bir tarayıcı API'si 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 bir iFrame yüklenmez.

2. Adım: Videoyu gecikmeli 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ü alanının içine girdiğinde veya görüntü 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 başlığınıza 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, true değerine eşittir. Bunun nasıl çalıştığını görmek için callback değerini 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 "Kontrol+Üst Karakter+J" (veya Mac'te "Komut+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 önemli 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 gecikmeli olarak 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 kaynağı kalır. Bu alanla erken bağlantı kurmak, dokümanın <head> bölümüne bir <link> etiketi eklemek kadar kolaydır:

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

Performansı yeniden değerlendirme

Sayfanın optimizasyondan sonraki durumu aşağıda 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.

1 saniyelik FCP&#39;yi ve 99 performans puanını gösteren Lighthouse denetimi.