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

Mariko Kosaka

Oluşturucu işleminin işleyiş şekli

Bu, tarayıcıların işleyişine odaklanan 4 bölümlük blog serisinin 3. bölümüdür. Daha önce çoklu işlem mimarisini ve gezinme akışını ele almıştık. Bu yayında, oluşturma işleminin içinde neler olduğuna bakacağız.

Oluşturucu işlemi, web performansının birçok yönünü etkiler. Oluşturucu sürecinde çok fazla işlem gerçekleştiği için bu yayında yalnızca genel bir bakış sunulmaktadır. Daha ayrıntılı bilgi edinmek isterseniz Web Temel Bilgileri'nin Performans bölümünde daha birçok kaynak bulabilirsiniz.

Oluşturucu işlemleri web içeriklerini işler

Oluşturucu işlemi, sekme içinde gerçekleşen her şeyden sorumludur. Bir oluşturma işleminde ana iş parçacığı, kullanıcıya gönderdiğiniz kodun çoğunu işler. Web çalışanı veya hizmet çalışanı kullanıyorsanız JavaScript'inizin bazı bölümleri bazen çalışan iş parçacıkları tarafından işlenir. Bir sayfayı verimli ve sorunsuz bir şekilde oluşturmak için bir oluşturucu ve raster iş parçacığı da oluşturucu işlemlerinde çalıştırılır.

Oluşturucu işleminin temel görevi, HTML, CSS ve JavaScript'i kullanıcının etkileşimde bulunabileceği bir web sayfasına dönüştürmektir.

Oluşturucu işlemi
Şekil 1: Ana iş parçacığı, çalışan iş parçacıkları, bir birleştirici iş parçacığı ve raster iş parçacığı içeren oluşturma işlemi

Ayrıştırma

DOM oluşturma

Oluşturucu işlem bir gezinme için bir taahhüt mesajı aldığında ve HTML verileri almaya başladığında ana mesaj dizisi, metin dizesini (HTML) ayrıştırmaya ve DocumentObject Model'e (DOM) dönüştürmeye başlar.

DOM, bir tarayıcının sayfanın dahili temsilidir. Ayrıca, web geliştiricinin JavaScript aracılığıyla etkileşim kurabileceği veri yapısı ve API'dir.

Bir HTML belgesinin DOM'a ayrıştırılması HTML Standardı tarafından tanımlanır. Bir tarayıcıya HTML beslemenin hiçbir zaman hata oluşturmadığını fark etmiş olabilirsiniz. Örneğin, eksik kapanış </p> etiketi geçerli bir HTML'dir. Hi! <b>I'm <i>Chrome</b>!</i> gibi hatalı işaretlemeler (b etiketi i etiketinden önce kapatılır) Hi! <b>I'm <i>Chrome</i></b><i>!</i> yazmışsınız gibi değerlendirilir. Bunun nedeni, HTML spesifikasyonunun bu hataları sorunsuz bir şekilde ele alacak şekilde tasarlanmış olmasıdır. Bu işlemlerin nasıl yapıldığını merak ediyorsanız HTML spesifikasyonunun "Ayrıştırıcıda hata işleme ve garip durumlara giriş" bölümünü okuyabilirsiniz.

Alt öğe yükleme

Web siteleri genellikle resim, CSS ve JavaScript gibi harici kaynaklar kullanır. Bu dosyaların ağdan veya önbellekten yüklenmesi gerekir. Ana iş parçacığı, DOM oluşturmak için ayrıştırma işlemi sırasında bulduğu öğeleri tek tek isteyebilir ancak hızlandırmak amacıyla "önyükleme tarayıcı" eşzamanlı olarak çalıştırılır. HTML dokümanında <img> veya <link> gibi öğeler varsa ön yükleme tarayıcı, HTML ayrıştırıcı tarafından oluşturulan jetonlara göz atar ve tarayıcı işlemindeki ağ iş parçacığına istek gönderir.

DOM
Şekil 2: HTML'yi ayrıştıran ve DOM ağacı oluşturan ana işleyici

JavaScript, ayrıştırmayı engelleyebilir

HTML ayrıştırıcı bir <script> etiketi bulduğunda HTML belgesinin ayrıştırmasını duraklatır ve JavaScript kodunu yüklemesi, ayrıştırması ve yürütmesi gerekir. Neden? Çünkü JavaScript, DOM yapısının tamamını değiştiren document.write() gibi öğeleri kullanarak belgenin şeklini değiştirebilir (HTML spesifikasyonundaki ayrıştırma modeline genel bakış bölümünde güzel bir şema vardır). Bu nedenle, HTML ayrıştırıcının HTML dokümanının ayrıştırılmasını devam ettirebilmek için JavaScript'in çalışmasını beklemesi gerekir. JavaScript yürütme sırasında neler olduğunu merak ediyorsanız V8 ekibinin bu konuyla ilgili konuşmaları ve blog yayınları mevcuttur.

Tarayıcıya kaynakları nasıl yüklemek istediğinizi belirtme

Web geliştiricileri, kaynakları düzgün bir şekilde yüklemek için tarayıcıya ipucu göndermenin birçok yolunu kullanabilir. JavaScript'inizde document.write() kullanılmıyorsa <script> etiketine async veya defer özelliğini ekleyebilirsiniz. Ardından tarayıcı, JavaScript kodunu eşzamansız olarak yükleyip çalıştırır ve ayrıştırmayı engellemez. Uygun olduğunda JavaScript modülü de kullanabilirsiniz. <link rel="preload">, tarayıcıya kaynağın mevcut gezinme için kesinlikle gerekli olduğunu ve en kısa sürede indirmek istediğinizi bildirmenin bir yoludur. Bu konuda daha fazla bilgiyi Kaynak Önceliklendirmesi – Tarayıcının Size Yardım Etmesini Sağlama başlıklı makalede bulabilirsiniz.

Stil hesaplama

Sayfa öğelerine CSS'de stil uygulayabileceğimiz için sayfanın nasıl görüneceğini bilmek için DOM'a sahip olmak yeterli değildir. Ana iş parçacığı CSS'yi ayrıştırır ve her DOM düğümü için hesaplanan stili belirler. Bu, CSS seçicilere göre her öğeye ne tür bir stilin uygulandığıyla ilgili bilgilerdir. Bu bilgileri DevTools'un computed bölümünde görebilirsiniz.

Hesaplanan stil
Şekil 3: Hesaplanmış stil eklemek için CSS'yi ayrıştıran ana iş parçacığı

Her DOM düğümünün, CSS sağlamasanız bile hesaplanmış bir stili vardır. <h1> etiketi, <h2> etiketinden daha büyük gösterilir ve her öğe için kenar boşlukları tanımlanır. Bunun nedeni, tarayıcının varsayılan bir stil sayfasına sahip olmasıdır. Chrome'un varsayılan CSS'sinin nasıl olduğunu öğrenmek istiyorsanız kaynak kodunu buradan görebilirsiniz.

Düzen

Oluşturucu işlemi artık dokümanın yapısını ve her bir düğümün stillerini biliyordur ancak bu, bir sayfayı oluşturmak için yeterli değildir. Arkadaşınıza telefonda bir tabloyu anlatmaya çalıştığınızı düşünün. "Büyük kırmızı bir daire ve küçük mavi bir kare var", arkadaşınızın resmin tam olarak nasıl görüneceğini anlaması için yeterli bilgi değildir.

insan faks makinesi oyunu
Şekil 4: Bir tablonun önünde duran bir kişi, diğer kişiye bağlı telefon hattı

Düzenleme, öğelerin geometrisini bulma işlemidir. Ana iş parçacığı, DOM ve hesaplanmış stilleri tarar ve x y koordinatları ve sınırlayıcı kutu boyutları gibi bilgiler içeren düzen ağacını oluşturur. Sayfa düzeni ağacı, DOM ağacına benzer bir yapıya sahip olabilir ancak yalnızca sayfada görünenlerle ilgili bilgileri içerir. display: none uygulanırsa bu öğe düzen ağacının bir parçası değildir (ancak visibility: hidden içeren bir öğe düzen ağacındadır). Benzer şekilde, p::before{content:"Hi!"} gibi bir içeriğe sahip bir sözde öğe uygulanırsa DOM'de olmasa bile düzen ağacına dahil edilir.

düzen
Şekil 5: Hesaplanmış stillerle DOM ağacını dolaşan ve düzen ağacı oluşturan ana iş parçacığı
Şekil 6: Satır sonu değişikliği nedeniyle hareket eden bir paragrafın kutu düzeni

Bir sayfanın düzenini belirlemek zor bir iştir. Üstten alta doğru blok akış gibi en basit sayfa düzenlerinde bile yazı tipinin boyutu ve satır aralarının nerede olacağı dikkate alınmalıdır. Bunlar, paragrafın boyutunu ve şeklini etkiler. Bu da sonraki paragrafın nerede olması gerektiğini etkiler.

CSS, öğenin bir tarafa kaymasını sağlayabilir, taşma öğesini maskeleyebilir ve yazı yönlerini değiştirebilir. Bu düzen aşamasının ne kadar önemli olduğunu tahmin edebilirsiniz. Chrome'da, düzen üzerinde bir mühendis ekibi çalışır. Çalışmalarının ayrıntılarını görmek istiyorsanız BlinkOn Konferansı'ndaki birkaç konuşmayı izleyebilirsiniz.

Boyama yapın

çizim oyunu
Şekil 7: Bir kanvas önünde, fırçayı elinde tutan ve önce daire mi yoksa kare mi çizmesi gerektiğine karar vermeye çalışan bir kişi

DOM, stil ve düzene sahip olmak, bir sayfayı oluşturmak için yeterli değildir. Bir resmi yeniden üretmeye çalıştığınızı varsayalım. Öğelerin boyutunu, şeklini ve konumunu bilseniz de bunları hangi sırayla boyayacağınıza karar vermeniz gerekir.

Örneğin, z-index belirli öğeler için ayarlanabilir. Bu durumda, HTML'de yazılan öğelerin sırasına göre boyama işlemi yanlış oluşturmaya neden olur.

z-index hatası
Şekil 8: Sayfa öğeleri, HTML işaretlemesi sırasına göre görünür. Z-dizini dikkate alınmadığından resim yanlış oluşturulur

Bu boyama adımında ana iş parçacığı, boyama kayıtları oluşturmak için düzen ağacında gezinir. Boyama kaydı, "önce arka plan, sonra metin, sonra dikdörtgen" gibi boyama işlemiyle ilgili bir nottur. JavaScript kullanarak <canvas> öğesinde çizim yaptıysanız bu işlem size tanıdık gelebilir.

boya kayıtları
Şekil 9: Düzen ağacında gezinen ve boya kayıtları oluşturan ana iş parçacığı

Oluşturma ardışık düzenini güncellemek maliyetlidir

Şekil 10: Oluşturulma sırasına göre DOM+Style, Layout ve Paint ağaçları

Oluşturma ardışık düzeninde anlaşılması gereken en önemli nokta, her adımda yeni veriler oluşturmak için önceki işlemin sonucunun kullanılmasıdır. Örneğin, düzen ağacında bir değişiklik olursa dokümanın etkilenen bölümleri için boyama sırasının yeniden oluşturulması gerekir.

Öğeleri animasyonlu hale getiriyorsanız tarayıcının bu işlemleri her kare arasında çalıştırması gerekir. Ekranlarımızın çoğu ekranı saniyede 60 kez (60 fps) yeniler. Ekrandaki öğeleri her karede hareket ettirdiğinizde animasyon insan gözüne düzgün görünür. Ancak animasyon, aralarındaki kareleri atlarsa sayfa "takılmalı" görünür.

Eksik kareler nedeniyle sarsıntı
Şekil 11: Zaman çizelgesinde animasyon kareleri

Oluşturma işlemleriniz ekran yenilemesini takip ediyor olsa bile bu hesaplamalar ana iş parçacığında çalışır. Bu da uygulamanız JavaScript'i çalıştırırken engellenebileceği anlamına gelir.

jage jank by JavaScript
Şekil 12: Zaman çizelgesinde animasyon kareleri ancak bir kare JavaScript tarafından engelleniyor

JavaScript işlemini küçük parçalara bölebilir ve requestAnimationFrame() kullanarak her karede çalışacak şekilde planlayabilirsiniz. Bu konu hakkında daha fazla bilgi için lütfen JavaScript'i yürütmeyi optimize etme başlıklı makaleyi inceleyin. Ana iş parçacığının engellenmesini önlemek için JavaScript'inizi Web İşleyiciler'de de çalıştırabilirsiniz.

request animation frame
Şekil 13: Animasyon çerçevesi içeren bir zaman çizelgesinde çalışan daha küçük JavaScript parçaları

Birleştirme

Bir sayfayı nasıl çizersiniz?

Şekil 14: Basit tarama işleminin animasyonu

Tarayıcı, dokümanın yapısını, her öğenin stilini, sayfanın geometrisini ve boyama sırasını bildiğine göre sayfayı nasıl çizer? Bu bilgilerin ekranda piksele dönüştürülmesine rasterleştirme denir.

Bunu yapmanın basit bir yolu, görüntü alanının içindeki parçaları rasterleştirmek olabilir. Kullanıcı sayfayı kaydırırsa rasterlenmiş çerçeveyi hareket ettirin ve daha fazla rasterleyerek eksik parçaları doldurun. Chrome, ilk yayınlandığında rasterleştirmeyi bu şekilde gerçekleştiriyordu. Ancak modern tarayıcı, birleştirme adı verilen daha karmaşık bir işlem yürütür.

Kompozit oluşturma nedir?

Şekil 15: Birleştirme işleminin animasyonu

Birleştirme, bir sayfanın bölümlerini katmanlara ayıran, bunları ayrı ayrı rasterleştiren ve birleştirici iş parçacığı adı verilen ayrı bir iş parçacığında sayfa olarak birleştiren bir tekniktir. Kaydırma gerçekleşirse katmanlar zaten rasterleştirildiğinden tek yapması gereken yeni bir kare oluşturmaktır. Animasyon, katmanları hareket ettirerek ve yeni bir kare oluşturarak da aynı şekilde yapılabilir.

Katmanlar panelini kullanarak web sitenizin DevTools'ta katmanlara nasıl bölündüğünü görebilirsiniz.

Katmanlara bölme

Ana iş parçacığı, hangi öğelerin hangi katmanlarda olması gerektiğini bulmak için katman ağacını oluşturmak üzere düzen ağacında gezinir (bu bölüm, DevTools performans panelinde "Katman Ağacını Güncelle" olarak adlandırılır). Bir sayfanın ayrı katman olması gereken belirli bölümleri (kaydırmalı yan menü gibi) ayrı katman olarak oluşturulmuyorsa CSS'de will-change özelliğini kullanarak tarayıcıya ipucu verebilirsiniz.

katman ağacı
Şekil 16: Katman ağacını oluşturan düzen ağacında gezinen ana iş parçacığı

Her öğeye katman eklemek isteyebilirsiniz ancak çok sayıda katmanda oluşturma işlemi yapmak, sayfanın küçük bölümlerini her karede rasterleştirmekten daha yavaş işleme neden olabilir. Bu nedenle, uygulamanızın oluşturma performansını ölçmeniz çok önemlidir. Konu hakkında daha fazla bilgi için Yalnızca Oluşturucu Özelliklerini Kullanma ve Katman Sayısını Yönetme başlıklı makaleyi inceleyin.

Ana iş parçacığının dışında raster ve birleştirme

Katman ağacı oluşturulduktan ve boyama siparişleri belirlendikten sonra ana iş parçacığı bu bilgileri birleştirici iş parçacığına bağlar. Daha sonra, karıştırıcı iş parçacığı her katmanı rasterleştirir. Katmanlar, bir sayfanın tamamı kadar büyük olabileceğinden, birleştirici iş parçacığı bunları karolara böler ve her karoyu raster iş parçacılarına gönderir. Rastırsal iş parçacıları her karoyu rasterleştirir ve GPU belleğinde depolar.

kafes
Şekil 17: Kartların bit eşlemini oluşturan ve GPU'ya gönderen raster iş parçacıkları

Oluşturucu iş parçacığı, görüntü alanındaki (veya yakınındaki) öğelerin önce rasterleştirilmesi için farklı raster iş parçacıklarına öncelik verebilir. Katmanlar, yakınlaştırma gibi işlemleri gerçekleştirmek için farklı çözünürlüklerde birden fazla döşeme de içerir.

Kartlar rasterleştirildikten sonra, bir resimlendirici çerçevesi oluşturmak için resimlendirici iş parçacığı çizim dörtgenleri adlı kart bilgilerini toplar.

Dörtgen çizme Kartın bellekteki konumu ve sayfa kompozisyonu dikkate alınarak kartın sayfanın neresinde çizileceği gibi bilgileri içerir.
Birleştirici çerçevesi Bir sayfanın çerçevesini temsil eden dörtgen çizim koleksiyonu.

Ardından, bir kompozitör çerçevesi IPC aracılığıyla tarayıcı sürecine gönderilir. Bu noktada, tarayıcı kullanıcı arayüzü değişikliği için kullanıcı arayüzü iş parçacığından veya uzantılar için diğer oluşturma işlemlerinden başka bir derleyici çerçevesi eklenebilir. Bu birleştirici kareler, ekranda gösterilmek üzere GPU'ya gönderilir. Bir kaydırma etkinliği gelirse kompozitör iş parçacığı, GPU'ya gönderilecek başka bir kompozitör çerçevesi oluşturur.

composit
Şekil 18: Birleştirme çerçevesi oluşturan birleştirici iş parçacığı. Kare, tarayıcı işlemine ve ardından GPU'ya gönderilir.

Birleştirmenin avantajı, ana iş parçacığı kullanılmadan yapılmasıdır. Oluşturucu iş parçacığının stil hesaplamasını veya JavaScript'in yürütülmesini beklemesi gerekmez. Bu nedenle, yalnızca animasyonların birleştirilmesi, sorunsuz performans için en iyi seçenek olarak kabul edilir. Düzenleme veya boyamanın tekrar hesaplanması gerekiyorsa ana iş parçacığının dahil edilmesi gerekir.

Özet

Bu yayında, ayrıştırmadan birleştirmeye kadar olan oluşturma ardışık düzenine baktık. Artık bir web sitesinin performans optimizasyonu hakkında daha fazla bilgi edinebilirsiniz.

Bu serinin bir sonraki ve son yayınında, derleyici iş parçasını daha ayrıntılı bir şekilde inceleyip mouse move ve click gibi kullanıcı girişleri geldiğinde ne olduğunu göreceğiz.

Yayından memnun kaldınız mı? 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.

Sonraki konu: Giriş, birleştiriciye gelir