Önceki modülde, kritik oluşturma yolunun arkasındaki bazı teoriler ve oluşturmayı engelleyen ve ayrıştırıcıyı engelleyen kaynakların bir sayfanın ilk oluşturmasını nasıl geciktirebileceği ele alınmıştı. Bu konunun teorik temellerini öğrendiğinize göre, kritik oluşturma yolunu optimize etmeye yönelik bazı teknikleri öğrenmeye hazırsınız.
Bir sayfa yüklenirken HTML'sinde birçok kaynağa referans verilir. Bu kaynaklar, CSS aracılığıyla sayfaya görünüm ve düzen, JavaScript aracılığıyla da etkileşim sağlar. Bu modülde, bu kaynaklarla ve bir sayfanın yükleme süresini nasıl etkiledikleriyle ilgili bir dizi önemli kavram ele alınmaktadır.
Oluşturma engelleme
Önceki modülde de belirtildiği gibi, CSS, oluşturmayı engelleyen bir kaynaktır. Tarayıcının CSS Nesne Modeli (CSSOM) oluşturulana kadar herhangi bir içeriği oluşturmasını engeller. Tarayıcı, kullanıcı deneyimi açısından istenmeyen bir durum olan Biçimlendirilmemiş İçerik Flaşını (FOUC) önlemek için oluşturmayı engeller.
Önceki videoda, sayfayı herhangi bir stil olmadan görebileceğiniz kısa bir FOUC (Stil Uygulanmamış İçerik Yanıp Sönmesi) var. Ardından, sayfanın CSS'si ağdan yüklenmeyi tamamladığında tüm stiller uygulanır ve sayfanın stil içermeyen sürümü hemen stilli sürümle değiştirilir.
Genel olarak FOUC, normalde görmediğiniz bir şeydir ancak tarayıcının CSS indirilip sayfaya uygulanana kadar sayfanın oluşturulmasını neden engellediğini anlamak için bu kavramı bilmeniz önemlidir. Oluşturmayı engelleyen kaynaklar mutlaka istenmeyen bir durum değildir ancak CSS'nizi optimize ederek bu durumun süresini en aza indirmeniz gerekir.
Ayrıştırıcı engelleme
async veya defer özellikleri olmayan bir <script> öğesi gibi bir ayrıştırıcıyı engelleyen kaynak, HTML ayrıştırıcısını kesintiye uğratır. Ayrıştırıcı bir <script> öğesiyle karşılaştığında tarayıcının, HTML'nin geri kalanını ayrıştırmaya devam etmeden önce komut dosyasını değerlendirip yürütmesi gerekir. Komut dosyaları, DOM oluşturulurken DOM'u değiştirebileceği veya DOM'a erişebileceği için bu durum tasarımdan kaynaklanmaktadır.
<!-- This is a parser-blocking script: -->
<script src="/script.js"></script>
Harici JavaScript dosyaları (async veya defer olmadan ya da type=module ile, bu da varsayılan olarak defer olur) kullanılırken dosya keşfedilip indirilene, ayrıştırılıp yürütülene kadar ayrıştırıcının çalışması engellenir. Satır içi JavaScript kullanılırken satır içi komut dosyası ayrıştırılıp yürütülene kadar ayrıştırıcı benzer şekilde engellenir.
Önyükleme tarayıcısı
Önceden yükleme tarayıcısı, birincil HTML ayrıştırıcısı kaynakları keşfetmeden önce ham HTML yanıtını tarayarak kaynakları bulup spekülatif olarak getiren ikincil bir HTML ayrıştırıcısı biçimindeki tarayıcı optimizasyonudur. Örneğin, ön yükleme tarayıcısı, HTML ayrıştırıcı CSS ve JavaScript gibi kaynakları getirip işlerken engellendiğinde bile tarayıcının <img> öğesinde belirtilen bir kaynağı indirmeye başlamasına olanak tanır.
Önceden yükleme tarayıcısından yararlanmak için kritik kaynaklar, sunucu tarafından gönderilen HTML işaretlemesine dahil edilmelidir. Aşağıdaki kaynak yükleme kalıpları, önceden yükleme tarayıcısı tarafından keşfedilemez:
background-imageözelliği kullanılarak CSS ile yüklenen resimler. Bu resim referansları CSS'de yer alır ve önceden yükleme tarayıcısı tarafından keşfedilemez.- JavaScript kullanılarak DOM'a yerleştirilen
<script>öğe işaretlemesi biçimindeki dinamik olarak yüklenen komut dosyaları veya dinamikimport()kullanılarak yüklenen modüller. - JavaScript kullanılarak istemcide oluşturulan HTML. Bu tür işaretlemeler, JavaScript kaynaklarındaki dizelerde yer alır ve önceden yükleme tarayıcısı tarafından bulunamaz.
- CSS
@importbeyanları.
Bu kaynak yükleme kalıplarının tümü geç keşfedilen kaynaklardır ve bu nedenle önceden yükleme tarayıcısından yararlanmaz. Mümkün olduğunca bunlardan kaçının. Ancak bu tür kalıplardan kaçınmak mümkün değilse kaynak keşfinde gecikmeleri önlemek için preload ipucunu kullanabilirsiniz.
CSS
CSS, bir sayfanın sunumunu ve düzenini belirler. Daha önce de belirtildiği gibi CSS, oluşturmayı engelleyen bir kaynaktır. Bu nedenle, CSS'nizi optimize etmek genel sayfa yükleme süresini önemli ölçüde etkileyebilir.
Sadeleştirme
CSS dosyalarının küçültülmesi, CSS kaynağının dosya boyutunu küçülterek indirme hızını artırır. Bu işlem, öncelikle kaynak CSS dosyasındaki boşluklar ve diğer görünmez karakterler gibi içerikleri kaldırarak ve sonucu yeni optimize edilmiş bir dosyaya aktararak gerçekleştirilir:
/* Unminified CSS: */
/* Heading 1 */
h1 {
font-size: 2em;
color: #000000;
}
/* Heading 2 */
h2 {
font-size: 1.5em;
color: #000000;
}
/* Minified CSS: */
h1,h2{color:#000}h1{font-size:2em}h2{font-size:1.5em}
En temel biçimiyle CSS küçültme, web sitenizin FCP'sini ve bazı durumlarda LCP'sini iyileştirebilecek etkili bir optimizasyondur. Paketleyiciler gibi araçlar, üretim derlemelerinde bu optimizasyonu sizin için otomatik olarak gerçekleştirebilir.
Kullanılmayan CSS'yi kaldırın
Tarayıcının herhangi bir içeriği oluşturmadan önce tüm stil sayfalarını indirmesi ve ayrıştırması gerekir. Ayrıştırmanın tamamlanması için gereken süre, geçerli sayfada kullanılmayan stilleri de içerir. Tüm CSS kaynaklarını tek bir dosyada birleştiren bir paketleyici kullanıyorsanız kullanıcılarınız büyük olasılıkla mevcut sayfayı oluşturmak için gerekenden daha fazla CSS indiriyordur.
Geçerli sayfada kullanılmayan CSS'leri bulmak için Chrome Geliştirici Araçları'ndaki Kapsam aracını kullanın.
Kullanılmayan CSS'yi kaldırmanın iki yönlü etkisi vardır: İndirme süresini azaltmanın yanı sıra, tarayıcının daha az CSS kuralı işlemesi gerektiğinden oluşturma ağacı oluşturma işlemini de optimize edersiniz.
CSS @import beyanlarından kaçının
CSS'de @import bildirimleri kullanmak kolay gibi görünse de bu bildirimlerden kaçınmanız gerekir:
/* Don't do this: */
@import url('style.css');
<link> öğesinin HTML'de çalışmasına benzer şekilde, CSS'deki @import bildirimi, bir stil sayfası içinden harici bir CSS kaynağını içe aktarmanıza olanak tanır. Bu iki yaklaşım arasındaki temel fark, HTML <link> öğesinin HTML yanıtının bir parçası olması ve bu nedenle @import bildirimiyle indirilen bir CSS dosyasından çok daha önce keşfedilmesidir.
Bunun nedeni, bir @import beyanının keşfedilebilmesi için bunu içeren CSS dosyasının öncelikle indirilmesi gerektiğidir. Bu durum, istek zinciri olarak bilinen bir duruma yol açar. Bu durum, CSS söz konusu olduğunda bir sayfanın ilk oluşturma işleminin ne kadar süreceğini geciktirir. Bir diğer dezavantaj ise @import bildirimi kullanılarak yüklenen stil sayfalarının önceden yükleme tarayıcısı tarafından keşfedilememesi ve bu nedenle geç keşfedilen, oluşturmayı engelleyen kaynaklar haline gelmesidir.
<!-- Do this instead: -->
<link rel="stylesheet" href="style.css">
Çoğu durumda, @import yerine <link rel="stylesheet"> öğesini kullanabilirsiniz. <link> öğeleri, stil sayfalarının eşzamanlı olarak indirilmesine olanak tanır ve @import bildirimlerinin aksine genel yükleme süresini kısaltır. @import bildirimleri, stil sayfalarını ardışık olarak indirir.
@import söz dizimini, geliştirici deneyimini iyileştirmenin bir parçası olarak kullanır. Bu sayede kaynak dosyalar ayrı ve daha modüler hale gelir. Ancak bir CSS ön işlemcisi @import bildirimleriyle karşılaştığında, referans verilen dosyalar paketlenir ve tek bir stil sayfasına yazılır. Böylece, @import'nın düz CSS'de neden olduğu ardışık istek cezası önlenir.
Kritik CSS'leri satır içine alma
CSS dosyalarının indirilmesi, sayfanın FCP'sini artırabilir. Dokümanda kritik stillerin satır içi olarak eklenmesi <head> CSS kaynağı için ağ isteğini ortadan kaldırır ve doğru şekilde yapıldığında, kullanıcının tarayıcı önbelleği hazır olmadığında ilk yükleme sürelerini iyileştirebilir. Kalan CSS, eşzamansız olarak yüklenebilir veya <body> öğesinin sonuna eklenebilir.
<head>
<title>Page Title</title>
<!-- ... -->
<style>h1,h2{color:#000}h1{font-size:2em}h2{font-size:1.5em}</style>
</head>
<body>
<!-- Other page markup... -->
<link rel="stylesheet" href="non-critical.css">
</body>
Bununla birlikte, çok miktarda CSS'nin satır içi olarak eklenmesi, ilk HTML yanıtına daha fazla bayt ekler. HTML kaynakları genellikle çok uzun süre veya hiç önbelleğe alınamadığından, satır içi CSS'nin harici stil sayfalarında aynı CSS'yi kullanabilecek sonraki sayfalar için önbelleğe alınmadığı anlamına gelir. Ödünlerin çabaya değdiğinden emin olmak için sayfanızın performansını test edin ve ölçün.
CSS demoları
JavaScript
JavaScript, web'deki etkileşimlerin çoğunu destekler ancak bunun bir maliyeti vardır. Çok fazla JavaScript göndermek, sayfa yükleme sırasında web sayfanızın yavaş yanıt vermesine neden olabilir ve hatta etkileşimleri yavaşlatan yanıt verme sorunlarına yol açabilir. Bu sorunların her ikisi de kullanıcılar için can sıkıcı olabilir.
Oluşturmayı engelleyen JavaScript
defer veya async özellikleri olmadan <script> öğeleri yüklenirken tarayıcı, komut dosyası indirilene, ayrıştırılana ve yürütülene kadar ayrıştırma ve oluşturma işlemlerini engeller. Benzer şekilde, satır içi komut dosyaları da ayrıştırıcıyı komut dosyası ayrıştırılıp yürütülene kadar engeller.
async - defer
async ve defer, harici komut dosyalarının HTML ayrıştırıcıyı engellemeden yüklenmesine izin verirken type="module" içeren komut dosyaları (satır içi komut dosyaları dahil) otomatik olarak ertelenir. Ancak async ve defer arasında anlaşılması gereken bazı önemli farklar vardır.
async ile yüklenen komut dosyaları indirildikten hemen sonra ayrıştırılıp yürütülürken defer ile yüklenen komut dosyaları HTML belgesi ayrıştırma işlemi tamamlandığında yürütülür. Bu işlem, tarayıcının DOMContentLoaded etkinliğiyle aynı anda gerçekleşir.
Ayrıca, async komut dosyaları sırayla yürütülmeyebilir. defer komut dosyaları ise işaretlemede göründükleri sırayla yürütülür.
İstemci tarafı oluşturma
Genel olarak, kritik içerikleri veya bir sayfanın LCP öğesini oluşturmak için JavaScript kullanmaktan kaçınmanız gerekir. Bu, istemci tarafı oluşturma olarak bilinir ve tek sayfalık uygulamalarda (SPA'lar) yaygın olarak kullanılan bir tekniktir.
JavaScript ile oluşturulan işaretleme, önceden yükleme tarayıcısını atlar. Bunun nedeni, istemci tarafında oluşturulan işaretlemede bulunan kaynakların tarayıcı tarafından bulunamamasıdır. Bu durum, LCP resmi gibi önemli kaynakların indirilmesini geciktirebilir. Tarayıcı, LCP resmini yalnızca komut dosyası yürütüldükten ve öğe DOM'a eklendikten sonra indirmeye başlar. Buna karşılık, komut dosyası yalnızca keşfedildikten, indirildikten ve ayrıştırıldıktan sonra yürütülebilir. Bu durum, birbirini takip eden kritik istekler olarak bilinir ve kaçınılması gerekir.
Ayrıca, JavaScript kullanılarak oluşturulan işaretlemenin, gezinme isteğine yanıt olarak sunucudan indirilen işaretlemeye kıyasla uzun görevler oluşturma olasılığı daha yüksektir. HTML'nin istemci tarafında oluşturulmasının yoğun kullanımı, etkileşim gecikmesini olumsuz yönde etkileyebilir. Bu durum, özellikle bir sayfanın DOM'sinin çok büyük olduğu ve JavaScript'in DOM'u değiştirmesi durumunda önemli oluşturma çalışması gerektirdiği durumlarda geçerlidir.
Sadeleştirme
CSS'ye benzer şekilde, JavaScript'i küçültmek bir komut dosyası kaynağının dosya boyutunu küçültür. Bu, daha hızlı indirmelere yol açabilir ve tarayıcının JavaScript'i ayrıştırma ve derleme sürecine daha hızlı geçmesini sağlayabilir.
Ayrıca, JavaScript'in küçültülmesi, CSS gibi diğer öğelerin küçültülmesinden bir adım daha ileri gider. JavaScript küçültüldüğünde yalnızca boşluklar, sekmeler ve yorumlar gibi öğeler kaldırılmaz. Kaynak JavaScript'teki semboller de kısaltılır. Bu işleme bazen uglification adı verilir. Farkı görmek için aşağıdaki JavaScript kaynak kodunu kullanın:
// Unuglified JavaScript source code:
export function injectScript () {
const scriptElement = document.createElement('script');
scriptElement.src = '/js/scripts.js';
scriptElement.type = 'module';
document.body.appendChild(scriptElement);
}
Yukarıdaki JavaScript kaynak kodu küçültüldüğünde sonuç aşağıdaki kod snippet'ine benzer olabilir:
// Uglified JavaScript production code:
export function injectScript(){const t=document.createElement("script");t.src="/js/scripts.js",t.type="module",document.body.appendChild(t)}
Önceki snippet'te, kaynakta bulunan, insanlar tarafından okunabilir değişkenin scriptElement kısaltılarak t yapıldığını görebilirsiniz. Çok sayıda komut dosyasına uygulandığında, web sitesinin üretim JavaScript'inin sağladığı özellikler etkilenmeden oldukça önemli tasarruflar elde edilebilir.
Web sitenizin kaynak kodunu işlemek için bir paketleyici kullanıyorsanız üretim derlemeleri için genellikle otomatik olarak küçültme işlemi yapılır. Örneğin Terser gibi karartıcılar da son derece yapılandırılabilir. Bu sayede, maksimum tasarruf elde etmek için karartma algoritmasının agresifliğini ayarlayabilirsiniz. Ancak, herhangi bir ad karartma aracının varsayılan ayarları genellikle çıktı boyutu ile özelliklerin korunması arasında doğru dengeyi kurmak için yeterlidir.
JavaScript demoları
Bilginizi test etme
Tarayıcıya birden fazla CSS dosyası yüklemenin en iyi yolu nedir?
@import bildirimi.<link> öğesi.Tarayıcı ön yükleme tarayıcısı ne işe yarar?
<link rel="preload"> öğelerini algılar.
Tarayıcı, JavaScript kaynaklarını indirirken neden HTML'nin ayrıştırılmasını varsayılan olarak geçici olarak engeller?
Sonrakine geçme: Tarayıcıya kaynak ipuçlarıyla yardımcı olma
<head> öğesinde yüklenen kaynakların ilk sayfa yüklemesini ve çeşitli metrikleri nasıl etkileyebileceğini öğrendiğinize göre artık bir sonraki adıma geçebilirsiniz. Bir sonraki modülde, kaynak ipuçları ve bunların, tarayıcının kaynakları yüklemeye başlaması ve kaynaklar olmadan yapacağından daha erken bir zamanda kaynaklar arası sunuculara bağlantı açması için tarayıcıya nasıl değerli ipuçları verebileceği ele alınmaktadır.