Chrome'da Hızlandırılmış Oluşturma

Katman modeli

Tom Wiltzius
Tom Wiltzius

Giriş

Çoğu web geliştiricisi için web sayfalarının temel modeli DOM'dir. Oluşturma işlemi, bir sayfanın bu sunumunu ekrandaki bir resme dönüştürme işlemidir. Modern tarayıcılar, grafik kartlarından yararlanmak için son yıllarda oluşturma işleminin çalışma şeklini değiştirmiştir: Buna çoğu zaman belirsiz bir şekilde "donanım hızlandırma" denir. Normal bir web sayfasından bahsederken (ör. Canvas2D veya WebGL değil) bu terim tam olarak ne anlama gelir? Bu makalede, Chrome'da web içeriğinin donanım hızlandırmalı oluşturulmasının temelini oluşturan temel model açıklanmaktadır.

Önemli ve Önemli Uyarılar

Burada WebKit'ten, daha ayrıntılı olarak ise WebKit'in Chromium'daki bağlantı noktasından bahsediyoruz. Bu makalede, web platformu özellikleri değil, Chrome'un uygulama ayrıntıları ele alınmaktadır. Web platformu ve standartlar, bu uygulama ayrıntısı düzeyini kodlamaz. Bu nedenle, bu makaledeki herhangi bir şeyin diğer tarayıcılar için geçerli olacağının garantisi yoktur, ancak dahili sistem bilgisinin gelişmiş hata ayıklama ve performans ayarı için yine de yararlı olabilir.

Ayrıca, bu makalenin tamamında çok hızlı bir şekilde değişen Chrome'un oluşturma mimarisinin temel bir parçasından bahsedildiğini unutmayın. Bu makalede yalnızca değişme olasılığı düşük olan hususlar ele alınmaya çalışılmıştır, ancak tüm bunların altı ay içinde geçerli olmaya devam edeceği garanti edilmemektedir.

Chrome'un bir süredir iki farklı oluşturma yoluna sahip olduğunun anlaşılması önemlidir: donanım hızlandırmalı yol ve eski yazılım yolu. Bu yazının hazırlandığı tarih itibarıyla tüm sayfalar Windows, ChromeOS ve Android için Chrome'da donanım hızlandırmalı yönteme tabi tutulacaktır. Yalnızca Mac ve Linux'ta içeriklerinin bir kısmının birleştirmesi gereken sayfalar hızlandırılmış yolda ilerler (birleştirmenin gerekli olduğu durumlar hakkında daha fazla bilgi için aşağıya bakın). Ancak, kısa bir süre sonra tüm sayfalar oradaki hızlandırılmış yola da inecektir.

Son olarak, oluşturma motorunun gelişmiş özelliklerine de göz atıyoruz ve bu motorun performans üzerinde büyük etkisi olan özelliklerine bakıyoruz. Kendi sitenizin performansını iyileştirmeye çalışırken, katman modelini anlamak yardımcı olabilir, ancak kendinizi gözden geçirmek de kolaydır: Katmanlar yararlı yapılardır, ancak çok fazla katman oluşturmak grafik yığınının tamamına ek yük yaratabilir. Kendinizi önceden uyarın!

DOM'den Ekrana

Katmanların Tanıtımı

Bir sayfa yüklenip ayrıştırıldıktan sonra tarayıcıda, birçok web geliştiricisinin aşina olduğu bir yapı olarak gösterilir: DOM. Bununla birlikte, bir sayfayı oluştururken tarayıcı, doğrudan geliştiricilerle karşılaşmayan bir dizi ara gösterime sahiptir. Bu yapılardan en önemlisi katmandır.

Chrome'da aslında birkaç farklı katman türü vardır: DOM'un alt ağaçlarından sorumlu Renderlayer ve RenderLayers'ın alt ağaçlarından sorumlu olan GraphicsLayers. Bizim için ikincisi en ilginç olanıdır, çünkü Graphicslayers, GPU'ya doku olarak yüklenen öğelerdir. Bundan sonra Grafik Katmanı anlamında "katman" diyeceğim.

GPU terminolojisini bir kenara bırakalım: Doku nedir? Bunu, ana bellekten (ör. RAM) video belleğine (GPU'nuzdaki VRAM) taşınan bir bit eşlem görüntüsü gibi düşünebilirsiniz. GPU'ya geldikten sonra bir ağ geometrisine eşleyebilirsiniz. Video oyunlarında veya CAD programlarında bu teknik, iskeletsel 3D modellere "cilt" oluşturmak için kullanılır. Chrome, web sayfası içeriği parçalarını GPU'ya almak için dokuları kullanır. Dokular, gerçekten basit bir dikdörtgen ağa uygulanarak ucuz konum ve dönüşümlerle kolayca eşlenebilir. 3D CSS bu şekilde çalışır ve hızlı kaydırma için de harikadır. Ancak ilerleyen zamanlarda her ikisine de değineceğiz.

Katman kavramını açıklamak için birkaç örneğe göz atalım.

Chrome'da katmanları incelerken çok kullanışlı bir araç, Geliştirici Araçları'nda, "oluşturma" başlığının altındaki ayarlarda bulunan "birleştirilmiş katman sınırlarını göster" işaretidir (örneğin, küçük dişli simgesi). Katmanların ekranda bulunduğu yerleri kolayca vurgular. Bunu etkinleştirelim. Bu ekran görüntüleri ve örneklerin tamamı, bu yazı hazırlanırken en son çıkan Chrome Canary Chrome 27 sürümünden alınmıştır.

Şekil 1: Tek katmanlı sayfa

<!doctype html>
<html>
<body>
  <div>I am a strange root.</div>
</body>
</html>
Birleştirilmiş katman oluşturma kenarlıklarının sayfanın temel katmanının ekran görüntüsü
Birleştirilmiş katman oluşturma kenarlıklarının sayfanın temel katmanının ekran görüntüsü

Bu sayfada yalnızca bir katman var. Mavi ızgara, blokları temsil eder. Bunları, Chrome'un büyük bir katmanın parçalarını aynı anda GPU'ya yüklemek için kullandığı bir katmanın alt birimleri olarak düşünebilirsiniz. Bunlar burada pek önemli değildir.

Şekil 2: Kendi katmanındaki bir öğe

<!doctype html>
<html>
<body>
  <div style="transform: rotateY(30deg) rotateX(-30deg); width: 200px;">
    I am a strange root.
  </div>
</body>
</html>
Döndürülen katmanın oluşturma kenarlıklarının ekran görüntüsü
Döndürülen katmanın oluşturma kenarlıklarının ekran görüntüsü

3D CSS özelliğini, onu döndüren <div> öğesine döndürerek bir öğenin kendi katmanına sahip olduğunda nasıl göründüğünü görebiliriz: Bu görünümde bir katmanı ana hatlarıyla belirten turuncu kenarlığa dikkat edin.

Katman Oluşturma Kriterleri

Başka hangi katman kendi katmanına sahip? Chrome'un buradaki buluşsal yöntemleri zaman içinde gelişti ve gelişmeye devam ediyor. Ancak şu anda aşağıdaki tetikleyici katmanı oluşturma yöntemlerinden herhangi biri:

  • 3D veya perspektif dönüştürme CSS özellikleri
  • Hızlandırılmış video kod çözmeyi kullanan <video> öğe
  • 3D (WebGL) bağlamı veya hızlandırılmış 2D içeriğe sahip <canvas> öğeler
  • Birleşik eklentiler (ör. Flash)
  • Opaklıkları için CSS animasyonlu veya animasyonlu dönüşüm kullanan öğeler
  • Hızlandırılmış CSS filtreleri olan öğeler
  • Öğenin birleştirme katmanına sahip bir alt öğesi vardır (diğer bir deyişle, öğenin kendi katmanında bir alt öğesi varsa)
  • Öğe, birleştirme katmanına sahip daha düşük Z-endeksine sahip bir kardeşe (diğer bir deyişle, birleştirilmiş bir katmanın üzerinde oluşturulur) sahip

Pratik Çıkarımlar: Animasyon

Katmanları da taşıyabilir, bu da animasyon için çok kullanışlı olmalarını sağlar.

Şekil 3: Animasyonlu Katmanlar

<!doctype html>
<html>
<head>
  <style>
  div {
    animation-duration: 5s;
    animation-name: slide;
    animation-iteration-count: infinite;
    animation-direction: alternate;
    width: 200px;
    height: 200px;
    margin: 100px;
    background-color: gray;
  }
  @keyframes slide {
    from {
      transform: rotate(0deg);
    }
    to {
      transform: rotate(120deg);
    }
  }
  </style>
</head>
<body>
  <div>I am a strange root.</div>
</body>
</html>

Daha önce belirtildiği gibi, katmanlar statik web içeriğinde hareket etmek için gerçekten yararlıdır. Temel durumda Chrome, bir katmanı GPU'ya bir doku olarak yüklemeden önce, katmanın içeriğini yazılım bit eşlemine boyar. Bu içerik gelecekte değişmezse yeniden boyanmasına gerek yoktur. Bu İyi Bir Şeydir: Yeniden boyama, JavaScript çalıştırmak gibi başka işlere harcanabilecek zaman alır ve boya uzunsa animasyonlarda aksaklıklara veya gecikmelere neden olur.

Örneğin, Geliştirici Araçları zaman çizelgesinin şu görünümüne bakın: Bu katman ileri geri döndürülürken boyama işlemi yoktur.

Animasyon sırasında Geliştirici Araçları zaman çizelgesinin ekran görüntüsü
Animasyon sırasında Geliştirici Araçları zaman çizelgesinin ekran görüntüsü

Geçersiz! Yeniden boyama

Ancak, katmanın içeriği değişirse, yeniden boyanması gerekir.

Şekil 4: Katmanları Yeniden Boyama

<!doctype html>
<html>
<head>
  <style>
  div {
    animation-duration: 5s;
    animation-name: slide;
    animation-iteration-count: infinite;
    animation-direction: alternate;
    width: 200px;
    height: 200px;
    margin: 100px;
    background-color: gray;
  }
  @keyframes slide {
    from {
      transform: rotate(0deg);
    }
    to {
      transform: rotate(120deg);
    }
  }
  </style>
</head>
<body>
  <div id="foo">I am a strange root.</div>
  <input id="paint" type="button" value="repaint">
  <script>
    var w = 200;
    document.getElementById('paint').onclick = function() {
      document.getElementById('foo').style.width = (w++) + 'px';
    }
  </script>
</body>
</html>

Giriş öğesi her tıklandığında, dönen öğe 1 piksel genişler. Bu, öğenin tamamının (bu örnekte bütün bir katman) taşınmasına ve yeniden boyanmasına neden olur.

Nelerin boyandığını görmenin iyi bir yolu, Geliştirici Araçları'nda bulunan ve Geliştirici Araçları ayarlarındaki "Oluşturma" başlığının altındaki "boya dikdörtgenlerini göster" aracını kullanmaktır. Bu özelliği açtıktan sonra, düğme tıklandığında animasyonlu öğenin ve düğmenin kırmızı renkte yanıp söndüğünü unutmayın.

Boya dikdörtgenlerini göster onay kutusunun ekran görüntüsü
Boya dikdörtgenlerini göster onay kutusunun ekran görüntüsü

Boyama etkinlikleri, Geliştirici Araçları zaman çizelgesinde de gösterilir. Gözleri keskin okuyucular burada iki boyama etkinliği olduğunu fark edebilir: Biri katman için, diğeri de bastırılmış duruma geçtiğinde veya düğmeden çıktıktan sonra yeniden boyanan düğme için.

Geliştirici Araçları Zaman Çizelgesi katmanının yeniden boyanmasını gösteren ekran görüntüsü
Geliştirici Araçları Zaman Çizelgesi'nin bir katmanı yeniden boyadığını gösteren ekran görüntüsü

Chrome'un her zaman katmanın tamamını yeniden boyaması gerekmez. DOM'nin yalnızca geçersiz kılınan bölümünü yeniden boyamak için akıllı olmaya çalışır. Bu örnekte, değiştirdiğimiz DOM öğesi tüm katmanın boyutudur. Ancak diğer birçok durumda da bir katmanda çok sayıda DOM öğesi bulunur.

Bir sonraki soru, geçersiz kılmaya neden olan ve yeniden boyamayı zorlayan şeyin ne olduğudur. Geçersiz kılmaları zorlayabilecek çok sayıda uç durum bulunduğundan, bu soruyu ayrıntılı bir şekilde yanıtlamak zordur. Bunun en yaygın nedeni, CSS stillerini değiştirerek veya geçişe neden olarak DOM'un kirlenmesidir. Tony Gentilcore'un geçişin nedenleri hakkında harika bir blog yayını ve Stoyan Stefanov'un resmi daha ayrıntılı olarak ele aldığı bir makale (ama bu gösterişli kompozisyonla değil, sadece boyamayla sona ermektedir).

Üzerinde çalıştığınız bir şeyi etkileyip etkilemediğini anlamanın en iyi yolu, Geliştirici Araçları Zaman Çizelgesi ve Boyama Rects araçlarını kullanarak, istemediğiniz halde boyama yapıp yapmadığınızı kontrol etmek ve geçiş/yeniden boyama işleminden hemen önce DOM'u nereden temizlediğinizi tanımlamaya çalışmaktır. Resim yapmak kaçınılmazsa ancak normalden daha uzun sürüyorsa Geliştirici Araçları'nda sürekli boyama moduyla ilgili Eberhard Gräther'in makalesine göz atın.

Birleştiriliyor: DOM'dan Ekrana

Peki Chrome, DOM'u ekran görüntüsüne nasıl dönüştürür? Kavramsal olarak:

  1. DOM'yi alır ve katmanlara ayırır
  2. Bu katmanların her birini bağımsız bir şekilde yazılım bit eşlemlerine boyar
  3. Bunları doku olarak GPU'ya yükler
  4. Çeşitli katmanları birleştirerek nihai ekran görüntüsü oluşturur.

Tüm bunların, Chrome ilk kez bir web sayfası çerçevesi oluşturduğunda yapılması gerekir. Ancak gelecekteki kareler için bazı kısayollar kullanılabilir:

  1. Belirli CSS özellikleri değişirse herhangi bir öğeyi yeniden boyamanız gerekmez. Chrome yalnızca, GPU'da halihazırda bulunan mevcut katmanları doku olarak, ancak farklı birleştirme özellikleriyle (ör.farklı konumlarda, farklı opaklıklarda vb.) yeniden kombine edebilir.
  2. Bir katmanın bir bölümü geçersiz hale gelirse yeniden boyanarak yeniden yüklenir. İçeriği aynı kalır ancak birleştirilmiş özellikleri değişirse (ör. çevrilirse veya opaklığı değişirse) Chrome, onu GPU'da bırakabilir ve yeni bir kare oluşturmak için yeniden birleştirebilir.

Açıkça anlaşılması gerektiği gibi, katman tabanlı birleştirme modelinin oluşturma performansı üzerinde derin etkileri vardır. Boyanacak herhangi bir şey olmadığında kompozisyon işlemi nispeten ucuzdur. Bu nedenle, oluşturma performansındaki hataları gidermeye çalışırken katmanların yeniden boyanmaması iyi bir genel hedeftir. Deneyimli geliştiriciler yukarıdaki birleştirme tetikleyicileri listesine göz atar ve katmanların oluşturulmasını kolayca zorunlu kılmanın mümkün olduğunu fark eder. Ancak bunlar boş olmadığından, bunları gizlice oluşturmaya dikkat edin. Sistem RAM'inde ve GPU'da bellek kullanırlar (özellikle mobil cihazlarda sınırlıdır). Bunların çok fazla olması, mantıkta görünür olan başka ek yüke neden olabilir. Ayrıca, birçok katman büyükse ve daha önce hiç olmadığı çok yerle örtüşüyorsa, pikselleştirme için harcanan zamanı artırabilir. Bu durum, bazen "aşırı çizim" olarak da adlandırılır. Bu nedenle, bilgilerinizi akıllıca kullanın!

Şimdilik hepsi bu. Katman modelinin pratik sonuçlarıyla ilgili birkaç makale daha için takipte kalın.

Ek Kaynaklar