isInputPending() ile daha iyi JS planlaması

Yükleme performansı ile giriş duyarlılığı arasındaki dengeyi sağlamanıza yardımcı olabilecek yeni bir JavaScript API.

Nate Schloss
Nate Schloss
Andrew Comminos
Andrew Comminos

Hızlı yüklemek zor. Halihazırda içeriklerini oluşturmak için JS'den yararlanan siteler yük performansı ile giriş arasında bir denge kurmak duyarlılık: görüntülü reklamlar için gereken tüm işi hepsi aynı anda (daha iyi yükleme performansı, daha kötü giriş duyarlılığı) veya küçük görevlere ayırmanızı ve bu sayede giriş ve boyama (daha düşük yük performansı, daha iyi giriş (yanıt verme derecesi).

Bu dengeyi sağlama ihtiyacını ortadan kaldırmak için, Facebook önerdi ve uyguladı. olmadan yanıt vermeyi iyileştirmek için Chromium'daki isInputPending() API'yi çok önemli. Kaynak denemesiyle ilgili geri bildirimlere dayanarak . 87!

Tarayıcı uyumluluğu

Tarayıcı Desteği

  • Chrome: 87..
  • Kenar: 87..
  • Firefox: Desteklenmez..
  • Safari: desteklenmez..

Kaynak

isInputPending(), sürüm 87'den itibaren Chromium tabanlı tarayıcılarda kullanıma sunulmuştur. Başka hiçbir tarayıcı, API'yi gönderme niyetini göstermedi.

Arka plan

Günümüzün JS ekosistemindeki çoğu iş, ana iş parçacığı olan tek bir iş parçacığı üzerinde gerçekleştirilir. Bu, geliştiricilere sağlam bir yürütme modeli sağlar ancak kullanıcı deneyimi komut dosyası uzun bir süre boyunca çalışırsa (özellikle yanıt verebilirlik) önemli ölçüde etkilenebilir gerekir. Bir giriş etkinliği tetiklenirken sayfa çok fazla işlem yapıyorsa Örneğin, sayfa bu işlem tamamlanana kadar tıklama girişi etkinliğini işlemez gerekir.

Mevcut en iyi uygulama, bu sorunu, JavaScript'i daha küçük bloklara ayırın. Sayfa yüklenirken, ve ardından kontrolü geri vererek tarayıcıya devredildiğini gösterir. İlgili içeriği oluşturmak için kullanılan tarayıcı, giriş etkinlik sırasını kontrol edebilir ve sayfada öğrenmesi gerekir. Ardından, tarayıcı Eklenen JavaScript blokları. Bu işe yarar ancak başka sorunlara da yol açabilir.

Sayfa, tarayıcıya her kontrol sağladığında, sayfanın yeniden yüklenmesi biraz zaman alır giriş etkinlik sırasını kontrol etmek, etkinlikleri işlemek ve sonraki JavaScript bloğu. Tarayıcı etkinliklere daha hızlı yanıt verirken, sayfanın yüklenme süresi yavaşlar. Çok sık geri dönersek sayfa, çok yavaş yükleniyor. Daha az verim verirsek tarayıcının yapması daha uzun sürer. yanıt veriyor ve kullanıcıları hayal kırıklığına uğratıyor. Eğlenceli değil.

Uzun JS görevleri çalıştırdığınızda, tarayıcının etkinlikleri göndermek için daha az zamanı olduğunu gösteren bir şema.

Facebook'ta, en popüler şirketlerden biri olursa nasıl bir şey ortadan kaldıracak yeni bir yükleme yaklaşımı geliştiriyoruz. Biz Chrome'daki arkadaşlarımıza danıştık ve teklifimizi isInputPending() için. isInputPending() API, web'deki kullanıcı girişleri için kesintiler sağlar ve JavaScript'in tarayıcıya dönmeden girişi kontrol edebilir.

isInputPending() işlevini gösteren bir şema, JS'nizin yürütmeyi tarayıcıya tamamen geri döndürmeden bekleyen kullanıcı girişi olup olmadığını kontrol etmesini sağlar.

Bu API'ye gösterdiğiniz ilgiden dolayı Chrome'daki meslektaşlarımızla birlikte ve özelliği Chromium'da kullanıma sunabiliriz. Chrome'un yardımıyla yamalar, bir kaynak deneme sürecinin (Chrome'un değişiklikleri test etmesinin ve geliştiricilerden geri bildirim almasının bir yoludur) )

Kaynak denemesinden ve kanalın diğer üyelerinden geri bildirim aldık. W3C Web Performansı Çalışma Grubu ve API'de değişiklikler uyguladı.

Örnek: getiri planlayıcısı

Verilerinizi yüklemek için görüntüleme engelleme çalışmanız olduğunu örneğin bileşenlerden işaretleme oluşturma, asalları hariç tutma veya düzgün bir şekilde yükleniyor. Bunlardan her biri daha küçük adımlara çalışma öğesi. Planlayıcı modelini kullanarak processWorkQueue() fonksiyonunda yaptığımızı varsayalım:

const DEADLINE = performance.now() + QUANTUM;
while (workQueue.length > 0) {
  if (performance.now() >= DEADLINE) {
    // Yield the event loop if we're out of time.
    setTimeout(processWorkQueue);
    return;
  }
  let job = workQueue.shift();
  job.execute();
}

Daha sonra setTimeout() üzerinden yeni bir makro görevde processWorkQueue() çağrısı yaparak tarayıcının girişe biraz duyarlı kalmasını sağlar (yani etkinlik işleyicileri çalıştırma) ve aynı zamanda nispeten çalışmasını kesintisiz. Fakat başka bir iş nedeniyle uzun bir süre planladığımızda veya etkinlik döngüsünü kontrol etmek isteyen ya da fazladan QUANTUM milisaniye yaklaşık %10’luk bir artış sağlar.

Sorun değil ama daha iyi olabilir miyiz? Kesinlikle!

const DEADLINE = performance.now() + QUANTUM;
while (workQueue.length > 0) {
  if (navigator.scheduling.isInputPending() || performance.now() >= DEADLINE) {
    // Yield if we have to handle an input event, or we're out of time.
    setTimeout(processWorkQueue);
    return;
  }
  let job = workQueue.shift();
  job.execute();
}

navigator.scheduling.isInputPending() için çağrı sunarak şunları yapabiliriz: girişlere daha hızlı yanıt verirken, görüntüleme engelleme özelliğiyle de kesintisiz olarak çalışır. Müşteri kimliğinizle alakalı herhangi bir iş tamamlanana kadar girdi (örneğin, boyama) dışında, QUANTUM uzunluğunu da ekleyebilirsiniz.

Varsayılan olarak "sürekli"dir. etkinlikler isInputPending() öğesinden döndürülmez. Bu mousemove, pointermove ve diğerlerini içerir. Gelecekteki projelerinizde sorun değil. isInputPending() için bir nesne sağlayarak includeContinuous true olarak ayarlandı. Artık hazırsınız:

const DEADLINE = performance.now() + QUANTUM;
const options = { includeContinuous: true };
while (workQueue.length > 0) {
  if (navigator.scheduling.isInputPending(options) || performance.now() >= DEADLINE) {
    // Yield if we have to handle an input event (any of them!), or we're out of time.
    setTimeout(processWorkQueue);
    return;
  }
  let job = workQueue.shift();
  job.execute();
}

İşte bu kadar. React gibi çerçeveler, isInputPending() temel zamanlama kitaplıklarının benzer bir mantığına göre yürütülmesine neden olur. Umarız bu, Scrum ekibinizle, isInputPending() ürününden yararlanabilmek için bu çerçeveleri kullanan geliştiriciler kamera arkası görüntülerine yer verir.

Getiri her zaman kötü değildir

Daha az verim almanın her kullanım için doğru çözüm olmadığını unutmamak gerekir. dava açın. Tarayıcıya kontrolün geri verilmesi için oluşturma işlemi gerçekleştirmek ve diğer komut dosyalarını çalıştırmak gibi giriş etkinliklerini yapalım.

Tarayıcının beklemedeki öğeleri doğru şekilde ilişkilendiremediği durumlar vardır giriş etkinlikleri. Özellikle çapraz kökenler için karmaşık klipler ve maskeler oluşturmak, iframe'ler yanlış negatifler bildirebilir (ör. isInputPending() beklenmedik bir şekilde dönebilir) false (yanlış) değerini alır. Her şeyin yolunda gitmesi halinde yeterli miktarda ve stilize edilmiş alt çerçevelerle etkileşim kurmanız gerekir.

Bir etkinlik döngüsünü paylaşan diğer sayfalara da dikkat edin. Bu tür platformlarda birden fazla kaynağın aynı etkinliği paylaşması yaygın bir uygulamadır. döngüde bulabilirsiniz. GirişisInputPending()true çapraz kaynak çerçevesini yorabilir ve dolayısıyla arka plana alınmış sayfalar, yanıt verme hızını artırır. Getiriyi azaltmayı, ertelemeyi ya da daha sık arka planda çalışırken Sayfa Görünürlük API'sini kullanın.

isInputPending() ürününü dikkatli bir şekilde kullanmanızı öneririz. Herhangi bir önce kullanıcı engelleme çalışması yapar, ardından etkinlik döngüsünde getiri sağladığını görebilirsiniz. Uzun görevler zararlı olabilir.

Geri bildirim

  • Spesifikasyonlarla ilgili geri bildirim göndermek için is-input-pending deposudur.
  • @acomminos (spesifikasyon yazarlarından biri) ile iletişime geçin

Sonuç

isInputPending() kullanıma sunulmasından ve geliştiricilerin hemen kullanmaya başlamanız gerekiyor. Bu API, Facebook'un ilk kez bir platformdaki ve fikri geliştirme aşamasından standartların teklifine geçirerek bir tarayıcıda gönderim. Bunu başarmamıza yardımcı olan herkese teşekkür ederiz. ve Chrome'da, programı başlatmamıza yardımcı olan herkese göndereceğim!

Will H McMahan'ın hero fotoğrafı Lansmanı kaldırın.