Daha Hızlı Sayfa Yüklemeleri için JavaScript Önceliğini Optimize Etme

Core Web Vitals'ı artırmak için scriptleri etkili bir şekilde nasıl önceliklendireceğinizi öğrenin.

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2024-12-12

Daha İyi Web Performansı için JavaScript Önceliklerini Yönetme

Bir şey her zaman açıktı: tüm JavaScript'ler eşit yaratılmamıştır. Bazı scriptler 'menü etkileşimi' veya 'sepete ekle' gibi kritik etkileşimleri yönetirken, diğer scriptler çok daha az önemlidir. Sitenizi terk etmek üzere olan ziyaretçileri bir anketi doldurmaya davet eden 'çıkış niyeti' popup scriptinizi ele alalım. Eminim sonuncular olmadan hepimiz yaşayabiliriz, ancak birincisi olmadan bir web sitesinde gezinmek gerçekten zor olurdu.

Yine de, teknik düzeyde 'ortalama bir web sitesinde' bu ayrım neredeyse hiç yapılmaz. Tüm JavaScript'ler 'sadece sayfaya eklenir' ve tarayıcı bunu çözmek için bırakılır. Şimdi bu bir problem çünkü tarayıcınızın neyin önemli neyin olmadığı hakkında hiçbir fikri yok. Biz geliştiriciler olarak biliyoruz. Öyleyse hadi bunu düzeltelim!

JavaScript önceliği Core Web Vitals'ı nasıl etkileyebilir

Doğru düşünce olmadan scriptleri sayfaya eklemek, Core Web Vitals'ın 3'ünü de etkileyebilir. Largest Contentful Paint, Interaction to Next Paint ve Cumulative Layout Shift. 

javascript lcp impact example

Örnek: LCP network kaynağı render blocking JavaScript'ler tarafından geciktiriliyor

Largest contentful Paint bant genişliği ve CPU rekabetine eğilimlidir. Çok fazla script erken network kaynakları için savaştığında, Largest Contentful Paint network kaynağını geciktirir ve erken CPU çalışması ana threadi bloke ederek LCP'yi geciktirir.

Interaction to Next Paint, bir etkileşimden hemen önce çalışan scriptler tarafından etkilenebilir. Scriptler çalıştığında ana threadi bloke ederler ve bu yürütme süresi boyunca herhangi bir etkileşimi geciktirir.

Scriptler ayrıca 'sayfanın nasıl göründüğünü değiştirirlerse' bir Cumulative Layout Shift'e neden olabilir. Sayfaya banner ekleyen reklam scriptleri ve slider'lar bunu yapmakla ünlüdür.

5 JavaScript Öncelik Türü

5 tür JavaScript önceliği arasında ayrım yapmayı severim. Daha derine inmeden önce bunları hızlıca tartışalım.

  • Render Critical: bunlar sahip olunabilecek en kötü scriptler arasındadır. Sayfanın düzenini değiştirirler ve bu scriptleri yüklemeden düzen tamamen farklı olacaktır. Örnek: bazı slider scriptleri veya bir A/B testi.
  • Critical Scripts: Bu scriptler kritik sayfa işlevselliğini yönetir ve bu scriptler olmadan sepete ürün ekleme, site araması veya navigasyon gibi kritik görevler mümkün değildir.
  • Important scripts. Bu scriptler önemli (iş) mantığını yönetir ve siteniz bunlara bağlıdır. Örneğin: Analytics
  • Nice to have scripts. Bu scriptlere sahip olmak güzeldir, ancak işler zorlaşırsa sayfanın çalışması için gerçekten ihtiyacımız yoktur. Örneğin bir sohbet widget'ı veya bir çıkış niyeti
  • Future Scripts. Bu scriptler kritik veya sahip olmak güzel olabilir, ancak şu anda ihtiyacımız yoktur çünkü bu scriptleri gerçekten kullanabilmemiz için 'diğer adımların' atılması gerekir. Örneğin çok aşamalı bir ödeme scripti.
Artık script öncelikleri hakkında bir fikrimiz olduğuna göre, hadi bunu parçalayalım!

1. Render-Critical Scripts

Bunlar sayfanın nasıl görüntülendiğini doğrudan etkiledikleri için en yıkıcı scriptlerdir. Onlar olmadan, düzen bozulabilir veya amaçlanan tasarımından önemli ölçüde farklı görünebilir. Örnekler arasında slider'lar için scriptler veya yükleme sürecinin başlarında düzeni değiştiren A/B test framework'leri bulunur. 

Bu tür scriptlerle ilgili sorun, ertelenemedikleri veya geciktirilemedikleridir. Herhangi bir gecikme, web sitesi düzeninin kaymasına neden olarak kötü bir UX'e ve Core Web Vitals'ın başarısız olmasına neden olur.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Page Title</title>
    <link href="styles.css" rel="stylesheet" />
    <script src="render-critical.js"></script>
  </head>
  <body></body>
</html>

En İyi Uygulamalar:

  • Bunun gibi render critical scriptlerden mümkün olduğunca kaçının. Bu tür scriptlere bağımlılığı önlemek için kodunuzu yeniden yazın.
  • Bunu önlemenin bir yolu yoksa, bu scriptlerin yalnızca kesinlikle gerekli kısımlarını inline yapın veya yükleyin. 
  • Bu scriptleri defer veya async yapmayın ve 'mümkün olduğunca erken' indirmeyi tetiklemek için onları head'in üstüne yerleştirin.

2. Critical Scripts

Bu scriptler temel etkileşimleri etkinleştirir. Onlar olmadan, site navigasyonu, sepete öğe ekleme, çerez bildirimi veya arama yapma gibi kritik görevler imkansız hale gelir. Site'nin temel işlevselliği için vazgeçilmezdirler.

Bu scriptler async veya defer özniteliği ile sayfanın head'ine yerleştirilmelidir.

<script defer src="critical.js"></script>
<script async src="critical.js"></script>

En İyi Uygulamalar:

  • Bunun gibi scriptleri minimumda tutun ve bu işlevselliği diğer, daha az kritik işlevsellikle birleştirmeyin.
  • Bu scriptleri bağımlılıklarına bağlı olarak async veya defer kullanarak erken yükleyin.
  • Yürütmedeki darboğazları belirlemek ve performanslarının kullanıcı ihtiyaçlarıyla uyumlu olmasını sağlamak için Coredash gibi Real User Monitoring (RUM) araçlarını kullanın.

3. Important Scripts

Site'nin kullanılabilirliğiyle doğrudan bağlantılı olmasa da, important scriptler temel iş işlevlerini destekler. Örneğin analytics scriptleri temel veriler sağlar ancak daha önemli görsel öğelerden önce yüklenmesi gerekmez. Açıkçası critical ve important scriptler arasındaki ayrım tartışmalı bir konu olabilir, bu nedenle bu önceliği belirlemeden önce tüm paydaşlarla konuştuğunuzdan emin olun!

Bu tür scriptler için script önceliğini düşürmenin 3 yolu vardır.

<html>
<head>
<!-- method 1: low fetchpriority -->
<script fetchpriority="low" defer src="important.js"></script>

<!-- method 2: inject after DOMContentLoaded -->
<script>
  document.addEventListener('DOMContentLoaded', function() {
    var script = document.createElement('script');
    script.src = 'important.js';
    document.body.appendChild(script);
  });
</script>
</head>
<body>

<!-- method 3: place at the bottom of the page -->
<script defer src="important.js"></script>
</body>
</html>

1. Low fetchpriority. 

Fetchpriority'yi ayarlamak scriptin göreceli önceliğini düşürür. Diğer deferred veya asynced scriptler muhtemelen yüksek öncelikle sıraya alınırken fetchprioriy="low" olan scriptler düşük öncelikle sıraya alınır. Sayfanıza (veya render yolunuza) bağlı olarak, bu Largest Contentful Paint görseli ve önemli fontlar gibi diğer kaynakları önceliklendirmek için yeterli olabilir. 

2: DOMContentLoaded'dan sonra enjekte edin

Scripti DOMContentLoaded olayından sonra enjekte ederek, HTML tamamen ayrıştırıldıktan hemen sonra scriptin indirmeye başlamasını sağlarsınız. Bu, görseller ve fontlar gibi keşfedilebilir kaynakların öncelik almasına izin verir. Bu yöntem bir denge sağlar: script, işlevsellikte gecikmeleri önlemek için yeterince erken yüklenmeye başlar ancak ilk sayfa render'ı için çok önemli olan erken kaynaklarla rekabet etmez.

3: sayfanın altına yerleştirin

Bu klasik teknik, tarayıcı tüm belgeyi işleyene kadar script yüklemeyi erteler ve kabaca teknikle aynı sonucu elde eder. Tek fark, teknik 2'nin tarayıcınızın preload tarayıcısını atlaması, bu tekniğin ise atlamamasıdır.  Preload tarayıcı, tarayıcınızın kritik kaynakları hızlıca tanımlamak ve sıraya almak için kullandığı hafif hızlı bir tarayıcıdır. Viewport'ta lazy loaded görsellerin olma olasılığı varsa preload tarayıcısını atlamak iyi bir fikir olabilirken, preload tarayıcısını kullanmak bu script için yüklemeyi hızlandıracaktır.

4. Nice-to-Have Scripts

Bu scriptler kullanıcı deneyimini geliştirir ancak sitenin çalışması için gerekli değildir. Örnekler arasında sohbet widget'ları, müşteri geri bildirim popup'ları veya isteğe bağlı animasyonlar bulunur. Faydalı olmalarına rağmen, birincil kullanıcı deneyimine müdahale etmemelidirler.

Bu scriptler 'lazy on load' adlı bir desenle yüklemek için ideal bir adaydır. Bu, sayfa load olayını bekleyin ve ardından, boşta kalma sırasında, scripti enjekte edin demektir.  Load olayını beklemek, scriptin daha önemli erken kaynaklarla bant genişliği ve CPU için rekabet etmemesini sağlar. Boşta kalma anını beklemek, tarayıcının kullanıcı girişi gibi daha önemli görevleri işlemediğini garanti eder.

İşte çalışan bir örnek:

window.addEventListener("load", () => {
  window.requestIdleCallback(() => {
    const script = document.createElement("script");
    script.src = "/path/to/script.js";
    document.head.appendChild(script);
  });
});

En İyi Uygulamalar:

  • Bu scriptleri sayfa yüklendikten sonra lazy-load yapın ve boşta kalma anını bekleyin.
  • Bu desenle yüklenen scriptlerin hızlı yüklenmesinin garanti edilmediğini anlayın

5. Future Scripts

Future scriptler, belirli koşullar karşılanana kadar ihtiyaç duyulmayacak olanlardır. Örneğin, çok aşamalı bir ödeme scripti yalnızca kullanıcı sepetine öğeler ekledikten sonra alakalı hale gelir. Bu scriptler genellikle kullanıcının yolculuğunda çok daha sonra bekleyebilir.

Bu örneğe bir göz atın. Form görünür viewport'ta olduğunda yalnızca kayıt scripti için gereken JS mantığını yüklemek için intersection observer kullanır.

<!DOCTYPE html>
<html>
  <head>
    <script>
      document.addEventListener("DOMContentLoaded", function () {
        const form = document.querySelector("form");
        const observer = new IntersectionObserver(function (entries) {
          entries.forEach((entry) => {
            if (entry.isIntersecting) {
              const script = document.createElement("script");
              script.src = "/sign-up.js";
              document.head.appendChild(script);
              observer.unobserve(form);
            }
          });
        });
        observer.observe(form);
      });
    </script>
  </head>
  <body>
    <form action="/sign-up" method="post">
      <label for="email">Email:</label>
      <input type="email" id="email" name="email" required />
      <button type="submit">Sign Up</button>
    </form>
  </body>
</html>

En İyi Uygulamalar:

  • Bu scriptleri kullanıcı eylemleri tarafından tetiklenen talep üzerine yükleyin.
  • Her adımda yalnızca gerekli kısımları sunmak için kod bölme tekniklerini kullanın.
  • Onları yalnızca gerektiğinde, örneğin kullanıcı belirli bir bölüme kaydırdığında dinamik olarak enjekte edin.

Stop debating in Jira.

Get a definitive answer on your performance issues. I deliver a granular breakdown of your critical rendering path.

Book a Deep Dive >>

  • Definitive Answers
  • Granular Breakdown
  • Critical Path Analysis
Daha Hızlı Sayfa Yüklemeleri için JavaScript Önceliğini Optimize EtmeCore Web Vitals Daha Hızlı Sayfa Yüklemeleri için JavaScript Önceliğini Optimize Etme