Üçü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 yüklenmesini nasıl optimize edeceğiniz gösterilmektedir. Aşağıdaki teknikleri ele alır:

  • Komut dosyası yüklemeyi erteleme

  • Kritik olmayan kaynakları geç yükleme

  • Gerekli kaynaklara önceden bağlanılıyor

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

  • Yerleştirilmiş video

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

  • Sosyal medya paylaşım widget'ı

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

Önce uygulamanın performansını ölçer, ardından her tekniği uygulayarak uygulama performansının farklı yönlerini geliştirirsiniz.

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üzenlemek için Remiks'i tıklayın.
  2. Siteyi önizlemek için Uygulamayı Görüntüle'ye basın. Ardından, Tam ekran tam ekran.

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

  1. Geliştirici Araçları'nı açmak için "Control+Üst Karakter+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 işaretleyin. (Denetimler bölümünde diğer onay kutularının işaretlerini kaldırabilirsiniz.)
  5. Simulated Fast 3G, 4x CPU Yavaşlama'yı tıklayın.
  6. Depolama Alanını Temizle onay kutusunu işaretleyin.
  7. Denetimleri çalıştır'ı tıklayın.

Makinenizde denetim gerçekleştirdiğinizde tam sonuçlar değişiklik gösterebilir ancak First Contentful Paint (FCP) süresinin oldukça uzun olduğunu ve Lighthouse'un araştırma yapmak için iki fırsat önerdiğini fark edersiniz: Oluşturmayı 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 tespit etti:

d3.v3.min.js komut dosyasının vurgulandığı Oluşturma engelleyen kaynaklar 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ği oluşturmak ve bunu sayfaya eklemek için D3 yardımcı program işlevlerini kullanır. Buradaki işlemlerin sırası önemlidir: script.js, belge ayrıştırıldıktan ve D3 kitaplığı yüklendikten sonra çalıştırılmalıdır. Bu nedenle, index.html içerisindeki </body> kapanış etiketinin hemen öncesine eklenir.

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

Başlıkta komut dosyası etiketinin vurgulandığı 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 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şlemi tamamlandıktan sonra yürütülmesini sağlar.

Bu grafik, sayfanın tamamı için 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ı engelleme 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 öğesinin 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ırasının doğru olmasını sağlayın

Artık 3. gün ertelendiğine göre, script.js D3 hazır olmadan önce çalıştırılacak ve bir hataya neden olacaktır.

defer özelliğine sahip komut dosyaları, belirtildikleri sırayla 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. Şimdi 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 uygulama, iframe içine yerleştirilmiş bir YouTube videosuna sahip. 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örüntüle'ye basın. Ardından, Tam ekran tam ekran.
  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. sekmesini tıklayın.
  4. Önbelleği devre dışı bırak onay kutusunu seçin.
  5. Kısıtlama açılır menüsünden Hızlı 3G'yi seçin.
  6. Sayfayı tekrar yükleyin.

Geliştirici Araçları 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österiliyor.

YouTube iframe tarafından gönderilen istekleri tespit etmek için Başlatan sütununda video kimliğini (6lfaiXM6waw) bulun. Tüm istekleri alan adına 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 istekte bulunur. 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 videonun geç yüklenmesini bekleyerek sayfanın başlangıçta gönderdiği istek sayısını azaltırsınız. Bu yaklaşım, 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 başlangıçta yüklenmesini engelleyin

Video iframe'ini geç yüklemek için öncelikle her zamanki gibi yüklenmesini önlemeniz gerekir. Bunun için src özelliğini, data-src özelliğiyle değiştirerek video URL'sini belirtin:

<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 bilgiler depolamanıza olanak tanıyan bir veri özelliğidir. Bir veri özelliği, "data-" ile başladığı sürece herhangi bir şey olarak adlandırılabilir.

src içermeyen 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 tam da bu noktada 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ülen bir geri çağırma işlevi kaydetmenizi sağlar.

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 aracında yeni bir IntersectionObserver oluşturun ve çalıştırılması için bu işleve bir geri çağırma işlevi iletin:

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

Şimdi, observe yönteminde bağımsız değişken olarak ileterek observer öğesine izlenecek bir hedef öğe (bu durumda 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 listesini alır. Her giriş bir target öğesi ve öğenin boyutlarını, konumunu, görüntü alanına girdiği zamanı ve daha fazlasını açıklayan özellikler içerir. IntersectionObserverEntry özelliklerinden biri isIntersecting şeklindedir. Bu, öğe görüntü alanına girdiğinde true değerine eşit olan bir boole değeridir.

Bu örnekte target, iframe öğesidir. 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 basın. Ardından, Tam ekran tam ekran.
  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.

Yukarı ve aşağı kaydırmayı deneyin. isIntersecting değişiminin değerini ve hedef öğenin konsola kaydedildiğini görürsünüz.

Videoyu kullanıcı konumuna doğru kaydırdığında yüklemek için, iframe öğesinin data-src değerindeki değeri alıp iframe öğesinin src özelliği olarak ayarlayan loadElement işlevini çalıştırmak için koşul olarak isIntersecting kullanın. Bu değiştirme işlemi, videonun yüklenmesini tetikler. Ardından, video yüklendikten sonra hedef öğeyi izlemeyi durdurmak için observer uygulamasında 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 istek yaptığını ve yalnızca 260 KB olduğunu gösteriyor. Bu, kayda değer 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. Bu nedenle, kalan üçüncü taraf içeriğini optimize etmenin zamanı geldi.

Bağlantıya rel=preconnect özelliği eklemek, tarayıcının söz konusu kaynak için istek yapılmadan önce alan adıyla bağlantı kurmasını sağlar. Bu özellik en çok, sayfanın ihtiyaç duyduğundan emin olduğunuz kaynakları sağlayan kaynaklarda kullanılı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 oluşturarak yaklaşık 400 ms kazanabilirsiniz:

staticxx.facebook.com alan adının vurgulandığı 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ı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ğerlendirin

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.