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

Mariko Kosaka

Giriş, birleştiriciye geliyor

Bu, Chrome'un içine baktığımız ve bir web sitesini görüntülemek için kodumuzu nasıl işlediğini incelediğimiz 4 bölümlük blog serisinin sonuncusudur. Önceki yayında, oluşturma sürecine göz atıp derleyici hakkında bilgi edinmiştik. Bu yayında, kullanıcı girişi geldiğinde kompozitörün nasıl sorunsuz bir etkileşim sağladığını inceleyeceğiz.

Tarayıcı açısından giriş etkinlikleri

"Giriş etkinlikleri"ni duyduğunuzda yalnızca metin kutusuna yazma veya fare tıklamayı düşünebilirsiniz ancak tarayıcı açısından giriş, kullanıcıdan gelen herhangi bir hareket anlamına gelir. Fare tekerleği kaydırma bir giriş etkinliğidir ve dokunma veya fareyle üzerine gelme de bir giriş etkinliğidir.

Kullanıcının ekrana dokunması gibi bir hareketi olduğunda, hareketi ilk olarak tarayıcı işlemi alır. Ancak sekme içindeki içerikler oluşturma işlemi tarafından işlendiğinden tarayıcı işlemi, yalnızca bu hareketin nerede gerçekleştiğini bilir. Bu nedenle tarayıcı işlemi, etkinlik türünü (ör. touchstart) ve koordinatlarını oluşturucu işlemine gönderir. Oluşturucu işlemi, etkinlik hedefini bulup bağlı etkinlik dinleyicilerini çalıştırarak etkinliği uygun şekilde işler.

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

Oluşturucu, giriş etkinlikleri alır

Şekil 2: Görüntü alanı, sayfa katmanlarının üzerinde geziniyor

Önceki yayında, rasterleştirilmiş katmanları birleştirerek kompozitörün kaydırma işlemini nasıl sorunsuz bir şekilde gerçekleştirebileceğine bakmıştık. Sayfaya giriş etkinliği dinleyicisi eklenmemişse Oluşturucu iş parçacığı, ana iş parçacığından tamamen bağımsız yeni bir birleşik çerçeve oluşturabilir. Ancak sayfaya bazı etkinlik dinleyicileri eklenmişse ne olur? Oluşturucu iş parçacığı, etkinliğin işlenmesi gerekip gerekmediğini nasıl anlar?

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

JavaScript'i çalıştırmak ana iş parçacığının işi olduğundan, bir sayfa birleştirilirken birleştirici iş parçacığı, sayfanın etkinlik işleyicilerinin eklendiği bir bölgeyi "Hızlı Kaydırılabilir Olmayan Bölge" olarak işaretler. Bu bilgilere sahip olan derleyici iş parçacığı, etkinlik söz konusu bölgede gerçekleşirse giriş etkinliğini ana iş parçacığına gönderebilir. Giriş etkinliği bu bölgenin dışından gelirse birleştirici iş parçacığı, ana iş parçacığı beklemeden yeni kareyi birleştirmeye devam eder.

Sınırlı, hızlı kaydırılabilir olmayan bölge
Şekil 3: Hızlı kaydırılabilir olmayan bölgeye yapılan girişin şeması

Etkinlik işleyicileri yazarken dikkat edilmesi gerekenler

Web geliştirmede sık kullanılan bir etkinlik işleme kalıbı, etkinlik yetkilendirmesidir. Etkinlikler balonlaştığından en üstteki öğeye bir etkinlik işleyici ekleyebilir ve görevleri etkinlik hedefine göre devredebilirsiniz. Aşağıdaki gibi kodlar 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 kalıbının ergonomisi caziptir. Ancak bu koda tarayıcının bakış açısından bakarsanız sayfanın tamamı artık hızlı kaydırılabilir olmayan bir bölge olarak işaretlenmiştir. Bu, uygulamanız sayfanın belirli bölümlerinden gelen girişleri dikkate almamasına rağmen, derleyici iş parçacığının ana iş parçacığıyla iletişim kurması ve her giriş etkinliği geldiğinde onu beklemesi gerektiği anlamına gelir. Bu nedenle, derleyicinin sorunsuz kaydırma özelliği devre dışı bırakılır.

Sayfanın tamamı, hızlı kaydırılabilir olmayan bölge
Şekil 4: Sayfanın tamamını kapsayan hızlı kaydırılabilir olmayan bölgeye yapılan girişin şeması

Bunun olmasını önlemek için etkinlik dinleyicinize passive: true seçenekleri iletebilirsiniz. Bu, tarayıcıya ana iş parçacığında etkinliği dinlemeye devam etmek istediğinizi ancak derleyicinin yeni kareyi de derleyebileceğini belirtir.

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 kısmının yatay kaydırmaya sabitlendiği bir web sayfası

Bir sayfada, kaydırma yönünü yalnızca yatay kaydırmayla sınırlamak istediğiniz bir kutu olduğunu varsayalım.

İşaretçi etkinliğinizde passive: true seçeneğini kullandığınızda sayfa kaydırma düzgün olabilir ancak kaydırma yönünü sınırlamak için preventDefault yapmak istediğiniz sırada 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 kaldırmak için touch-action gibi bir CSS kuralı da kullanabilirsiniz.

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

Etkinlik hedefini bulma

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

Oluşturucu iş parçacığı ana iş parçacığına bir giriş etkinliği gönderdiğinde ilk olarak etkinlik hedefini bulmak için bir isabet testi çalıştırılır. İsabet testi, etkinliğin gerçekleştiği nokta koordinatlarının altında ne olduğunu bulmak için oluşturma sürecinde oluşturulan boyama kaydı verilerini kullanır.

Ana iş parçacığına etkinlik dağıtımını en aza indirme

Önceki yayında, tipik ekranımızın ekranı saniyede 60 kez nasıl yenilediğini ve sorunsuz animasyon için ritmi nasıl yakalamamız gerektiğini ele almıştık. Giriş için, tipik bir dokunmatik ekranlı cihaz saniyede 60-120 kez dokunma etkinliği, tipik bir fare ise saniyede 100 kez etkinlik sağlar. Giriş etkinliği, ekranımızın yenileyebileceğinden daha yüksek doğruluğa sahiptir.

touchmove gibi sürekli bir etkinlik ana iş parçacığına saniyede 120 kez gönderilirse ekranın yenilenme hızına kıyasla aşırı miktarda isabet testi ve JavaScript yürütme işlemi tetiklenebilir.

filtrelenmemiş etkinlikler
Şekil 7: Çerçeve zaman çizelgesini dolduran ve sayfadaki takılmalara neden olan etkinlikler

Chrome, ana iş parçacığına yapılan aşırı çağrıları en aza indirmek için sürekli etkinlikleri (wheel, mousewheel, mousemove, pointermove, touchmove gibi) birleştirir ve dağıtımı bir sonraki requestAnimationFrame'den hemen öncesine kadar geciktirir.

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

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

Kare içi etkinlikleri almak için getCoalescedEvents öğesini kullanın

Çoğu web uygulamasında, birleştirilmiş etkinlikler iyi bir kullanıcı deneyimi sunmak için yeterlidir. Ancak çizim uygulaması gibi şeyler oluşturuyor ve touchmove koordinatlarına göre bir yol yerleştiriyorsanız düzgün bir çizgi çizmek için aradaki koordinatları kaybedebilirsiniz. Bu durumda, birleştirilen etkinlikler hakkında bilgi edinmek için işaretçi etkinliğindeki getCoalescedEvents yöntemini kullanabilirsiniz.

getCoalescedEvents
Şekil 9: Sol tarafta düzgün dokunma hareketi yolu, sağ tarafta 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 seride, web tarayıcısının işleyiş mekanizmasını ele aldık. DevTools'un neden etkinlik işleyicinize {passive: true} eklemenizi önerdiğini veya komut dosyası etiketinize neden async özelliğini yazabileceğinizi hiç düşünmediyseniz bu serinin, bir tarayıcının daha hızlı ve sorunsuz bir web deneyimi sunmak için bu bilgilere neden ihtiyaç duyduğuna dair biraz açıklık getirdiğini umuyoruz.

Lighthouse'u kullanma

Kodunuzun tarayıcıya uygun olmasını istiyorsanız ancak nereden başlayacağınızı bilmiyorsanız Lighthouse'u kullanabilirsiniz. Bu araç, herhangi bir web sitesini denetleyen ve nelerin doğru yapıldığını, nelerin iyileştirilmesi gerektiğini gösteren bir rapor sunar. Denetim listesini okumak, bir tarayıcının ne tür konulara önem verdiği hakkında da fikir edinmenize yardımcı olur.

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

Performans ayarlamaları farklı siteler için değişiklik gösterebilir. Bu nedenle, sitenizin performansını ölçmeniz ve siteniz için en uygun seçeneğe karar vermeniz önemlidir. Chrome Geliştirme Araçları Ekibi, sitenizin performansını ölçme ile ilgili birkaç eğitim içeriği sunmaktadır.

Sitenize Özellik Politikası ekleme

Bir adım daha ileri gitmek istiyorsanız projenizi oluştururken size yol gösterebilecek yeni bir web platformu özelliği olan Özellik Politikası'nı kullanabilirsiniz. Özellik politikasını etkinleştirmek, uygulamanızın belirli bir şekilde davranmasını sağlar ve hata yapmanızı önler. Örneğin, uygulamanızın hiçbir zaman ayrıştırmayı engellemediğinden emin olmak istiyorsanız uygulamanızı senkronize komut dosyaları politikasında çalıştırabilirsiniz. sync-script: 'none' etkinleştirildiğinde, ayrıştırıcıyı engelleyen JavaScript'in yürütülmesi engellenir. Bu, kodunuzun herhangi birinin ayrıştırıcıyı engellemesini önler ve tarayıcı, ayrıştırıcıyı duraklatma konusunda endişelenmemelidir.

Son adım

teşekkür ederim

Web sitesi oluşturmaya başladığımda neredeyse tek endişem kodumu nasıl yazacağım ve daha üretken olmama neyin yardımcı olacağıydı. Bunlar önemli olsa da, yazdığımız kodun tarayıcı tarafından nasıl alındığını da düşünmemiz gerekir. Modern tarayıcılar, kullanıcılara daha iyi bir web deneyimi sunmanın yollarına yatırım yapmaya devam etmektedir. Kodumuzu düzenleyerek tarayıcıya yardımcı olmak, kullanıcı deneyiminizi de iyileştirir. Tarayıcılara karşı nazik olma yolculuğumda bana katılacağınızı umuyorum.

Alex Russell, Paul Irish, Meggin Kearney, Eric Bidelman, Mathias Bynens, Addy Osmani, Kinuko Yasuda, Nasko Oskov ve Charlie Reis dahil (ancak bunlarla sınırlı olmamak üzere) bu serinin ilk taslaklarını inceleyen herkese çok teşekkür ederiz.

Bu seriyi beğendiniz mi? Gelecekteki bir yayınımız için sorularınız veya önerileriniz varsa aşağıdaki yorum bölümünden veya Twitter'daki @kosamari hesabından bizimle iletişime geçebilirsiniz.