Kaynak yüklemeyi optimize edin

Ö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 başvurulur. Bu kaynaklar, CSS aracılığıyla sayfaya görünüm ve düzen, JavaScript aracılığıyla da etkileşim özelliği kazandırır. 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ş içeriklerin anlık olarak görünmesini (FOUC) önlemek için oluşturmayı engeller.

Önceki videoda, sayfayı herhangi bir stil olmadan görebileceğiniz kısa bir FOUC (biçimlendirilmemiş içerik flaşı) 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 her zaman 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. Bu durum, komut dosyaları henüz oluşturulma aşamasındayken DOM'u değiştirebileceği veya DOM'a erişebileceği için tasarımdan kaynaklanmaktadır.

<!-- This is a parser-blocking script: -->
<script src="/script.js"></script>

Harici JavaScript dosyaları (async veya defer olmadan) kullanılırken dosya keşfedilip indirilene, ayrıştırılıp yürütülene kadar ayrıştırıcının engellenmesi. Satır içi JavaScript kullanılırken ayrıştırıcı, satır içi komut dosyası ayrıştırılıp yürütülene kadar 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ısı 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'dedir 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 dinamik import() 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 keşfedilemez.
  • CSS @import beyanları.

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ğunda 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 daha hızlı indirilmesini sağlar. Bu işlem, öncelikle kaynak CSS dosyasındaki boşluklar ve diğer görünmez karakterler gibi içeriklerin kaldırılması ve sonucun yeni optimize edilmiş bir dosyaya aktarılmasıyla 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ıca, ayrıştırmanın tamamlanması için gereken süreye geçerli sayfada kullanılmayan stiller de dahildir. 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.

Mevcut sayfada kullanılmayan CSS'leri bulmak için Chrome Geliştirici Araçları'ndaki Kapsam aracını kullanın.

Chrome Geliştirici Araçları&#39;ndaki kapsam aracının ekran görüntüsü. Alt bölmede bir CSS dosyası seçilir ve mevcut sayfa düzeni tarafından kullanılmayan önemli miktarda CSS gösterilir.
Chrome Geliştirici Araçları'ndaki kapsam aracı, geçerli sayfa tarafından kullanılmayan CSS'yi (ve JavaScript'i) tespit etmek için kullanışlıdır. Sayfanın oluşturulmasını geciktirebilecek çok daha büyük bir CSS paketi göndermek yerine, CSS dosyalarını farklı sayfalar tarafından yüklenecek birden fazla kaynağa bölmek için kullanılabilir.

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

Kolaylık sağlasa da CSS'de @import bildirimlerinden kaçınmalısınız:

/* Don't do this: */
@import url('style.css');

<link> öğesinin HTML'deki işleyişine 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 önce 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.

Kritik CSS'leri satır içine alma

CSS dosyalarının indirilmesi, bir 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 fazla 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, harici stil sayfalarında aynı CSS'yi kullanabilecek sonraki sayfalar için önbelleğe alınmaz. Ö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ırmayı ve oluşturmayı 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.

Çeşitli komut dosyası yükleme mekanizmalarının gösterimi. Tüm mekanizmalar, ayrıştırıcı, getirme ve yürütme rollerini; async, defer, type=&#39;module&#39; gibi kullanılan çeşitli özelliklere ve üçünün kombinasyonuna göre ayrıntılı olarak açıklar.
https://html.spec.whatwg.org/multipage/scripting.html adresinden alınmıştı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, istemci tarafından oluşturulan işaretlemenin içerdiği kaynaklar önceden yükleme tarayıcısı tarafından keşfedilemediği için önceden yükleme tarayıcısını atlar. Bu durum, LCP resmi gibi önemli kaynakların indirilmesini geciktirebilir. Tarayıcı, komut dosyası yürütülüp öğe DOM'a eklendikten sonra LCP resmini 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ı tetiklediğ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 durum, 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 (çirkinleştirme) 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, t olarak kısaltıldığını görebilirsiniz. Çok sayıda komut dosyasına uygulandığında, web sitesinin üretim JavaScript'inin sağladığı özellikleri etkilemeden oldukça önemli tasarruflar elde edilebilir.

Web sitenizin kaynak kodunu işlemek için bir paketleyici kullanıyorsanız üretim derlemelerinde 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?

Birden fazla <link> öğesi.
CSS @import bildirimi.

Tarayıcı ön yükleme tarayıcısı ne işe yarar?

Bir HTML kaynağındaki <link rel="preload"> öğelerini algılar.
Bu, DOM ayrıştırıcının kaynakları daha erken keşfedebilmesi için ham işaretlemeyi inceleyerek kaynakları keşfeden ikincil bir HTML ayrıştırıcısıdır.

Tarayıcı, JavaScript kaynaklarını indirirken neden HTML ayrıştırmasını varsayılan olarak geçici olarak engeller?

Biçimlendirilmemiş İçerik Yanıp Sönmesini (FOUC) önlemek için.
Bunun nedeni, komut dosyalarının DOM'u değiştirebilmesi veya başka bir şekilde erişebilmesidir.
Çünkü JavaScript'i değerlendirmek çok fazla CPU kaynağı gerektiren bir görevdir ve HTML ayrıştırmayı duraklatmak, komut dosyalarının yüklenmesini tamamlamak için CPU'ya daha fazla bant genişliği sağlar.

Sıradaki: Kaynak ipuçlarıyla tarayıcıya 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ı inceleniyor ve bu ipuçlarının, tarayıcının kaynakları yüklemeye başlaması ve kaynaklar olmadan yapacağından daha erken bir zamanda, kaynaklar arası sunucularla bağlantı açması için tarayıcıya nasıl değerli ipuçları verebileceği açıklanıyor.