Modern web tarayıcısına yakından bakış (4. bölüm)

Mariko Kosaka

Giriş, Birleştiriciye geliyor

Bu, Chrome'un içine odaklanan 4 bölümlük blog dizisinin son bölümüdür. Chrome'un, bir web sitesini görüntülemek için kodumuzu nasıl işlediğini araştırıyoruz. Önceki gönderide, oluşturma sürecini ele aldık ve birleştirici hakkında bilgi edindik. Bu gönderide, kullanıcı girişi geldiğinde düzenleyicinin nasıl sorunsuz etkileşim sağladığına bakacağız.

Etkinlikleri tarayıcının bakış açısından girme

"Giriş etkinlikleri" ifadesini duyduğunuzda yalnızca metin kutusuna giriş yapma veya fare tıklamasını düşünebilirsiniz, ancak tarayıcı açısından bakıldığında giriş, kullanıcının yaptığı herhangi bir hareket anlamına gelir. Fare tekerleğiyle kaydırma bir giriş etkinliğidir ve dokunma veya fareyle üzerine gelme işlemleri de bir giriş etkinliğidir.

Ekranda dokunma gibi bir kullanıcı hareketi gerçekleştiğinde, hareketi ilk olarak tarayıcı işlemi alır. Bununla birlikte, tarayıcı işlemi yalnızca bir sekmenin içindeki içerik oluşturucu işlemi tarafından işlendiği için bu hareketin nerede gerçekleştiğini bilir. Dolayısıyla tarayıcı işlemi, etkinlik türünü (touchstart gibi) ve koordinatlarını oluşturucu işlemine gönderir. Oluşturucu işlemi, etkinlik hedefini bularak ve ekli etkinlik işleyicileri çalıştırarak etkinliği uygun şekilde ele alır.

giriş etkinliği
Şekil 1: Tarayıcı işlemi üzerinden oluşturucu işlemine yönlendirilen giriş etkinliği

Toplayıcı, giriş etkinliklerini alır

Şekil 2: Sayfa katmanlarının üzerine gelen görünüm

Önceki yayında, birleştiricinin gözetilmiş katmanları birleştirerek kaydırma işlemini nasıl sorunsuz gerçekleştirebileceğini dikkate aldık. Sayfaya hiçbir giriş etkinliği işleyicisi eklenmemişse Birleştirici iş parçacığı ana iş parçacığından tamamen bağımsız olarak yeni bir birleşik çerçeve oluşturabilir. Peki sayfaya bazı etkinlik dinleyicileri eklenmiş olsaydı ne olur? Birleştirici iş parçacığı, etkinliğin işlenmesi gerekip gerekmediğini nasıl öğrenir?

Hızlı olmayan kaydırılabilir bölgeyi anlama

JavaScript çalıştırmak ana iş parçacığının işi olduğundan, bir sayfa birleştirildiğinde birleştirici iş parçacığı sayfanın "Hızlı Olmayan Kaydırılabilir Bölge" olarak eklenmiş etkinlik işleyicilere sahip bir bölgesini işaretler. Bu bilgileri alan birleştirici iş parçacığı, etkinlik ilgili bölgede gerçekleşirse giriş etkinliğinin ana iş parçacığına gönderilmesini sağlayabilir. Giriş etkinliği bu bölgenin dışından geliyorsa birleştirici iş parçacığı ana iş parçacığını beklemeden yeni çerçeve oluşturmaya devam eder.

hızlı kaydırılamayan sınırlı bölge
Şekil 3: Hızlı olmayan kaydırılabilir bölgeye ait açıklanan giriş şeması

Etkinlik işleyicileri yazarken dikkatli olun

Web geliştirmede yaygın olarak kullanılan bir olay işleme kalıbı, etkinlik yetkilendirmesidir. Etkinlikler baloncuğundan en üstteki öğeye bir etkinlik işleyici ekleyebilir ve etkinlik hedefine göre görevler atayabilirsiniz. Aşağıdaki gibi bir kod görmüş veya yazmış olabilirsiniz.

document.body.addEventListener('touchstart', event => {
    if (event.target === area) {
        event.preventDefault();
    }
});

Tüm öğeler için yalnızca bir etkinlik işleyici yazmanız gerektiğinden, bu etkinlik yetkilendirme modelinin ergonomisi caziptir. Ancak bu koda tarayıcının bakış açısından bakarsanız sayfanın tamamı hızlı kaydırılamayan bir bölge olarak işaretlenir. Yani, uygulamanız sayfanın belirli bölümlerinden gelen girişleri önemsemiyor olsa bile, birleştirici iş parçacığının ana iş parçacığıyla iletişim kurması ve bir giriş etkinliği her geldiğinde bunu beklemesi gerekir. Bu nedenle, birleştiricinin sorunsuz kaydırma yeteneği ortadan kalkar.

tam sayfa hızlı kaydırılamayan bölge
Şekil 4: Tüm sayfayı kapsayan, hızlı kaydırılamayan bir bölgeye yönelik açıklanan girişin şeması

Bu durumu azaltmak için etkinlik işleyicinizde passive: true seçeneklerini iletebilirsiniz. Bu, tarayıcıya ana iş parçacığında etkinliği dinlemeyi hâlâ istediğinize dair ipucu verir, ancak birleştirici devam edip yeni çerçeve de oluşturabilir.

document.body.addEventListener('touchstart', event => {
    if (event.target === area) {
        event.preventDefault()
    }
 }, {passive: true});

Etkinliğin iptal edilebilir olup olmadığını kontrol etme

sayfa kaydırma
Şekil 5: Sayfanın bir bölümü yatay kaydırmaya sabitlenmiş web sayfası

Bir sayfada, kaydırma yönünü yalnızca yatay kaydırmayla sınırlamak istediğiniz bir kutunuz olduğunu düşünün.

İşaretçi etkinliğinizde passive: true seçeneğini kullanmak, sayfa kaydırmanın sorunsuz olacağı anlamına gelir. Ancak kaydırma yönünü sınırlamak için preventDefault istediğiniz zamanda dikey kaydırma başlamış olabilir. event.cancelable yöntemini kullanarak bunu kontrol edebilirsiniz.

document.body.addEventListener('pointermove', event => {
    if (event.cancelable) {
        event.preventDefault(); // block the native scroll
        /*
        *  do what you want the application to do here
        */
    }
}, {passive: true});

Alternatif olarak, etkinlik işleyiciyi tamamen ortadan kaldırmak için touch-action gibi bir CSS kuralı kullanabilirsiniz.

#area {
  touch-action: pan-x;
}

Etkinlik hedefini bulma

isabet testi
Şekil 6: Boya kayıtlarına bakan ve x.y noktasında neyin çizildiğini soran ana iş parçacığı

Birleştirici iş parçacığı ana iş parçacığına bir giriş etkinliği gönderdiğinde çalıştırılacak ilk şey etkinlik hedefini bulmak için bir isabet testidir. İsabet testi, etkinliğin gerçekleştiği nokta koordinatlarının altında ne olduğunu bulmak için oluşturma işleminde oluşturulan boya kaydı verilerini kullanır.

Ana iş parçacığına etkinlik gönderme sayısını en aza indirme

Bir önceki gönderide, normal görüntümüzün saniyede 60 kez ekranı nasıl yenilediğinden ve akıcı bir animasyon için bu kadansa nasıl uyum sağlamamız gerektiğinden bahsettik. Tipik bir dokunmatik ekranlı cihaz, giriş için saniyede 60-120 kez dokunma etkinliği, tipik bir fare ise etkinlikleri saniyede 100 kez iletir. Giriş etkinliğinin netliği, ekranımızın yenilenebileceğinden daha yüksek.

touchmove gibi sürekli bir etkinlik ana iş parçacığına saniyede 120 kez gönderilirse ekranın yenilenme hızıyla karşılaştırıldığında çok fazla isabet testi ve JavaScript yürütme işlemini tetikleyebilir.

filtrelenmemiş etkinlikler
Şekil 7: Çerçeve zaman çizelgesine taşan etkinlikler, sayfa olumsuzluğuna neden olur

Chrome, ana iş parçacığına yapılan aşırı sayıda çağrıyı en aza indirmek için sürekli etkinlikleri (ör. wheel, mousewheel, mousemove, pointermove, touchmove) bir araya getirir ve bir sonraki requestAnimationFrame tarihine kadar dağıtımı geciktirir.

birleştirilmiş etkinlikler
Şekil 8: Önceki zaman çizelgesiyle aynı ancak etkinlik birleşip gecikiyor

keydown, keyup, mouseup, mousedown, touchstart ve touchend gibi ayrı etkinlikler hemen gönderilir.

Çerçeve içi etkinlikleri almak için getCoalescedEvents kullanın

Çoğu web uygulamasında, birleştirilen etkinlikler iyi bir kullanıcı deneyimi sağlamak için yeterli olacaktır. Ancak, uygulama çizimi ve touchmove koordinatlarına göre bir yol çizme gibi işlemler yapıyorsanız yumuşak bir çizgi çizmek için koordinatlar arasında kaybolabilirsiniz. Bu durumda, bu birleştirilen etkinlikler hakkında bilgi almak için işaretçi etkinliğinde getCoalescedEvents yöntemini kullanabilirsiniz.

getCoalescedEvents
Şekil 9: Solda yumuşak dokunma hareket yolu, sağda birleştirilmiş sınırlı yol
window.addEventListener('pointermove', event => {
    const events = event.getCoalescedEvents();
    for (let event of events) {
        const x = event.pageX;
        const y = event.pageY;
        // draw a line using x and y coordinates.
    }
});

Sonraki adımlar

Bu dizide, bir web tarayıcısının iç işleyişini ele aldık. DevTools'un etkinlik işleyicinize neden {passive: true} eklemenizi önerdiğini veya komut dosyası etiketinize neden async özelliğini yazabileceğinizi daha önce hiç düşünmediyseniz bu serinin, daha hızlı ve sorunsuz bir web deneyimi sunmak için tarayıcıların neden bu bilgilere ihtiyaç duyduğuna ışık tutacağını umuyorum.

Lighthouse'u kullanma

Kodunuzun tarayıcı için iyi olmasını istiyorsanız ancak nereden başlayacağınızı bilmiyorsanız, Lighthouse herhangi bir web sitesinin denetimini çalıştıran ve neyin doğru yapıldığı ve nelerin iyileştirilmesi gerektiği konusunda size rapor sağlayan bir araçtır. Denetim listesini okumak, tarayıcının ne tür konulara önem verdiğine de dair fikir edinmenizi sağlar.

Performansı nasıl ölçeceğinizi öğrenin

Performans değişiklikleri farklı siteler için değişiklik gösterebilir. Bu nedenle, sitenizin performansını ölçmeniz ve siteniz için en uygun olana karar vermeniz önemlidir. Chrome Geliştirici Araçları ekibi, sitenizin performansını nasıl ölçeceğiniz konusunda birkaç eğitici sunuyor.

Sitenize Özellik Politikası ekleyin

Ek bir adım atmak istiyorsanız Özellik Politikası, projenizi oluştururken size yardımcı olabilecek yeni bir web platformu özelliğidir. Özellik politikasını etkinleştirmek, uygulamanızın belirli davranışlarını garanti eder ve hata yapmanızı önler. Örneğin, uygulamanızın ayrıştırmayı hiçbir zaman engellememesini istiyorsanız uygulamanızı eşzamanlı komut dosyaları politikasında çalıştırabilirsiniz. sync-script: 'none' etkinleştirildiğinde ayrıştırıcı engelleyici JavaScript'in yürütülmesi engellenir. Bu, kodunuzun ayrıştırıcıyı engellemesini önler ve tarayıcının ayrıştırıcıyı duraklatma konusunda endişe duymasına gerek kalmaz.

Son adım

teşekkür ederim

Web siteleri oluşturmaya başladığımda, neredeyse yalnızca kodumu nasıl yazacağıma ve daha üretken olmama ne yardımcı olacağına dikkat ediyordum. Bunlar önemlidir, ancak tarayıcının yazdığımız kodu nasıl aldığını da düşünmemiz gerekir. Modern tarayıcılar, kullanıcılara daha iyi bir web deneyimi sunma yollarına yatırım yapmaya devam etmektedir. Kodumuzu düzenleyerek tarayıcıya karşı nazik olmak da kullanıcı deneyimini iyileştirir. Umarım tarayıcılara karşı nazik olma macerasında bana katılırsınız.

Bu serinin ilk taslaklarını incelemiş olan herkese çok teşekkür ederiz. Bunlardan bazıları: Alex Russell, Paul Ireland, Meggin Kearney, Eric Bidelman, Mathias Bynens, Addy Osmani, Kinuko ReNsue}, Nsuda. .

Bu seriyi beğendiniz mi? Gelecekteki gönderimizle ilgili sorularınız veya önerileriniz varsa aşağıdaki yorum bölümünden ya da Twitter'daki @kosamari adresinden bize yanıt verebilirsiniz.