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 üst öğeye göre açık veya örtük boyutlandırma bilgilerine sahiptir. 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üzenleme, genellikle dokümanın tamamı için geçerlidir.
- DOM öğelerinin sayısı performansı etkiler. Mümkün olduğunda düzeni tetiklemekten kaçınmalısınız.
- Zorunlu eşzamanlı düzenlerden ve düzen taşmasından kaçının. Stil değerlerini okuyup stil değişiklikleri yapın.
Düzenin etkileşim gecikmesi üzerindeki etkileri
Kullanıcı sayfayla etkileşimde bulunduğunda bu etkileşimler olabildiğince 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. Görsel güncellemeler, bu hedefe ulaşmak için bir miktar düzen çalışması gerektirebilir.
Web sitenizin INP'sini mümkün olduğunca düşük tutmak için, sayfa düzeninden mümkün olduğunca kaçınmak önemlidir. 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, "Kaydet"i tıklayın ve sitenizle etkileşime geçin. Kaydı durdurduğunuzda sitenizin nasıl performans gösterdiğine dair bir döküm 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. Ayrıca, Geliştirici Araçları'nın ağaç boyutunu (bu örnekte 1.618 öğe) ve kaç tane düğümün düzene ihtiyacı olduğunu (bu örnekte 5 tane) belirteceğ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üzen kullanmaktan kaçınamayacağınız durumlarda, düzen maliyetinin DOM'un boyutuyla ilişkili olduğunu unutmayın. İkisi arasındaki ilişki sıkı sıkıya bağlı olmasa da, daha büyük DOM'ler 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ışır, ardından stil hesaplamaları, sonra düzen. 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 sorusunu yanıtlamak için tarayıcının önce stil değişikliğini (super-big
sınıfının eklenmesi nedeniyle) uygulaması, ardından düzeni çalıştırması gerekir. Ancak o zaman 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 uygulamanız ve ardından değerleri sorgulamanız gerekmez. Son karenin değerlerini kullanmak 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 örnek için düzeltme, değerleri tekrar okuyup 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 FastDOM'u kullanabilirsiniz. Bu API, okuma ve yazma işlemlerinizi sizin için otomatik olarak gruplandırır ve yanlışlıkla zorunlu senkronize düzenler veya düzen karmaşası tetiklemenizi önler.