Oluşturucu İşleminin iç işleyişi
Bu, tarayıcıların nasıl çalıştığını anlatan 4 bölümlük blog dizisinin 3. bölümüdür. Daha önce çok işlemli mimari ve gezinme akışını ele almıştık. Bu gönderide, oluşturucu işleminin içinde neler olduğuna bakacağız.
Oluşturucu işlemi, web performansının birçok unsurunu ilgilendirir. Oluşturucu işleminin içinde çok şey yaşandığından bu gönderi sadece genel bakış niteliğindedir. Daha ayrıntılı bilgi edinmek isterseniz Web'in Temelleri'nin Performans bölümünde çok daha fazla kaynak bulabilirsiniz.
Oluşturucu işlemleri web içeriklerini işler
Oluşturucu işlemi, bir sekmede olan her şeyden sorumludur. Bir oluşturucu işleminde, ana iş parçacığı, kullanıcıya gönderdiğiniz kodun büyük kısmını işler. Web çalışanı veya Service Worker kullanıyorsanız JavaScript'inizin bazı bölümleri, çalışan iş parçacıkları tarafından işlenir. Birleştirme ve kafes iş parçacıkları, bir sayfayı verimli ve sorunsuz bir şekilde oluşturmak için oluşturucu işlemlerinin içinde de çalıştırılır.
Oluşturucu işleminin temel işi 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](https://developer.chrome.google.cn/static/blog/inside-browser-part3/image/renderer-process-df424472d0633.png?authuser=5&hl=tr)
Ayrıştırma
DOM oluşturma
Oluşturucu işlemi, gezinme için bir kayıt mesajı alıp HTML verileri almaya başladığında, ana iş parçacığı metin dizesini (HTML) ayrıştırmaya ve bir Document Object Model'e (DOM) dönüştürmeye başlar.
DOM, web geliştiricisinin JavaScript aracılığıyla etkileşimde bulunabileceği veri yapısının ve API'nin yanı sıra sayfanın tarayıcı dahili gösterimidir.
Bir HTML belgesinin DOM olarak ayrıştırılması HTML Standardı tarafından tanımlanmıştır. HTML'yi bir tarayıcıya beslemenin hiçbir zaman hata
vermediğini fark etmiş olabilirsiniz. Örneğin, </p>
kapanış etiketinin eksik olması geçerli bir HTML'dir. Hi! <b>I'm <i>Chrome</b>!</i>
gibi hatalı işaretleme (b etiketi, i etiketinden önce kapatılır) Hi! <b>I'm <i>Chrome</i></b><i>!</i>
gibi hatalı işaretlemeler kabul edilir. Bunun nedeni, HTML spesifikasyonunun bu hataları incelikle
inceleyecek şekilde tasarlanmış olmasıdır. Bu işlemlerin nasıl yapıldığını merak ediyorsanız HTML spesifikasyonunun "Hata işlemeye ve ayrıştırıcıdaki tuhaf durumlara giriş" bölümüne bakabilirsiniz.
Alt kaynak yükleniyor
Bir web sitesi genellikle resimler, CSS ve JavaScript gibi harici kaynakları kullanır. Bu dosyaların ağ veya önbellekten
yüklenmesi gerekir. Ana iş parçacığı, DOM oluşturmak için ayrıştırma yaparken bunları bulduğu için tek tek isteyebilir, ancak bunu hızlandırmak için "önceden yükleme tarayıcısı" eşzamanlı olarak çalıştırılır.
HTML belgesinde <img>
veya <link>
gibi öğeler varsa tarayıcı, HTML ayrıştırıcısı tarafından oluşturulan jetonlara önceden göz atar ve istekleri tarayıcı işlemindeki ağ iş parçacığına gönderir.
![DOM](https://developer.chrome.google.cn/static/blog/inside-browser-part3/image/dom-ffeed8e96a6e8.png?authuser=5&hl=tr)
JavaScript, ayrıştırmayı engelleyebilir
HTML ayrıştırıcısı bir <script>
etiketi bulduğunda, HTML belgesinin ayrıştırılmasını duraklatır ve JavaScript kodunu yüklemesi, ayrıştırması ve yürütmesi gerekir. Neden? JavaScript, tüm DOM yapısını değiştiren document.write()
gibi şeyler kullanarak dokümanın şeklini değiştirebilir (HTML spesifikasyonundaki ayrıştırma modeline genel bakış iyi bir diyagrama sahiptir). Bu nedenle, HTML ayrıştırıcısının HTML belgesini ayrıştırmaya devam edebilmesi için JavaScript'in çalışmasını beklemesi gerekir. JavaScript yürütmede ne olduğunu merak ediyorsanız, V8 ekibinin bu konuyla ilgili konuşmaları ve blog yayınları vardır.
Tarayıcı için kaynakları nasıl yüklemek istediğinize dair ipucu
Web geliştiricilerinin, kaynakları düzgün bir şekilde yüklemek için tarayıcıya ipuçları gönderebilecekleri pek çok yöntem vardır.
JavaScript'iniz document.write()
kullanmıyorsa <script>
etiketine async
veya defer
özelliğini ekleyebilirsiniz. Daha sonra tarayıcı, JavaScript kodunu eşzamansız olarak yükleyip çalıştırır, ayrıştırmayı engellemez. Uygun olması durumunda JavaScript modülünü de kullanabilirsiniz. <link rel="preload">
, mevcut gezinme için kaynağın kesinlikle gerekli olduğunu ve mümkün olan en kısa sürede indirmek istediğinizi tarayıcıya bildirmenin bir yoludur. Bu konuyla ilgili daha fazla bilgiyi Kaynak Önceliklendirme - Tarayıcının Size Yardımcı Olmasını Sağlama bölümünde bulabilirsiniz.
Stil hesaplaması
DOM'ye sahip olmak, sayfanın nasıl görüneceğini bilmek yeterli değildir, çünkü sayfa öğelerini CSS'de biçimlendirebiliriz. Ana iş parçacığı CSS'yi ayrıştırır ve her bir DOM düğümü için hesaplanan stili belirler. Bu, CSS seçicilere dayalı olarak her bir öğeye ne tür stil uygulandığıyla ilgili bilgidir. Bu bilgileri Geliştirici Araçları'nın computed
bölümünde görebilirsiniz.
![Hesaplanan stil](https://developer.chrome.google.cn/static/blog/inside-browser-part3/image/computed-style-5e3c65a01f3f1.png?authuser=5&hl=tr)
Herhangi bir CSS sağlamasanız bile her DOM düğümünün hesaplanan bir stili olur. <h1>
etiketi, <h2>
etiketten daha büyük olarak 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 koduna buradan bakabilirsiniz.
Düzen
Artık oluşturucu süreci, bir dokümanın yapısını ve her bir düğüme ait stilleri bilir, ancak bu, sayfayı oluşturmak için yeterli değildir. Bir resmi arkadaşınıza telefonla tarif etmeye çalıştığınızı düşünün. "Kırmızı büyük bir daire ve küçük mavi bir kare var", arkadaşınızın tablonun tam olarak neye benzediğini bilmesi için yeterli bilgi sağlamaz.
![insan faks makinesi oyunu](https://developer.chrome.google.cn/static/blog/inside-browser-part3/image/game-human-fax-machine-17f10d8b400ac.png?authuser=5&hl=tr)
Düzen, öğelerin geometrisini bulma işlemidir. Ana iş parçacığı DOM'de ve hesaplanan stillerde gezinir, x y koordinatları ve sınırlayıcı kutu boyutları gibi bilgiler içeren düzen ağacını oluşturur. Düzen 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 parçası olmaz (ancak düzen ağacında visibility: hidden
içeren bir öğe yer alır). Benzer şekilde, p::before{content:"Hi!"}
gibi içeriğe sahip bir sözde öğe uygulanırsa, DOM'de bulunmasa bile düzen ağacına dahil edilir.
![düzen](https://developer.chrome.google.cn/static/blog/inside-browser-part3/image/layout-9d8ed8c743f45.png?authuser=5&hl=tr)
Bir sayfanın Düzenini belirlemek zor bir iştir. Üstten alta doğru blok akışı gibi en basit sayfa düzenlerinin bile, yazı tipinin ne kadar büyük olduğunu ve paragrafın hangi satırdan ayrılacağını dikkate alması gerekir. Çünkü bunlar bir 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 yazma yönünü değiştirebilir. Bu düzen aşamasının zor bir görev olduğunu tahmin edebilirsiniz. Chrome'da, mühendislerden oluşan bütün bir ekip düzen üzerinde çalışıyor. Ekibin çalışmalarının ayrıntılarını görmek istiyorsanız BlinkOn Konferansı'ndan birkaç konuşma kaydedilmiş ve bu konuşmalar oldukça ilginç görünüyor.
Boyama yapın
![çizim oyunu](https://developer.chrome.google.cn/static/blog/inside-browser-part3/image/drawing-game-7902ad8a91d2f.png?authuser=5&hl=tr)
Bir sayfayı oluşturmak için DOM, stil ve düzenin olması yeterli değildir. Diyelim ki bir resmi yeniden oluşturmaya çalışıyorsunuz. Öğelerin boyutunu, şeklini ve konumunu bilirsiniz ama yine de bunları hangi sırayla boyadığınıza karar vermeniz gerekir.
Örneğin, belirli öğeler için z-index
ayarlanmış olabilir. Bu durumda, HTML'de yazılan öğeleri sıraya göre boyamak yanlış oluşturmaya neden olur.
![z-endeksi başarısız](https://developer.chrome.google.cn/static/blog/inside-browser-part3/image/z-index-fail-2529cf989dc65.png?authuser=5&hl=tr)
Bu boyama adımında, ana iş parçacığı düzen ağacında yürüyüş yaparak boyama kayıtları oluşturur. Boyama kaydı, "önce arka plan, ardından metin, sonra dikdörtgen" gibi bir boyama işlemi notudur. JavaScript kullanarak <canvas>
öğesi üzerine çizim yaptıysanız bu işlem size tanıdık gelebilir.
![boya kayıtları](https://developer.chrome.google.cn/static/blog/inside-browser-part3/image/paint-records-151165f18a91e.png?authuser=5&hl=tr)
Oluşturma ardışık düzenini güncellemek maliyetli bir işlemdir
Oluşturma ardışık düzeninde anlaşılması gereken en önemli nokta, her adımda yeni veriler oluşturmak için bir önceki işlemin sonucunun kullanılmasıdır. Örneğin, düzen ağacında bir değişiklik olursa Boya sırasının belgenin etkilenen bölümleri için yeniden oluşturulması gerekir.
Öğelere animasyon oluşturuyorsanı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; siz her karede ekrandaki öğeleri hareket ettirdiğinizde animasyon insan gözleri için akıcı bir şekilde görünür. Bununla birlikte, animasyonda aradaki kareler eksikse sayfa "titreşimli" görünür.
![eksik karelerden jage jank](https://developer.chrome.google.cn/static/blog/inside-browser-part3/image/jage-jank-missing-frames-187496b8fbc8e.png?authuser=5&hl=tr)
Oluşturma işlemleriniz ekran yenilemeye ayak uydursa bile bu hesaplamalar ana iş parçacığında çalışır. Bu da uygulamanız JavaScript'i çalıştırırken iş parçacığının engellenebileceği anlamına gelir.
![JavaScript'ten jage jank](https://developer.chrome.google.cn/static/blog/inside-browser-part3/image/jage-jank-javascript-b19c0193934a3.png?authuser=5&hl=tr)
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 Yürütmeyi Optimize Etme bölümüne bakın. Ana iş parçacığının engellenmesini önlemek için Web Çalışanlarında JavaScript'inizi de çalıştırabilirsiniz.
![animasyon çerçevesi iste](https://developer.chrome.google.cn/static/blog/inside-browser-part3/image/request-animation-frame-3b04e26660019.png?authuser=5&hl=tr)
Birleştiriliyor
Nasıl sayfa çizersiniz?
Tarayıcı dokümanın yapısını, her bir öğenin stilini, sayfanın geometrisini ve boyama sırasını bildiğine göre artık sayfayı nasıl çizer? Bu bilgileri ekranda piksellere dönüştürmeye rasterleştirme denir.
Bunu yönetmenin naif bir yolu, görüntü alanının içindeki bölümleri kafeslemek olabilir. Kullanıcı sayfayı kaydırırsa kafesli çerçeveyi hareket ettirin ve daha fazla pikselleştirerek eksik kısımları doldurun. Chrome, ilk yayınlandığında pikselleştirmeyi bu şekilde ele aldı. Ancak modern tarayıcı, birleştirme adı verilen daha karmaşık bir işlem çalıştırır.
Birleştirme nedir?
Birleştirme, bir sayfanın bölümlerini katmanlara ayırmak, bunları ayrı ayrı rasterleştirmek ve birleştirici iş parçacığı adı verilen ayrı bir iş parçacığında bir sayfa olarak birleştirmek için kullanılan bir tekniktir. Kaydırma gerçekleşirse katmanlar zaten pikselleştirildiği için yapmanız gereken tek şey yeni bir kareyi birleştirmektir. Animasyonu da aynı şekilde katmanları hareket ettirip yeni bir kare ekleyerek yapabilirsiniz.
Web sitenizin Geliştirici Araçları'nda Katmanlar panelini kullanarak katmanlara nasıl bölündüğünü görebilirsiniz.
Katmanlara bölünme
Hangi öğelerin hangi katmanlarda olması gerektiğini bulmak için ana iş parçacığı, katman ağacını oluşturmak üzere düzen ağacında ilerler (bu bölüme, Geliştirici Araçları performans panelinde "Katman Ağacı Güncelleme" adı verilir). Bir sayfanın ayrı katman olarak kullanılması gereken belirli bölümleri (ör. kayan yan menü) bu seçeneği almıyorsa CSS'de will-change
özelliğini kullanarak tarayıcıya ipucu verebilirsiniz.
![katman ağacı](https://developer.chrome.google.cn/static/blog/inside-browser-part3/image/layer-tree-cc92336966c73.png?authuser=5&hl=tr)
Katmanları her öğeye vermek cazip gelse de fazla sayıda katmandan faydalanmak, bir sayfanın her karede küçük parçalarını pikselleştirmektense 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 Birleştirici Mülklere Bağlı Kalma ve Katman Sayısını Yönetme bölümüne bakın.
Ana iş parçacığından kafes ve birleşik öğe
Katman ağacı oluşturulduktan ve boyama siparişleri belirlendikten sonra, ana iş parçacığı bu bilgileri birleştirici iş parçacığına kaydeder. Birleştirici iş parçacığı daha sonra her bir katmanı pikselleştirir. Bir katman, bir sayfanın tüm uzunluğu kadar büyük olabilir. Bu nedenle, birleştirici iş parçacığı bunları karolara böler ve her bir parçayı kafes ileti dizilerine gönderir. Kafes iş parçacıkları her parçayı rasterleştirir ve GPU belleğinde depolar.
![kafes](https://developer.chrome.google.cn/static/blog/inside-browser-part3/image/raster-9dfd7af5a9554.png?authuser=5&hl=tr)
Birleştirici iş parçacığı, farklı kafes iş parçacıklarına öncelik verebilir. Böylece, görüntü alanındaki (veya yakındaki) öğeler ilk önce pikselleştirilebilir. Bir katman, yakınlaştırma işlemi gibi şeyleri işlemek amacıyla farklı çözünürlükler için birden fazla döşeme de içerir.
Karolar pikselleştirildikten sonra birleştirici iş parçacığı çizme dörtlü adı verilen parça bilgilerini toplayarak bir birleştirici çerçevesi oluşturur.
Dörtlü çekiliş | Parçanın bellekteki konumu ve sayfa birleştirme dikkate alınarak karonun çizileceği sayfanın neresinde olduğu gibi bilgileri içerir. |
Birleştirme çerçevesi | Sayfanın çerçevesini temsil eden çizim dörtlüleri koleksiyonu. |
Daha sonra, birleştirici çerçeve IPC aracılığıyla tarayıcı işlemine 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şturucu işlemlerinden başka bir oluşturucu çerçevesi eklenebilir. Bu birleştirici kareler, ekranda görüntülemek için GPU'ya gönderilir. Bir kaydırma etkinliği gelirse birleştirici iş parçacığı, GPU'ya gönderilecek başka bir birleştirici karesi oluşturur.
![birleştirme](https://developer.chrome.google.cn/static/blog/inside-browser-part3/image/composit-266744978ac93.png?authuser=5&hl=tr)
Birleştirmenin avantajı, işlemin ana iş parçacığı içermeden yapılmasıdır. Birleştirici iş parçacığının stil hesaplamasını veya JavaScript'in yürütülmesini beklemesine gerek yoktur. Bu nedenle, sorunsuz performans için yalnızca animasyonların birleştirilmesi en iyi seçenek olarak kabul edilir. Düzenin veya boyanın tekrar hesaplanması gerekiyorsa ana iş parçacığı dahil edilmelidir.
Son adım
Bu gönderide, oluşturma ardışık düzeninden ayrıştırmadan birleştirmeye kadar çeşitli işlemleri inceledik. Artık bir web sitesinin performans optimizasyonu hakkında daha fazla bilgi edinebileceğinizi umuyoruz.
Bu serinin bir sonraki ve son gönderisinde, oluşturucu ileti dizisine daha ayrıntılı bir şekilde bakıp mouse move
ve click
gibi kullanıcı girişleri geldiğinde ne olduğunu göreceğiz.
Gönderiyi beğendiniz mi? Gelecekteki bir gönderi için sorularınız veya önerileriniz varsa aşağıdaki yorum bölümüne ya da Twitter'da @kosamari adresine yazın.