Tarayıcılar Css’i Nasıl Yorumlar? Part I — Giriş

Oğuz Kılıç
7 min readApr 8, 2018

--

Hangi aşamalardan geçer ve nasıl çalışır?

Stillendirmenin doğuşu ile birlikte web sıradan olmaktan çıkıp daha çok hayatımıza girmiş oldu. Her gün girdiğimiz sosyal medya sitelerine kadar geniş bir kullanılabilirliğin önünü açmış, son kullanıcının web üzerinde geçirdiği vaktin artmasında önemli bir rol oynamıştır.

3 serilik bir yazı dizisi boyunca Browser dediğimiz host environment’ların www(world-wide-web)’in görünen yüzünü son kullanıcıyla nasıl buluşturduğunu inceleyeceğiz. Daha önce JavaScript motorlarının nasıl çalıştığını anlattığım yazıdan sonra yazdığımız html ve css’in tarayıcı üzerinde yarattığı etki sayesinde ekrandaki piksellerin nasıl bir araya gelip anlamlı görüntüler çizdiğine değinmenin faydalı ve tamamlayıcı olacağını düşünerek bu yazıya başladım. Umarım okurken keyif alırsınız.

Web’in ve Css’in Tarihi

İlk web sitesi 1990 yılında CERN’de ortaya çıktı ve tam olarak şuna benziyordu ancak elbette browser’lar böyle görünmüyordu. 😊

http://info.cern.ch/

Tim Berners-Lee adındaki İngiliz bilim adamı 1989 yılında www(world-wide-web)’i icat etti. Başlangıçta dünyanın dört bir yanındaki üniversitelerdeki bilim insanlarının birbirleri ile olan iletişimini ve bilgi paylaşımını sağlamak üzere tasarlandı. Daha fazla bilgi edinmek isterseniz info.cern.ch adresini ziyaret edebilirsiniz.

Tim Berners Lee

İlk line-mode browser 1992 yılında tam olarak şuna benziyordu;

Günümüzdeki adres çubuğu, menüleri ve kullanıcı arayüzü olan tarayıcılar henüz ortaya çıkmamıştı.

Css Håkon Wium Lie ismindeki yine bir CERN bilim adamı tarafından yayınlanan belgelerin stillendirilmesi ihtiyacı dolayısıyla tasarlanmıştır. Örneğin o sıralarda web üzerinde gazete benzeri bir düzen sağlamak için bir stillendirmenin gerekliliği tartışılmaya başlanmıştı. Aslında bu düşünce HTML ile birlikte zaten planlanmaya başlanmıştı. Temel amaç daha en başından beri stillendirilmiş web sayfalarının yaratılmasıydı.

Håkon Wium Lie

Nihayetinde Bernes-Lee, NeXT tarayıcısını basit stil dosyaları ile HTML’i stillendirebilmesi için yeniden yapılandırdı. İlk CSS işte bu dönemde ortaya çıktı. Daha sonra çeşitli tarayıcılar çeşitli stillendirme kuralları ile bir bir web dünyasında yer almaya başladı. NCSA Mosaic gibi web’i popüler yapan tarayıcıların dönemiydi. Tabi bu tarayıcılar her stile izin vermiyordu. Sadece yazıyı kalın yapma, renklendirme gibi basit işlevler sunuyorlardı. Bu aslında kullanıcıları ve geliştiricileri oldukça rahatsız etmeye başlamıştı.

İşlerin hararetlendiği bu dönemde www-talk posta listesine gelen maillerden biri durumu özetler nitelikteydi;

In fact, it has been a constant source of delight for me over the past year to get to continually tell hordes (literally) of people who want to — strap yourselves in, here it comes — control what their documents look like in ways that would be trivial in TeX, Microsoft Word, and every other common text processing environment: “Sorry, you’re screwed.”

Maili yazan kişi NCSA Mosaic tarayıcısını geliştiren programcılardan Marc Andreessen’den başkası değildi. Daha sonra Adreessen, Netscape’in kurucu ortaklarından biri olacaktı.

İlk CSS taslağı 1994 yılında Chicago’da ki bir web konferansında sunuldu. Bu sunum sırasında çeşitli sert eleştiriler yapıldı. Daha sonrasında 1995'e geldiğimizde www-style adında bir e-posta listesi oluşturuldu. CSS’in günümüzdeki haline gelmesinde bu e-posta listesinin önemli bir yeri var. Bir çok özellik, fikir buradan çıktı. Bu yıllarda aynı zamanda W3C konsorsiyumu faaliyetlerine başladı.

Css’i ilk destekleyen ticari tarayıcı 1996 yılında Internet Explorer v3'dü. Ardından Netscape Navigator v4 destek vermeye başladı.

Süre gelen zaman içinde CSS evrimleşti, gelişti ve farklı tarayıcılar tarafından desteklenmeye başlandı.

Nostaljik bir tarih yolculuğundan sonra bugün üzerinde gezindiğimiz web’in bu hale gelmesinde yani normal kullanıcılar tarafından sevilen ve çok vakit geçirilen bir yer haline gelmesinde CSS’in payı oldukça büyük.

Peki web’in sevilmesine bu kadar etki eden bir dil nasıl oluyorda Tarayıcının ekranda şekiller çizmesine, renklendirmesine, hatta animasyon oynatmasına imkan tanıyor. Temelde tarayıcı ve CSS nasıl konuşuyorlar ve aldığı komutları tarayıcı nasıl işleyerek her bir pixel’i birleştirip anlamlı görüntüler gösterebiliyor?

Tarayıcılar aynı JavaScript’te olduğu gibi CSS’i işleyen bir mekanizmaya sahipler. Bu yapıları layout engine, CSS engine gibi isimlerle tanımlıyoruz. Daha önce ki yazımda tarayıcıların JavaScript’i nasıl yorumladığını anlatmaya çalışmıştım. Bu yazı çoğu geliştiricinin “çok basit” olarak nitelendirdiği ancak web dünyasının en önemli enstrümanlarından biri olan CSS’in tarayıcılar tarafından nasıl yorumlandığını, işlendiğini anlamak üzerine olacak.

Bu yazıda stillendirmenin nasıl yapıldığından, layout engine’lerin genel çalışma prensiplerine doğru bir yolculuk yapacağız. Yine üzerinde yaptığım araştırmalar ve çalışmalardan dolayı bu yolculuğu Chrome üzerinden yapacağım. Ancak özellikle WebKit’i araştırmanızı, incelemenizi tavsiye ediyorum.

Tarayıcılara göre kullanılan Layout Motorları

  • Chrome — Blink
  • Firefox — Gecko/Stylo
  • Safari — WebKit
  • Opera — Blink
  • IE— EdgeHTML

Chrome aslında bir süre önce WebKit kullanıyordu. Daha sonra WebKit’ten ayrıldılar ancak yeni çıkardıkları Blink yine WebKit tabanlı bir engine olarak tasarlandı. Diğer yandan dikkatinizi çekmiştir Opera genellikle Chrome’u takip ediyor. JS tarafında V8 kullandıkları gibi layout tarafında da Blink kullanıyor.

Ayrıca Firefox eskiden Gecko kullanırken yeni Quantum tarayıcısı ile birlikte bir çok şeyi yeniden ele aldı. Bunlardan biri de Rust ile geliştirdikleri yeni css engine olan Stylo.

Öncelikle tarayıcının temel çalışma prensibini hatırlayalım;

Client görevi gören Browser bir http isteği ile hedef sunucuya ulaşır. Hedef sunucu browser’ın istediği yanıtı döner. Bu akışta bir html dosyası dönüyor. Html dosyasında dom, css, js, img, font gibi farklı elemanlar yer alabilir.

Mevcut Bileşenler

Layout engine’lerin yukarıdaki gibi 4 temel bileşeni bulunmaktadır. Bu bileşenler şu akışı kullanarak birbirleri ile iletişim halindedir.

Css temelde HTML elemanlarını stillendirmek için tasarlanmıştır çünkü HTML web’in görünen kısmındaki iskelet görevini görmektedir. Dolayısı ile iki aşamaya sahiptir. Öncelikle HTML parse edilerek DOM oluşturulur, daha sonra yazdığımız CSS parse edilerek CSSOM(css object model) elde edilir. Ardından DOM ve CSSOM referans kaynakları birleşerek Render Tree’yi meydana getirir.

Oluşan Render tree sonrası son iki aşama ile browser üzerindeki viewport’da görüntü işlenir. Bu aşamalar layout ve paint katmanlarını kapsamaktadır.

Hemen hemen her tarayıcının herhangi bir şeyi ekrana çizme aşaması bu şekilde meydana gelmektedir.

Oluşturulan render tree kullanılarak her bir öğenin ekranda nereye konumlandırılacağı, nasıl konumlandırılacağı gibi bazı hesaplar yapılır. Paint aşamasında ise ekrandaki piksellerin oluşan bu ağaç baz alınarak boyanması gerçekleşir.

Burada önemli bir noktaya değinmek istiyorum display: none ve visibility: hidden özelliklerine.

Render tree’nin oluşma sürecinde eğer bir html elemanına atanmış css tanımının içerisinde visibility: hidden varsa bu html elemanı sadece ekranda görünmez olur ama html node’u olarak ağaçta yer kaplamaya devam eder yani içi boş bir box-model olarak hayatına devam eder. display: none olan bir html elemanı ise ağaçta yer kaplamaz. Eğer engine, display: none ile eşleşen bir html elemanına denk gelirse ilgili node’u ağaçtan çıkardıktan sonra render tree’yi oluşturur. İki özellik arasındaki en temel fark budur.

Sonuç olarak oluşan render tree, paint aşamasından önceki son durağımız. Bu ağaç html ve stilleri barındırarak bizim için paint referans kaynağını ifade ediyor.

Şimdi aşama aşama bu akışın derinliklerine göz atalım;

HTML’in parse edilmesi

html parsing flow

Öncelikle tarayıcı HTML’in raw byte’ını local diskten veya network’den(cdn, kendi sunucunuz vs) chunk chunk alıp okumaya başlar. Bu okuma işlemi sırasında belirtilen encoding’e göre tek tek karakterlere ayrılır. Yani aslında tüm parser-lexer mekanizmalarında olduğu gibi bir tokenizing işlemine tabi tutulur yani atomik yapılara veya simgelere ayırma işlemi yapılır.

Basit bir html ağacının nasıl parse edildiğini inceleyelim;

DOM ağacı semantik olarak yukarıdan aşağıya doğru nested bir ağaçtır. Render edilirkende yukarıdan aşağıya ve soldan sağa doğru iç içe okunur. Yukarıdaki örnekte DOCTYPE tanımlaması olmadığını farketmişsinizdir. DOCTYPE yani DTD(document type definition) html dosyasının hangi kurallara göre parse edileceğini belirten bir tanımlamadır. Parser html’in raw byte’ını almaya başladığında ilk baktığı yer DTD’dir. Daha sonra tokenizing işlemine geçer.

Ancak Html’in eski versiyonlarında yani Html5 öncesinde(HTML 2.0 — 4.0.1'e kadar) SGML’e dayalı bir dil yapısı vardı. Dolayısıyla o versiyonlarda kullanılan parse kuralları ile şu an kullanılan kurallar aynı değil. Bu tanımlı kurallar sayesinde HTML dökümanlarının nasıl ayrıştırılacağı belirleniyor. Ek olarak bir tarayıcının hızlı çalışmasına etki eden en önemli unsurlardan biri parser’dır. Web sayfasının son kullanıcıya ulaşma zamanında geçen sürenin %10–15 gibi bir bölümü dökümanın parse edilmesi sırasında geçiyor. Dolayısıyla tarayıcı yarışlarında parser’ın performansı doğrudan etki etmektedir.

Konumuza tekrar dönecek olursak yukarıdaki html dökümanını yukarıdan aşağıya doğru okuyan Parser soldan sağa doğru lexical analiz yaparak ayrıştırmaya başlar.

Bu aşamada etiket açma karakteri(<), etiket kapatma karakteri (>), etiket işaretleyiciyi kapatma (/) gibi gibi parçalara ayrılır.

Hatta bazen html yazarken bir div etiketini kapatmayı unuturuz veya kapatırız ama açmayı unuturuz bu gibi durumlarda tarayıcının bu hataları yokmuş gibi davranıp düzgün bir şekilde çalıştırdığını görürsünüz. Bu gibi durumlar için hata toleransı politikası(error tolarance policy) uygulanır. Yani tarayıcı sizin yaptığınız bu hataları size yansıtmadan düzelterek hiç bir şey olmamış gibi akışın devam etmesine imkan tanır.

Nasıl oluyorda tarayıcı benim hatamı düzeltiyor dediğiniz noktada cevap “ön görülebilirlik ve ekstra efor” diyorum. 😊

Tokenizing işleminden sonra Html DOM ağacı oluşturulur.

Şu an elimizde web sayfasının iskeletini oluşturan bir yapı mevcut. Bir sonraki aşamada ağaçta bulunan her bir node’un id ve class isimleri ile bağlanmış CSS nesnelerinin parse edilmesi var. Ardından bu iki ham yapı tek bir gövdede buluşarak ekranda kullanıcının görebileceği görüntülerin tarayıcı tarafından hazırlanması için gerekli referans bilgiyi oluşturacak. Yani viewport dediğimiz kutu içerisinde node’ların geometrik olarak konumlarının belirlenmesi ve yerleştirilmesi, renkleri, fontları gibi bilgileri işleyeceğiz.

Bir sonraki yazıda CSS parse edildikten sonra elde edilen CSSOM ve DOM’un nasıl render tree’yi meydana getirdiğini ve layout’un nasıl oluştuğunu inceleyeceğiz.

Yazıyı beğendiyseniz paylaşmayı ve beğenmeyi unutmayın.

Bana her konuda oguzz.kilic@gmail.com mail adresinden ulaşabilirsiniz.

Sevgiler,

Faydalı Kaynaklar

https://superpeer.com/oguz

--

--

Oğuz Kılıç

developer @trendyol, ex @eBay, sci-fi addict. JavaScript, Frontend, Software Architecture