Üçü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 teknikleri ele alır:

  • Komut dosyasının yüklenmesini erteleme

  • Kritik olmayan kaynakları geç yükleme

  • Gerekli kaynaklara önceden bağlanma

Dahil edilen örnek uygulama, üçüncü taraf kaynaklardan gelen üç özelliğe sahip basit bir web sayfasına sahiptir:

  • Video yerleştirme

  • Çizgi grafik oluşturmak için kullanılan bir 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ı.

İlk olarak uygulamanın performansını ölçün ve ardından her bir tekniği uygulayarak uygulama performansının farklı yönlerini geliştirin.

Performansı ölçün

İlk olarak örnek uygulamayı tam ekran görünümünde açın:

  1. Projeyi düzenlenebilir hale getirmek için Düzenlenecek remiks'i tıklayın.
  2. Siteyi önizlemek için Uygulamayı Göster'e, ardından Tam Ekran'a tam ekran basın.

Performansı temel almak için sayfada bir Lighthouse performans denetimi çalıştırın:

  1. Geliştirici Araçları'nı açmak için "Control+Shift+J" (veya Mac'te "Command+Option+J") tuşlarına basın.
  2. Lighthouse sekmesini tıklayın.
  3. Mobil'i tıklayın.
  4. Performans onay kutusunu seçin. (Denetimler bölümündeki geri kalan onay kutularının işaretlerini kaldırabilirsiniz.)
  5. Simulated Fast 3G, 4x CPU Slowdown'u (Hızlı 3G, 4x CPU Yavaşlaması) tıklayın.
  6. Depolama Alanını Temizle onay kutusunu seçin.
  7. Denetimleri çalıştır'ı tıklayın.

Makinenizde bir denetim çalıştırdığınızda tam sonuçlar değişiklik gösterebilir ancak İlk Zengin İçerikli Boyama (FCP) süresinin oldukça yüksek olduğunu ve Lighthouse'un araştırma için iki fırsat önerdiğini fark etmeniz gerekir: Oluşturmayı engelleyen kaynakları ortadan kaldırma ve Gerekli kaynaklara önceden bağlanma. (Metriklerin tümü yeşil renkte olsa bile, optimizasyonlar yine de iyileştirmeler sağlayacaktır.)

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

Üçüncü taraf JavaScript'i ertele

Oluşturmayı engelleyen kaynakları ortadan kaldırma denetimi, bir komut dosyasının d3js.org'dan gelmesini erteleyerek zaman kazanabileceğinizi tespit etti:

Oluşturmayı engelleyen kaynak denetimini ortadan kaldırma bölümünde d3.v3.min.js komut dosyasının vurgulandığı 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şlemlerin sırası önemlidir: script.js, doküman ayrıştırıldıktan ve D3 kitaplığı yüklendikten sonra çalıştırılmalıdır. Bu nedenle, index.html içindeki </body> kapanış etiketinden hemen önce yer alır.

Ancak D3 komut dosyası, sayfanın <head> bölümünde bulunur ve geri kalan dokümanın ayrıştırılmasını engeller:

Başlıkta vurgulanan komut dosyası etiketi bulunan index.html ekran görüntüsü.

İki sihirli özellik, komut dosyası etiketine eklendiğinde ayrıştırıcının engellemesini kaldırabilir:

  • async, komut dosyalarının arka planda indirilmesini ve indirildikten sonra ilk fırsatta yürütülmesini sağlar.

  • defer, komut dosyalarının arka planda indirilmesini ve ayrıştırmadan sonra yürütülmesini sağlar.

Bu grafik, sayfanın geneli açısından gerçekten kritik öneme sahip olmadığından ve büyük olasılıkla ekranın alt kısmında yer alacağından ayrıştırıcı engellemesi olmadığından emin olmak için defer kullanın.

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

index.html içindeki 17. satırda, <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ğinden, script.js, D3 hazır olmadan önce çalışır ve hata verir.

defer özelliğine sahip komut dosyaları, belirtildikleri sırayla yürütülür. D3 hazır olduğunda script.js öğesinin yürütülebilmesi için defer ifadesini ekleyin ve D3 <script> öğesinin hemen sonrasına, dokümanın <head> kısmına taşıyın. Artık ayrıştırıcıyı engellemez ve indirme işlemi daha erken başlar.

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

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

  1. Siteyi önizlemek için Uygulamayı Göster'e, ardından Tam Ekran'a tam ekran basın.
  2. Geliştirici Araçları'nı açmak için "Control+Shift+J" (veya Mac'te "Command+Option+J") tuşlarına basın.
  3. sekmesini tıklayın.
  4. Önbelleği devre dışı bırak onay kutusunu seçin.
  5. Hızlandırma açılır menüsünden Hızlı 3G'yi seçin.
  6. Sayfayı tekrar yükleyin.

DevTools Network panelinin ekran görüntüsü.

paneli, sayfanın toplam 28 istek yaptığını ve yaklaşık 1 MB sıkıştırılmış kaynak aktardığını gösterir.

YouTube iframe tarafından yapılan istekleri belirlemek 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üden 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 ek istekler olduğunu ortaya çıkarıyor. YouTube iframe'i komut dosyaları, stil sayfaları, resimler ve yazı tipleri için toplamda 14 istekte bulunur. Ancak kullanıcılar videoyu oynatmak için sayfayı aşağı kaydırmıyorsa tüm bu öğelere gerçekten ihtiyaç duymazlar.

Kullanıcı sayfanın bu bölümüne kadar geçene kadar videonun geç yüklenmesini beklerseniz sayfanın başlangıçta gönderdiği istek sayısını azaltırsınız. Bu yaklaşım kullanıcıların 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 öğeden çıktığında sizi bilgilendiren bir tarayıcı API'si olan Intersection Observer'ı kullanmaktır.

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

Video iframe'ini geç yüklemek için öncelikle normal şekilde yüklenmesini önlemeniz gerekir. Video URL'sini belirtmek için src özelliğini data-src özelliğiyle değiştirerek bu işlemi gerçekleş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 öğeleri hakkında ek bilgi depolamanıza olanak tanıyan bir veri özelliğidir. Bir 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 geç yüklemek için Intersection Observer'ı kullanın

Kullanıcı sayfayı kaydırdığında videoyu yüklemek için bunun ne zaman olduğunu bilmeniz gerekir. Intersection Observer API'si burada devreye girer. Intersection Observer API'si, izlemek istediğiniz bir öğe görüntü alanına girdiğinde veya görüntü alanından çıktığında yürütülecek bir geri çağırma işlevini kaydetmenize olanak tanır.

Başlamak için yeni bir dosya oluşturun ve 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ırması için bir geri çağırma işlevi iletin:

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

Şimdi observer öğesini observe yönteminde bağımsız değişken olarak geçirerek izlemesi için bir hedef öğe (bu örnekte video iframe'i) verin:

// 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 ve IntersectionObserver nesnesinin kendisinin bir listesini alır. Her giriş, boyutlarını, konumunu, görüntü alanına girdiği zamanı ve daha fazlasını açıklayan bir target öğesi ve özellikleri içerir. IntersectionObserverEntry öğesinin özelliklerinden biri isIntersecting'dir. Bu, öğe görüntü alanına girdiğinde true değerine eşit bir boole değeridir.

Bu örnekte target, iframe değeridir. target, görüntü alanına girdiğinde isIntersecting true değerine eşit olur. Bunun 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öster'e, ardından Tam Ekran'a tam ekran basın.
  2. Geliştirici Araçları'nı açmak için "Control+Shift+J" (veya Mac'te "Command+Option+J") tuşlarına basın.
  3. Konsol sekmesini tıklayın.

Yukarı ve aşağı kaydırmayı deneyin. isIntersecting değerinin değiştiğini ve hedef öğenin konsola kaydedildiğini görmeniz gerekir.

Kullanıcı sayfayı kaydırdığında videoyu yüklemek için bir loadElement işlevi çalıştırmak üzere koşul olarak isIntersecting kullanın. Bu işlev, iframe öğesinin data-src öğesinden değeri alıp iframe öğesinin src özelliği olarak ayarlar. Bu değiştirme, 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. paneli, sayfanın 14 istekte bulunduğunu ve yalnızca 260 KB boyutunda olduğunu gösterir. Bu, anlamlı bir gelişme.

Şimdi sayfayı aşağı kaydırın ve paneline dikkat edin. Videoya ulaştığınızda sayfanın ek istekleri tetiklediğini görmeniz gerekir.

Gerekli kaynaklara önceden bağlanın

Kritik olmayan JavaScript'i ertelediniz ve YouTube isteklerini geç yüklediniz. Dolayısıyla, şimdi sıra kalan üçüncü taraf içeriği optimize etmeye geldi.

Bir bağlantıya rel=preconnect özelliği eklendiğinde tarayıcıya, söz konusu kaynak için istek yapılmadan önce alanla bağlantı kurması sağlanır. Bu özelliğin en çok kullanıldığı kaynaklar, sayfanın ihtiyaç duyduğundan emin olduğunuz kaynakları sağlayan kaynaklardır.

Gerekli kaynaklara önceden bağlanma bölümünde önerilen ilk adımda çalıştırdığınız Lighthouse denetimi, staticxx.facebook.com ve youtube.com ile erken bağlantılar kurarak yaklaşık 400 ms tasarruf sağlayabilirsiniz:

staticxx.facebook.com alanı vurgulanmış halde, gerekli kaynak denetimine önceden bağlanın.

YouTube videosu artık geç yüklendiği için yalnızca sosyal medya paylaşım widget'ının kaynağı olan staticxx.facebook.com kalır. Bu alan adıyla 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ğerlendirin

Burada, sayfanın optimizasyondan sonraki durumunu görebilirsiniz. Başka bir Lighthouse denetimi çalıştırmak için codelab'in Performansı ölçme bölümündeki adımları uygulayın.

1 saniye FCP ve 99 performans puanını gösteren Lighthouse denetimi.