JavaScript çerçevelerinde kaynak satır içine alma

JavaScript ekosisteminde Largest Contentful Paint'i iyileştirme.

Google, Aurora projesi kapsamında, Core Web Vitals'a göre iyi performans göstermeleri için popüler web çerçeveleriyle birlikte çalışıyor. Angular ve Next.js'de yazı tipi satır içi ekleme özelliği kullanıma sunulmuştur. Bu özellik bu makalenin ilk bölümünde açıklanmıştır. Ele alacağımız ikinci optimizasyon, kritik CSS satır içi eklemedir. Bu özellik artık Angular CLI'de varsayılan olarak etkindir ve Nuxt.js'de uygulama aşamasındadır.

Yazı tipi satır içi ekleme

Aurora ekibi, yüzlerce uygulamayı analiz ettikten sonra geliştiricilerin genellikle index.html öğesindeki <head> öğesine referans vererek yazı tiplerini uygulamalarına dahil ettiğini tespit etti. Aşağıda, Material Icons'un dahil edildiği bir örneği görebilirsiniz:

<!doctype html>
<html lang="en">
<head>
  <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
  ...
</html>

Bu kalıp tamamen geçerli ve işlevsel olsa da uygulamanın oluşturulmasını engeller ve ek bir istek ekler. Olan biteni daha iyi anlamak için yukarıdaki HTML'de referans verilen stil sayfasının kaynak koduna göz atın:

/* fallback */
@font-face {
  font-family: 'Material Icons';
  font-style: normal;
  font-weight: 400;
  src: url(https://fonts.gstatic.com/font.woff2) format('woff2');
}

.material-icons {
  /*...*/
}

font-face tanımının fonts.gstatic.com adresinde barındırılan harici bir dosyaya nasıl referans verdiğini görebilirsiniz. Uygulamayı yüklerken tarayıcının önce başlıkta referans verilen orijinal stil sayfasını indirmesi gerekir.

Web sitesinin sunucuya istek gönderip harici stil sayfasını nasıl indirmesi gerektiğini gösteren resim
Web sitesi ilk olarak yazı tipi stil sayfasını yükler.

Ardından tarayıcı, woff2 dosyasını indirir ve uygulamayı oluşturmaya devam edebilir.

Biri yazı tipi stil sayfası, diğeri yazı tipi dosyası için olmak üzere yapılan iki isteği gösteren resim.
Ardından, yazı tipinin yüklenmesi için istek gönderilir.

Optimize etme fırsatı olarak, ilk stil sayfasını derleme sırasında indirip index.html içine satır içi olarak ekleyebilirsiniz. Bu sayede, çalışma zamanında CDN'ye yapılan gidiş dönüş işleminin tamamı atlanır ve engelleme süresi kısalır.

Uygulama oluşturulurken CDN'ye bir istek gönderilir. Bu istek, stil sayfasını getirir ve HTML dosyasına satır içi olarak ekler. Bu işlem, alana bir <link rel=preconnect> ekler. Bu tekniği uyguladığımızda aşağıdaki sonucu elde ederiz:

<!doctype html>
<html lang="en">
<head>
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin >
  <style type="text/css">
  @font-face{font-family:'Material Icons';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/font.woff2) format('woff2');}.material-icons{/*...*/}</style>
  ...
</html>

Yazı tipi içe yerleştirme özelliği artık Next.js ve Angular'da kullanılabilir

Çerçeve geliştiricileri, temel araçta optimizasyon uyguladığında mevcut ve yeni uygulamaların bu özelliği etkinleştirmesini kolaylaştırarak iyileştirmeyi tüm ekosisteme getirir.

Bu iyileştirme, Next.js 10.2 ve Angular 11 sürümlerinden itibaren varsayılan olarak etkindir. Her ikisinde de Google ve Adobe yazı tiplerinin yerleştirilmesi desteklenir. Angular, ikincisini 12.2 sürümünde kullanıma sunmayı planlıyor.

Next.js'de yazı tipi satır içi ekleme uygulamasını GitHub'da bulabilir ve bu optimizasyonu Angular bağlamında açıklayan videoya göz atabilirsiniz.

Kritik CSS'leri satır içine alma

Kritik CSS'yi satır içi olarak ekleyerek İlk Zengin İçerikli Boyama (FCP) ve Largest Contentful Paint (LCP) metriklerini iyileştirmek de bir diğer geliştirmedir. Bir sayfanın kritik CSS'si, ilk oluşturulmasında kullanılan tüm stilleri içerir. Konu hakkında daha fazla bilgi edinmek için Kritik olmayan CSS'yi erteleme başlıklı makaleyi inceleyin.

Birçok uygulamanın, stili eşzamanlı olarak yüklediğini ve bu durumun uygulama oluşturmayı engellediğini tespit ettik. Hızlı bir çözüm olarak stilleri eşzamansız olarak yükleyebilirsiniz. Komut dosyalarını media="all" ile yüklemek yerine media özelliğinin değerini print olarak ayarlayın ve yükleme tamamlandıktan sonra özellik değerini all ile değiştirin:

<link rel="stylesheet" href="..." media="print" onload="this.media='all'">

Ancak bu uygulama, stil uygulanmamış içeriğin titremesine neden olabilir.

Türler yüklenirken sayfa titrer.

Yukarıdaki videoda, stillerini eşzamansız olarak yükleyen bir sayfanın oluşturulması gösterilmektedir. Yanıp sönme, tarayıcı önce stilleri indirmeye başladığı ve ardından HTML'yi oluşturmaya başladığı için gerçekleşir. Tarayıcı, stilleri indirdikten sonra bağlantı öğesinin onload etkinliğini tetikler, media özelliğini all olarak günceller ve stilleri DOM'a uygular.

HTML'nin oluşturulması ile stillerin uygulanması arasındaki süre boyunca sayfanın stili kısmen kaldırılır. Tarayıcı stilleri kullandığında titreme görüyoruz. Bu, kötü bir kullanıcı deneyimidir ve Kümülatif Yerleşim Kayması (CLS)'nda gerilemelere neden olur.

Eşzamansız stil yüklemeyle birlikte kritik CSS'yi satır içine yerleştirme, yükleme davranışını iyileştirebilir. Tarama aracı, stil sayfasındaki seçicilere bakarak ve bunları HTML ile eşleştirerek sayfada hangi stillerin kullanıldığını bulur. Bir eşleşme bulduğunda, ilgili stilleri kritik CSS'nin bir parçası olarak kabul eder ve satır içine yerleştirir.

Bunu bir örnek üzerinde inceleyelim:

Yapılmaması gerekenler:
<head>
   <link rel="stylesheet" href="/styles.css" media="print" onload="this.media='all'">
</head>
<body>
  <section>
    <button class="primary"></button>
  </section>
</body>
/* styles.css */
section button.primary {
  /* ... */
}
.list {
  /* ... */
}

Satır içi yerleştirilmeden önceki örnek.

Yukarıdaki örnekte, critters styles.css içeriğini okur ve ayrıştırır, ardından iki seçiciyi HTML ile eşleştirir ve section button.primary kullandığımızı keşfeder. Son olarak, critters, ilgili stilleri sayfanın <head> içine satır içi olarak ekler. Bu işlem sonucunda:

Yapılması gerekenler
<head>
  <link rel="stylesheet" href="/styles.css" media="print" onload="this.media='all'">
  <style>
  section button.primary {
    /* ... */
  }
  </style>
</head>
<body>
  <section>
    <button class="primary"></button>
  </section>
</body>

Satır içi yerleştirildikten sonraki örnek.

Kritik CSS'yi HTML'ye yerleştirdikten sonra sayfanın titremesinin ortadan kalktığını göreceksiniz:

CSS satır içine alındıktan sonra sayfanın yüklenmesi.

Kritik CSS satır içi ekleme özelliği artık Angular'da kullanılabilir ve v12'de varsayılan olarak etkindir. 11. sürüm kullanıyorsanız angular.json'de inlineCritical özelliğini true olarak ayarlayarak özelliği etkinleştirin. Next.js'de bu özelliği etkinleştirmek için next.config.js dosyanıza experimental: { optimizeCss: true } ekleyin.

Sonuçlar

Bu yayında, Chrome ile web çerçeveleri arasındaki bazı işbirliklerine değindik. Çerçeve yazarıysanız ve teknolojinizde ele aldığımız bazı sorunları tanıyorsanız bulgularımızın benzer performans optimizasyonları uygulamanıza ilham vermesini umuyoruz.

İyileştirmeler hakkında daha fazla bilgi edinin. Core Web Vitals için yaptığımız optimizasyon çalışmalarının kapsamlı bir listesini Aurora'yı tanıtıyoruz başlıklı makalede bulabilirsiniz.