Kaynak yüklemeyi optimize edin

Önceki modülde, kritik oluşturma yolunun arkasındaki bazı teorilerin yanı sıra, oluşturma ve ayrıştırıcı engelleme kaynaklarının bir sayfanın ilk oluşturulmasını nasıl geciktirebileceği incelenmiştir. Artık bunun arkasındaki teorinin bir kısmını anladığınıza göre kritik oluşturma yolunu optimize etmek için bazı teknikleri öğrenmeye hazırsınız.

Bir sayfa yüklenirken, HTML'si içinde birçok kaynağa başvurulur. Bunlar, CSS aracılığıyla görünümü ve düzeninin yanı sıra JavaScript aracılığıyla etkileşimine sahip bir sayfa sağlar. Bu modülde, bu kaynaklarla ilgili bir dizi önemli kavram ve bunların bir sayfanın yükleme süresini nasıl etkilediği ele alınmaktadır.

Oluşturma engelleme

Önceki modülde de açıklandığı gibi CSS, CSS Nesne Modeli (CSSOM) oluşturulana kadar tarayıcının herhangi bir içeriği oluşturmasını engellediğinden oluşturmayı engelleyen bir kaynaktır. Tarayıcı, kullanıcı deneyimi açısından istenmeyen bir Stil Dışı İçerik Flash'ı (FOUC) olmasını önlemek için oluşturmayı engeller.

Önceki videoda, sayfayı herhangi bir stil olmadan görebileceğiniz kısa bir FOUC vardır. Daha sonra, sayfanın CSS'sinin ağdan yüklenmesi tamamlandıktan sonra tüm stiller uygulanır ve sayfanın stil olmayan sürümü hemen stilize edilmiş sürümle değiştirilir.

Genel olarak, FOUC normalde görmediğiniz bir şeydir ancak CSS indirilip sayfaya uygulanana kadar tarayıcının sayfanın oluşturulmasını neden engellediğini bilmeniz için kavramın anlaşılması önemlidir. Oluşturma engelleme istenmeyen bir durum değildir ancak CSS'nizi optimize edilmiş tutarak bu işlemin ne kadar süreceğini en aza indirmek istiyorsunuz.

Ayrıştırıcı engelleme

Ayrıştırıcı engelleme kaynağı, async veya defer özellikleri olmayan <script> öğesi gibi HTML ayrıştırıcısını kesintiye uğratır. Ayrıştırıcı bir <script> öğesiyle karşılaştığında, HTML'nin geri kalanını ayrıştırmaya geçmeden önce tarayıcının komut dosyasını değerlendirmesi ve yürütmesi gerekir. Komut dosyaları, oluşturulma aşamasındaki bir süre boyunca DOM'a erişim sağlayabildiği için bu bir tasarımdır.

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

Harici JavaScript dosyaları (async veya defer olmadan) kullanılırken ayrıştırıcı, dosya keşfedilene kadar indirilen, ayrıştırılana ve çalıştırılana kadar engellenir. Satır içi JavaScript kullanılırken satır içi komut dosyası ayrıştırılana ve yürütülene kadar ayrıştırıcı benzer şekilde engellenir.

Önceden yükleme tarayıcısı

Önceden yükleme tarayıcısı, ham HTML yanıtını tarayarak birincil HTML ayrıştırıcı tarafından keşfedilmeden önce kaynakları bulup kurgusal olarak getiren ikincil bir HTML ayrıştırıcısı biçiminde bir tarayıcı optimizasyonudur. Örneğin, ön yükleme tarayıcısı CSS ve JavaScript gibi kaynakları getirirken HTML ayrıştırıcı engellenmiş olsa bile tarayıcının <img> öğesinde belirtilen bir kaynağı indirmeye başlamasına izin verir.

Önceden yükleme tarayıcısından yararlanmak için kritik kaynakların, sunucu tarafından gönderilen HTML işaretlemesine dahil edilmesi gerekir. Aşağıdaki kaynak yükleme kalıpları, önceden yükleme tarayıcısı tarafından keşfedilemez:

  • Resimler, CSS tarafından background-image özelliği kullanılarak yüklenir. Bu resim referansları CSS'dedir ve ön yükleme tarayıcısı tarafından keşfedilemez.
  • JavaScript veya dinamik import() kullanılarak yüklenen modüller kullanılarak DOM'a yerleştirilen <script> öğe işaretlemesi biçiminde dinamik olarak yüklenmiş komut dosyaları.
  • JavaScript kullanılarak istemcide oluşturulan HTML. Bu tür işaretlemeler, JavaScript kaynaklarındaki dizeler içinde bulunur ve önceden yükleme tarayıcısı tarafından bulunabilir.
  • CSS @import bildirimleri.

Bu kaynak yükleme kalıplarının tümü geç keşfedilen kaynaklardır ve bu nedenle ön yükleme tarayıcısından yararlanamaz. Mümkün olduğu sürece bunlardan kaçının. Ancak bu tür kalıplardan kaçınmak mümkün değilse kaynak keşfi gecikmelerini önlemek için bir preload ipucu kullanabilirsiniz.

CSS

CSS, sayfaların sunumunu ve düzenini belirler. Daha önce açıklandığı gibi, CSS oluşturmayı engelleyen bir kaynaktır. Bu nedenle CSS'nizi optimize etmenin genel sayfa yüklenme süresi üzerinde önemli bir etkisi olabilir.

Küçültme

CSS dosyalarını küçültmek, CSS kaynağının dosya boyutunu küçülterek indirilmesini hızlandırır. Bu öncelikle, boşluk ve diğer görünmez karakterler gibi kaynak CSS dosyasındaki içeriğin kaldırılması ve sonucun çıktısını yeni optimize edilmiş bir dosyanın oluşturulmasıyla yapılır:

/* 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}

CSS küçültme, en temel şekliyle web sitenizin FCP'sini, hatta bazı durumlarda LCP'yi iyileştirebilecek etkili bir optimizasyondur. Paketler gibi araçlar, üretim derlemelerinde bu optimizasyonu sizin için otomatik olarak gerçekleştirebilir.

Kullanılmayan CSS'yi kaldırın

Herhangi bir içeriği oluşturmadan önce, tarayıcının tüm stil sayfalarını indirip ayrıştırması gerekir. Ayrıştırma işleminin 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 muhtemelen geçerli sayfayı oluşturmak için gerekenden daha fazla CSS indiriyordur.

Geçerli sayfadaki kullanılmayan CSS'yi 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ölmesinde geçerli sayfa düzeni tarafından kullanılmayan CSS&#39;nin önemli bir kısmını gösteren bir CSS dosyası seçilidir.
Chrome Geliştirici Araçları'ndaki kapsam aracı, geçerli sayfa tarafından kullanılmayan CSS'yi (ve JavaScript'i) algılamak için yararlı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 önemli 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ı yapısını optimize etmiş olursunuz.

CSS @import bildirimlerinden kaçının

Her ne kadar pratik görünse de CSS'de @import bildirimleri kullanmaktan kaçınmalısınız:

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

<link> öğesinin HTML'deki çalışma şekline benzer şekilde, CSS'deki @import bildirimi de bir stil sayfasından harici bir CSS kaynağını içe aktarmanıza olanak tanır. Bu iki yaklaşım arasındaki en önemli 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 erken keşfedilmesidir.

Bunun nedeni, @import bildiriminin bulunması için öncelikle bu bildirimi içeren CSS dosyasının indirilmesidir. Bu, istek zinciri olarak bilinen bir duruma neden olur. CSS'de bu, bir sayfanın ilk kez oluşturulmasının ne kadar sürdüğünü geciktirir. Diğer bir dezavantaj, @import bildirimi kullanılarak yüklenen stil sayfalarının ön yükleme tarayıcısı tarafından keşfedilemeyen ve bu nedenle geç keşfedilen oluşturma engelleyici kaynaklara dönüşmesidir.

<!-- Do this instead: -->
<link rel="stylesheet" href="style.css">

Çoğu durumda @import öğesini bir <link rel="stylesheet"> öğesi kullanarak değiştirebilirsiniz. <link> öğeleri, stil sayfalarının eşzamanlı olarak indirilmesine olanak tanır ve stil sayfalarını ardışık olarak indiren @import bildirimlerinin aksine genel yükleme süresini azaltır.

Kritik CSS'leri satır içine alın

CSS dosyalarının indirilmesi için gereken süre sayfanın FCP değerini artırabilir. <head> dokümanında kritik stillerin satır içine alınması, CSS kaynağına yönelik ağ isteğini ortadan kaldırır ve doğru 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>

Olumsuz yönde, büyük miktarda CSS'yi satır içine almak, ilk HTML yanıtına daha fazla bayt ekler. HTML kaynakları genellikle çok uzun süre (veya hiç) önbelleğe alınamadığı için bu, 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 verdiğiniz ç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şimin çoğunu sağlar, ancak bunun bir maliyeti vardır. Çok fazla JavaScript yüklemek, sayfa yüklenirken web sayfanızın yavaş yanıt vermesine neden olabilir ve etkileşimleri yavaşlatan yanıt verme sorunlarına neden olabilir. Bu her iki durum da kullanıcılar için can sıkıcı olabilir.

Oluşturmayı engelleyen JavaScript

Tarayıcı, defer veya async özellikleri olmadan <script> öğelerini yüklerken 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ı, komut dosyası ayrıştırılıp yürütülene kadar ayrıştırıcıyı engeller.

async - defer maçı

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ı farklılıklar vardır.

Çeşitli komut dosyası yükleme mekanizmalarının tasviri. Bunların tümü, eşzamansız, defer, type=&#39;module&#39; gibi çeşitli özelliklere ve bu üçünün bir kombinasyonuna göre ayrıştırıcı, getirme ve yürütme rollerini ayrıntılı bir şekilde gösterir.
Kaynak: https://html.spec.whatwg.org/multipage/scripting.html

async ile yüklenen komut dosyaları indirildikten hemen sonra ayrıştırılır ve 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, tarayıcının DOMContentLoaded etkinliğiyle aynı anda gerçekleşir. Ayrıca, async komut dosyaları sıra dışı olarak yürütülürken defer komut dosyaları, 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çınmalısınız. Bu, istemci tarafı oluşturma olarak bilinir ve Tek Sayfalık Uygulamalarda (SPA'lar) yaygın olarak kullanılan bir tekniktir.

İstemci tarafından oluşturulan işaretlemede bulunan kaynaklar, bu işaretleme tarafından bulunabileceğinden JavaScript tarafından oluşturulan işaretleme, önceden yükleme tarayıcısının ilerlemesini engeller. Bu durum, LCP görüntüsü gibi önemli kaynakların indirilmesini geciktirebilir. Tarayıcı, yalnızca komut dosyası yürütüldükten ve öğeyi DOM'ye ekledikten sonra LCP görüntüsünü indirmeye başlar. Komut dosyası ancak keşfedildikten, indirildikten ve ayrıştırıldıktan sonra yürütülebilir. Bu, kritik istek zinciri olarak bilinir ve kaçınılmalıdır.

Ayrıca, işaretlemeyi JavaScript kullanarak oluşturmak, gezinme isteğine yanıt olarak sunucudan indirilen işaretlemeden uzun görevler oluşturma olasılığından daha yüksektir. HTML'nin istemci tarafında oluşturmanın yoğun şekilde kullanılması, etkileşim gecikmesini olumsuz etkileyebilir. Bu durum özellikle bir sayfa DOM'sinin çok büyük olduğu durumlarda geçerlidir. Bu durum, JavaScript DOM'u değiştirdiğinde önemli bir oluşturma işlemi tetikler.

Küçültme

CSS'ye benzer şekilde, JavaScript'i küçültmek komut dosyası kaynağının dosya boyutunu küçültür. Bu da indirme işlemlerinin daha hızlı olmasını sağlayabilir ve tarayıcının JavaScript'i daha hızlı ayrıştırma ve derleme işlemine devam etmesine olanak tanır.

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şluk, sekme ve yorum gibi öğelerden arındırılmaz, aynı zamanda kaynak JavaScript'teki simgeler kısaltılır. Bu işlem bazen uglification olarak da bilinir. Farkı görmek için aşağıdaki JavaScript kaynak kodunu alı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);
}

Önceki JavaScript kaynak kodu karıştırıldığında sonuç aşağıdaki kod snippet'i gibi görünebilir:

// 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, kaynaktaki insan tarafından okunabilir değişkenin scriptElement t değerine kısaltıldığını görebilirsiniz. Geniş bir komut dosyası koleksiyonuna uygulandığında, tasarruflar bir web sitesinin üretim JavaScript'inin sağladığı özellikleri etkilemeden oldukça önemli olabilir.

Web sitenizin kaynak kodunu işlemek için bir paketleyici kullanıyorsanız düzenleme, üretim derlemeleri için genellikle otomatik olarak gerçekleştirilir. Örneğin, Terser gibi yükselticiler de son derece yapılandırılabilir. Bu da, maksimum tasarruf elde etmek için düzeltme algoritmasının agresifliğini değiştirmenize olanak tanır. Bununla birlikte, tüm tekilleştirme araçlarının varsayılan değerleri genellikle çıktı boyutu ile özelliklerin korunması arasında doğru dengeyi kurmak için yeterlidir.

JavaScript demoları

Bilginizi test etme

Tarayıcıda birden fazla CSS dosyası yüklemenin en iyi yolu nedir?

CSS @import beyanı.
Tekrar deneyin.
Birden çok <link> öğesi.
Doğru.

Tarayıcı önceden yükleme tarayıcısı ne yapar?

Kaynakları DOM ayrıştırıcıdan önce keşfedip daha erken keşfetmek için ham işaretlemeyi inceleyen ikincil bir HTML ayrıştırıcısıdır.
Doğru.
Bir HTML kaynağındaki <link rel="preload"> öğelerini algılar.
Tekrar deneyin.

Tarayıcı JavaScript kaynaklarını indirirken neden varsayılan olarak HTML'nin ayrıştırılmasını geçici olarak engelliyor?

Stilsiz İçeriğin (FOUC) Flash'ını önlemek için.
Tekrar deneyin.
JavaScript'in değerlendirilmesi çok CPU yoğun bir iştir ve HTML ayrıştırmasının duraklatılması, komut dosyalarının yüklenmesini tamamlamak için CPU'ya daha fazla bant genişliği sağlar.
Tekrar deneyin.
Komut dosyaları DOM'da değişiklik yapabilir veya DOM'ye başka bir şekilde erişebilir.
Doğru.

Sıradaki: Tarayıcıya kaynak ipuçları konusunda 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 devam edebilirsiniz. Bir sonraki modülde, kaynak ipuçları ve bunların, kaynakları yüklemeye ve çapraz kaynak sunuculara bağlantı oluşturmaya başlaması için tarayıcının aksi takdirde erişemeyeceğinden daha kısa sürede tarayıcıya nasıl değerli ipuçları verebilecekleri açıklanmaktadır.