Titremesiz İstemci Tarafı A/B Testi

Web özellikleri: blocking="render"

Sorun

İstemci tarafı A/B testi araçları, tarayıcı sayfayı oluşturmaya başladıktan sonra DOM'u değiştiren bir komut dosyası yükleyerek çalışır. Müdahale edilmediğinde kullanıcı, deneme varyantına geçmeden önce özgün içeriği kısa bir süre görür. Test platformları, geçmişte bu sorunu çözmek için deneme komut dosyası tamamlanana veya rastgele bir zaman aşımı süresi (genellikle 4 saniye) geçene kadar tüm sayfayı opacity: 0 ile gizleyen "titreşim önleyici snippet'ler" kullanıyordu. Bu yaklaşım, aşamalı oluşturmayı feda eder, görünmez içeriklerin yanlışlıkla tıklanmasına neden olur ve gereksiz boyama döngüleri oluşturur.

Çözüm

blocking=render özelliği, <head> içine yerleştirilen bir <script> veya <link> öğesinin, kaynak getirilip yürütülene kadar oluşturmayı (ayrıştırmayı değil) engellemesine olanak tanır. Bu sayede, deneme komut dosyaları, stil sayfalarının varsayılan olarak sahip olduğu oluşturmayı engelleme davranışına sahip olur ve tarayıcının, deneme varyantı uygulanana kadar sayfayı hiçbir zaman boyamamasını sağlar. Opaklık hileleri, rastgele zaman aşımları ve titreme yok.

Uygulama Stratejisi

  1. ZORUNLU: Deneme komut dosyasını dokümanın <head> bölümüne yerleştirin ve blocking="render" ekleyin.
  2. ZORUNLU: Komut dosyasında type="module" (satır içi komut dosyaları için tercih edilir) veya async (src değerine sahip harici komut dosyaları için tercih edilir) bulunduğundan emin olun.
  3. Deneme komut dosyasını küçük ve hızlı TUTUN. Oluşturma, komut dosyası yürütülene kadar engellendiğinden, büyük veya yavaş bir komut dosyası ilk boyamayı doğrudan geciktirir.
  4. İlk boyamadan önce çalıştırılması gerekmeyen komut dosyalarında blocking="render" KULLANMAYIN. Yalnızca çıkışı ilk oluşturmada görünür olması gereken komut dosyaları için tasarlanmıştır.
  5. <head> dışındaki komut dosyalarına blocking="render" UYGULAMAYIN. Yalnızca <head> içindeki komut dosyaları oluşturmayı engelleyebilir.

Uygulama Kılavuzu

Temel Kurulum

ZORUNLU: Deneme komut dosyasını hem async hem de blocking="render" ile yükleyin. async özelliği, komut dosyasının HTML ayrıştırmasını engellememesini sağlar (tarayıcı, komut dosyasını getirirken DOM'u oluşturmaya devam eder). blocking="render" özelliği, komut dosyası yürütülene kadar tarayıcının hiçbir şey boyamamasını sağlar.

<head>
  <!--
    MANDATORY: Both `async` and `blocking="render"` are required.
    - `async`: Prevents parser-blocking, so the DOM is built in parallel.
    - `blocking="render"`: Holds rendering until the script executes,
      ensuring experiment changes are applied before the user sees anything.
  -->
  <script
    src="https://cdn.example.com/experiment-sdk.js"
    async
    blocking="render"
  ></script>
</head>

Denemeye Özel Stiller Yükleniyor

Deneme için bir varyant stil sayfası gerekiyorsa <link> öğesinde blocking="render" kullanın. <head> içindeki stil sayfaları varsayılan olarak oluşturmayı engeller ancak dinamik olarak eklenen veya komut dosyası aracılığıyla eklenen stil sayfaları engellemez. Stil sayfası dinamik olarak eklendiğinde veya niyetinizi açıkça belirtmek istediğinizde blocking="render" öğesini açıkça kullanın.

<head>
  <!--
    DO: Use blocking="render" on experiment stylesheets that are
    dynamically inserted or conditionally loaded by the experiment SDK.
    This ensures variant styles are applied before first paint.
  -->
  <link
    rel="stylesheet"
    href="https://cdn.example.com/experiment-variant-b.css"
    blocking="render"
  >
</head>

Satır içi deneme komut dosyası

Deneme mantığı satır içi olarak eklenebilecek kadar basitse blocking="render" ile satır içi modül komut dosyası kullanın. Bu, deneme mantığı bir yapılandırmayı getirip DOM değişikliklerini doğrudan uyguladığında kullanışlıdır.

<head>
  <!--
    DO: Use an inline module script when the experiment logic is small.
    Module scripts are deferred by default (non-parser-blocking),
    and blocking="render" ensures rendering waits for execution.
  -->
  <script type="module" blocking="render">
    // Fetch the experiment configuration from your testing platform.
    const config = await fetch('/api/experiment?id=homepage-cta')
      .then(res => res.json());

    // Apply the variant by setting a data attribute on <html>.
    // CSS rules keyed to this attribute will style the variant.
    document.documentElement.dataset.variant = config.variant;
  </script>

  <style>
    /* Default styles (control group) */
    .cta-button {
      background-color: blue;
    }

    /* Variant B styles, activated by the data attribute */
    [data-variant="b"] .cta-button {
      background-color: green;
    }
  </style>
</head>

En İyi Uygulamalar

  • ZORUNLU: Deneme komut dosyası hızlı bir şekilde yürütülmelidir. Yavaş bir komut dosyası, tüm oluşturma işlemlerini geciktirir. Oluşturmayı engelleyen komut dosyası için bir performans bütçesi (ör. 100 ms'nin altında yürütme süresi) belirleyin.
  • DO split heavy experiment logic from the render-blocking script. Varyantı uygulayan küçük, oluşturmayı engelleyen bir taslak yükleyin, ardından daha ağır izleme veya analiz komut dosyalarını async ya da defer ile (blocking="render" olmadan) ayrı olarak yükleyin.
  • Etkin varyantı belirtmek için <html> veya <body> üzerinde bir veri özelliği KULLANIN ve varyant stili için bu özelliğe göre ayarlanmış CSS seçicileri kullanın. Bu sayede, oluşturmayı engelleyen komut dosyasında doğrudan DOM manipülasyonu önlenir.
  • Analiz, izleme veya diğer görsel olmayan komut dosyalarında blocking="render" KULLANMAYIN. Yalnızca kullanıcının ilk boyamada gördüğü şeyi değiştirmesi gereken komut dosyaları oluşturmayı engellemelidir.
  • blocking="render"'yi eski titreme önleme snippet'leriyle BİRLEŞTİRMEYİN. İkisi de aynı sorunu çözer. İkisini de kullanmak gereksiz gecikmelere neden olur.

Yedek Stratejiler

blocking özelliği tüm tarayıcılarda desteklenmez. Bu özelliği desteklemeyen tarayıcılarda özellik yok sayılır ve komut dosyası varsayılan davranışıyla (yukarıdaki örneklerde async) yüklenir. Bu durum, titremeye neden olabilir. Desteklenmeyen tarayıcılarda titremeyi önlemek için yedek gereklidir.

Yedek: Titreme Önleme Snippet'i

DO: Use a lightweight anti-flicker snippet as a fallback only when blocking="render" is not supported. Özellik algılama desteği ve yerel olarak işleyen tarayıcılarda yedek seçeneğini atlayın.

<head>
  <!--
    DO: Load the experiment script with blocking="render" for
    browsers that support it. This is the preferred approach.
  -->
  <script
    src="https://cdn.example.com/experiment-sdk.js"
    async
    blocking="render"
  ></script>

  <script>
    // DO: Only apply the anti-flicker fallback in browsers
    // that do not support blocking="render".
    if (!Object.hasOwn(HTMLScriptElement.prototype, 'blocking')) {
      // Hide the page until the experiment script runs.
      document.documentElement.classList.add('ab-loading');

      // DO: Set a timeout to reveal the page if the experiment
      // script takes too long. This prevents an indefinitely
      // blank page on slow connections. Adjust the timeout
      // to match your experiment SDK's expected load time.
      setTimeout(() => {
        document.documentElement.classList.remove('ab-loading');
      }, 4000);
    }
  </script>

  <style>
    /*
      DO: Use opacity to hide content during experiment loading.
      This is only applied when blocking="render" is unsupported.
    */
    .ab-loading {
      opacity: 0 !important;
    }
  </style>
</head>
// DO: In your experiment SDK's initialization callback,
// remove the fallback class to reveal the page.
function onExperimentReady() {
  document.documentElement.classList.remove('ab-loading');
}

Dikkat edilmesi gereken diğer noktalar

  1. Performansa Etkisi: blocking="render", görsel doğruluk için ilk boyama hızından ödün verir. Deneme komut dosyasının aşırı gecikmeye neden olmadığından emin olmak için Largest Contentful Paint (LCP) ve First Contentful Paint (FCP) değerlerini izleyin.
  2. Üçüncü Taraf Komut Dosyası Güvenilirliği: Deneme SDK'sı üçüncü taraf bir CDN'de barındırılıyorsa CDN kesintisi, oluşturmayı tamamen engelleyebilir. Tarayıcı kendi zaman aşımı bulgusal yöntemlerini (4 saniyeden uzun olabilir) uygular ancak blocking="render" için geliştirici tarafından kontrol edilen bir zaman aşımı yoktur. Üçüncü taraf sağlayıcının güçlü çalışma süresi garantileri olduğundan emin olun.
  3. Sunucu tarafı alternatifleri: Performans açısından kritik sayfalar için istemci tarafı test yerine sunucu tarafı A/B testini (sunucunun doğru varyantı doğrudan oluşturduğu) kullanabilirsiniz. Sunucu tarafı yaklaşımlar, oluşturmayı engelleme maliyeti olmadan titremeyi tamamen ortadan kaldırır. İstemci tarafı blocking="render" özelliğini yalnızca sunucu tarafı testinin mümkün olmadığı durumlarda kullanın.