Düzen, tarayıcının öğelere ilişkin geometrik bilgileri (öğelerin boyutları ve sayfadaki konumları) belirlediği yerdir. Her öğe, kullanılan CSS'ye, öğenin içeriğine veya üst öğeye göre açık veya örtük boyutlandırma bilgilerine sahiptir. Bu işleme Chrome'da düzen adı verilir.
Düzen, tarayıcının öğelerle ilgili geometrik bilgileri (öğelerin boyutu ve sayfadaki konumu) belirlediği yerdir. Her öğe, kullanılan CSS'ye, öğenin içeriğine veya bir üst öğeye bağlı olarak açık veya örtülü boyutlandırma bilgilerine sahip olur. Bu işleme Chrome (ve Edge gibi türetilmiş tarayıcılar) ile Safari'de Düzen adı verilir. Firefox'ta bu işleme yeniden akış denir ancak süreç aynıdır.
Stil hesaplamalarına benzer şekilde, düzen maliyetiyle ilgili acil sorunlar şunlardır:
- Sayfanın DOM boyutunun bir yan ürünü olan, düzen gerektiren öğelerin sayısı.
- Bu düzenlerin karmaşıklığı.
Özet
- Düzen, etkileşim gecikmesini doğrudan etkiler
- Düzen normalde dokümanın tamamını kapsar.
- DOM öğelerinin sayısı performansı etkiler. Mümkün olduğunda düzeni tetiklemekten kaçınmalısınız.
- Zorunlu senkronize düzenleri ve düzen karmaşasını önleyin; stil değerlerini okuyup stil değişiklikleri yapın.
Düzenin etkileşim gecikmesi üzerindeki etkileri
Kullanıcı sayfayla etkileşime geçtiğinde bu etkileşimler mümkün olduğunca hızlı olmalıdır. Bir etkileşimin tamamlanması için geçen süre (tarayıcının etkileşimin sonuçlarını göstermek için bir sonraki kareyi sunduğunda sona erer) etkileşim gecikmesi olarak bilinir. Bu, sayfa performansının Sonraki Boyamayla Etkileşim metriğinin ölçtüğü bir yönüdür.
Tarayıcının, kullanıcı etkileşimine yanıt olarak bir sonraki kareyi sunması için geçen süre, etkileşimin sunma gecikmesi olarak bilinir. Etkileşimin amacı, kullanıcıya bir şey olduğunu bildirmek için görsel geri bildirim sağlamaktır ve görsel güncellemeler bu hedefe ulaşmak için bir miktar sayfa düzeni çalışması içerebilir.
Web sitenizin INP'sini mümkün olduğunca düşük tutmak için mümkün olduğunda düzen kullanmaktan kaçının. Düzenlemeden tamamen kaçınmak mümkün değilse tarayıcının bir sonraki kareyi hızlı bir şekilde sunabilmesi için bu düzenleme çalışmasını sınırlamak önemlidir.
Mümkün olduğunda düzenden kaçının
Stil değiştirdiğinizde tarayıcı, değişikliklerden herhangi birinin düzenin hesaplanmasını ve bu oluşturma ağacının güncellenmesini gerektirip gerektirmediğini kontrol eder. Genişlik, yükseklik, sol veya üst gibi "geometrik özelliklerde" yapılan tüm değişiklikler için düzen gerekir.
.box {
width: 20px;
height: 20px;
}
/**
* Changing width and height
* triggers layout.
*/
.box--expanded {
width: 200px;
height: 350px;
}
Düzenleme, neredeyse her zaman dokümanın tamamına uygulanır. Çok sayıda öğeniz varsa tümünün konumlarını ve boyutlarını belirlemek uzun zaman alır.
Düzenlemeden kaçınmak mümkün değilse ne kadar sürdüğünü görmek ve düzenin darboğazın nedeni olup olmadığını belirlemek için Chrome Geliştirici Araçları'nı tekrar kullanmanız gerekir. Öncelikle Geliştirici Araçları'nı açın, Zaman Çizelgesi sekmesine gidin, Kayıt'a basın ve sitenizle etkileşime geçin. Kaydı durdurduğunuzda sitenizin performansının dökümünü görürsünüz:
Yukarıdaki örnekteki izlemeye baktığımızda, her kare için düzen içinde 28 milisaniyeden fazla zaman harcandığını görüyoruz. Bu süre, bir animasyonda ekrana kare göstermek için 16 milisaniyemiz olduğunda çok yüksektir. DevTools'un size ağaç boyutunu (bu durumda 1.618 öğe) ve kaç düğümün düzene ihtiyaç duyduğunu (bu durumda 5) da bildirdiğini görebilirsiniz.
Buradaki genel tavsiyenin, mümkün olduğunda düzenden kaçınmak olduğunu unutmayın. Ancak düzenden her zaman kaçınmak mümkün değildir. Düzenden kaçınamadığınız durumlarda, düzen maliyetinin DOM boyutuyla bir ilişkisi olduğunu unutmayın. İkisi arasındaki ilişki sıkı bir şekilde bağlı olmasa da daha büyük DOM'lar genellikle daha yüksek düzen maliyetlerine neden olur.
Zorunlu senkronize düzenlerden kaçının
Çerçeveyi ekrana gönderme sırası şu şekildedir:
Önce JavaScript çalıştırılır, sonra stil hesaplamaları, sonra düzen çalıştırılır. Ancak JavaScript ile bir tarayıcıda düzeni daha önce gerçekleştirmeye zorlamak mümkündür. Buna zorunlu senkronize düzen denir.
Unutmayın, JavaScript çalışırken önceki çerçevedeki tüm eski düzen değerleri bilinir ve sorgulanmaya hazırdır. Örneğin, karenin başında bir öğenin yüksekliğini (bunu "kutu" olarak adlandıralım) yazmak istiyorsanız aşağıdaki gibi bir kod yazabilirsiniz:
// Schedule our function to run at the start of the frame:
requestAnimationFrame(logBoxHeight);
function logBoxHeight () {
// Gets the height of the box in pixels and logs it out:
console.log(box.offsetHeight);
}
Kutunun stillerini yüksekliğini istemeden önce değiştirirseniz sorun yaşanır:
function logBoxHeight () {
box.classList.add('super-big');
// Gets the height of the box in pixels and logs it out:
console.log(box.offsetHeight);
}
Şimdi, yükseklik sorununu yanıtlamak için tarayıcı önce stil değişikliğini (super-big
sınıfı eklendiğinden) uygulamalı, sonra düzeni çalıştırmalıdır. Yalnızca bu durumda doğru yüksekliği döndürebilir. Bu gereksiz ve pahalı bir işlemdir.
Bu nedenle, stil okumalarınızı her zaman toplu olarak yapmalı ve önce bunları (tarayıcının önceki çerçevenin düzen değerlerini kullanabileceği şekilde) yapmalı, ardından tüm yazma işlemlerini yapmalısınız:
Yukarıdaki işlev doğru şekilde yapıldığında şu şekilde olur:
function logBoxHeight () {
// Gets the height of the box in pixels and logs it out:
console.log(box.offsetHeight);
box.classList.add('super-big');
}
Çoğu durumda, stilleri uygulayıp ardından değerleri sorgulamanız gerekmez. Son karenin değerlerini kullanmanız yeterlidir. Stil hesaplamalarını ve düzeni eşzamanlı olarak ve tarayıcının istediğinden daha önce çalıştırmak olası darboğazlardır ve normalde yapmak istemeyeceğiniz bir şey değildir.
Düzenin çok hızlı değişmesini önleyin
Zorunlu senkronize düzenleri daha da kötüleştirmenin bir yolu vardır: Bunları hızlı bir şekilde arka arkaya yapın. Şu koda göz atın:
function resizeAllParagraphsToMatchBlockWidth () {
// Puts the browser into a read-write-read-write cycle.
for (let i = 0; i < paragraphs.length; i++) {
paragraphs[i].style.width = `${box.offsetWidth}px`;
}
}
Bu kod, bir paragraf grubunu döngü şeklinde işler ve her paragrafın genişliğini "kutu" adlı bir öğenin genişliğiyle eşleşecek şekilde ayarlar. Bu kod yeterince zararsız görünse de sorun, döngünün her iterasyonunda bir stil değerinin (box.offsetWidth
) okunması ve ardından bu değerin bir paragrafın genişliğini güncellemek için hemen kullanılmasıdır (paragraphs[i].style.width
). Döngünün bir sonraki iterasyonunda, offsetWidth
son kez istendiğinden (önceki iterasyonda) stillerin değiştiğini hesaba katması gerekir. Bu nedenle, stil değişikliklerini uygulamalı ve düzeni çalıştırmalıdır. Bu işlem her iterasyonda gerçekleşir.
Bu örneğin çözümü, değerleri bir kez daha okumak ve ardından yazmaktır:
// Read.
const width = box.offsetWidth;
function resizeAllParagraphsToMatchBlockWidth () {
for (let i = 0; i < paragraphs.length; i++) {
// Now write.
paragraphs[i].style.width = `${width}px`;
}
}
Güvenliği garanti etmek istiyorsanız okuma ve yazma işlemlerinizi sizin yerinize otomatik olarak gruplandıran ve zorunlu eşzamanlı düzenlerin veya düzen baskılarının yanlışlıkla tetiklenmesini önlemek üzere FastDOM'yi kullanabilirsiniz.