Kod bölmeli JavaScript

Büyük JavaScript kaynaklarının yüklenmesi sayfa hızını önemli ölçüde etkiler. Yarma Baltası JavaScript'inizi daha küçük parçalara ayırarak ve sadece başlatma sırasında çalışacak bir sayfa, sayfanızın yüklenmesini büyük ölçüde iyileştirebilir duyarlılığı, bu da sayfanızın Sonrakiyle Etkileşimi'ni iyileştirebilir Boyama (INP).

Bir sayfa büyük JavaScript dosyalarını indirir, ayrıştırır ve derlerken, JavaScript dosyaları belli bir süre yanıt vermeyebilir. Sayfa öğeleri bir sayfanın ilk HTML'sinin bölümüdür ve stili CSS tarafından belirlenir. Ancak, JavaScript ve komut dosyası tarafından yüklenen diğer komut dosyalarını desteklemek için JavaScript'i ayrıştırıp yürütüyor olabilir. İlgili içeriği oluşturmak için kullanılan sonuçta, kullanıcı etkileşimin önemli ölçüde gerçekleşiyormuş gibi gecikebilir ve hatta kırılabilir.

Bu genellikle, JavaScript ayrıştırıldığında ana iş parçacığının engellenmesinden kaynaklanır ana iş parçacığında derlenir. Bu süreç çok uzun sürerse, etkileşimli bir sayfa öğeleri, kullanıcı girişine yeterince hızlı yanıt vermeyebilir. Bunun telafilerinden biri sayfanın çalışması için ihtiyacınız olan JavaScript'i yüklemektir. kod adı verilen bir teknikle diğer JavaScript'in daha sonra yüklenmesini engellemek bölme. Bu modülde, bu iki teknikten ikincisi ele alınmaktadır.

Kod bölme sayesinde başlatma sırasında JavaScript ayrıştırma ve yürütme sürecini azaltın

JavaScript yürütme 2'den uzun sürdüğünde Lighthouse bir uyarı gönderir saniyedir ve 3, 5 saniyeden uzun sürdüğünde başarısız olur. Aşırı JavaScript ayrıştırma ve yürütme, sayfanın herhangi bir noktasında potansiyel bir sorundur Etkileşimin giriş gecikmesini artırma potansiyeline sahip olduğundan Kullanıcının sayfayla etkileşime girdiği zaman o ana denk geliyorsa JavaScript'i işlemekten ve yürütmekten sorumlu ana iş parçacığı görevleri şunlardır: çalışıyor.

Ayrıca, aşırı JavaScript yürütme ve ayrıştırma işlemleri, ilk sayfa yükleme sırasında sorunlu olabilir; çünkü bu, sayfadaki nokta büyük olasılıkla kullanıcıların sayfayla etkileşime girmesini sağlayabilecek yaşam döngüsünü içerir. Hatta, Bir yükleme yanıt hızı metriği olan Toplam Engelleme Süresi (TBT) yüksek düzeyde ilişkilidir. INP ile ifade edilir. Bu, kullanıcıların etkileşime geçme eğiliminin yüksek olduğunu gösterir. sırasında yüklenenleri daraltır.

Her bir JavaScript dosyasını yürütmek için harcanan süreyi bildiren Lighthouse denetimi yardımcı olması açısından önemlidir. Bu sayede, sayfa isteklerinizin komut dosyaları kod bölme için aday olabilir. Ardından, hedeflerinize ulaşmak için Chrome Geliştirici Araçları'ndaki kapsam aracını kullanarak sayfa yükleme sırasında bir sayfanın JavaScript'i kullanılmaz.

Kod bölme, bir sayfanın ilk JavaScript'ini azaltabilecek faydalı bir tekniktir yükler. Bir JavaScript paketini iki bölüme ayırmanıza olanak tanır:

  • Sayfa yüklenirken JavaScript gerekir, bu nedenle başka bir yerde yüklenemez gerekir.
  • Daha sonra, çoğu zaman yüklenebilecek kalan JavaScript kullanıcının belirli bir etkileşimli öğeyle etkileşimde bulunduğu anda yapalım.

Kod bölme işlemi, dinamik import() söz dizimi kullanılarak yapılabilir. Bu söz dizimi (belirli bir JavaScript kaynağını isteyen <script> öğelerinin aksine) başlatma sırasında—ileride bir JavaScript kaynağı için istekte bulunur değişiklik gösterir.

document.querySelectorAll('#myForm input').addEventListener('blur', async () => {
  // Get the form validation named export from the module through destructuring:
  const { validateForm } = await import('/validate-form.mjs');

  // Validate the form:
  validateForm();
}, { once: true });

Önceki JavaScript snippet'inde validate-form.mjs modülü bir kullanıcı bir formun herhangi bir öğesini bulanıklaştırdığında indirilir, ayrıştırılır ve yürütülür <input> alanları için geçerlidir. Böyle bir durumda, formun doğrulama mantığının çalıştırılması, yalnızca bu biçimin kullanılmasıdır.

webpack, Parcel, Rollup ve esbuild gibi JavaScript paketleyicileri JavaScript paketlerini daha küçük parçalara bölecek şekilde kaynak kodunuzda dinamik import() çağrısı ile karşılaşırsınız. Bu araçların çoğu bunu otomatik olarak yapabilirsiniz, ancak özellikle optimize edebilirsiniz.

Kod bölmeyle ilgili faydalı notlar

Kod bölme, ana iş parçacığı anlaşmazlığını azaltmada etkili bir yöntem olsa da ilk sayfa yükleme sırasında, sayfa yüklemenizin neredeyse her 2'ye kadar olduğu gibi ziyaret edin.

Mümkünse bir paketleyici kullanın

Güncelleme sırasında geliştiricilerin JavaScript modüllerini kullanması, sürecidir. Geliştirici deneyimini iyileştirmesi, kod okunabilirliğini ve sürdürülebilirliğini iyileştirir. Ancak bununla ilgili JavaScript'i gönderirken ortaya çıkabilecek optimum olmayan performans özellikleri üretim sürecine gönderebilirsiniz.

En önemlisi, kaynağınızı işlemek ve optimize etmek için bir paketleyici kullanmanız gerekir. istediğiniz modüller de dahil olmak üzere kod. Paketleyiciler proje açısından JavaScript kaynak koduna optimizasyon yapmanın yanı sıra, paket boyutu gibi performans konularının dengelenmesinde oldukça etkilidir. karşılaştırabilirsiniz. Paket boyutu arttıkça sıkıştırma etkisi de artar. Ancak paketleyiciler paketlerin çok büyük olmamasına rağmen uzun görevler olabilir.

Paketleyiciler, çok sayıda paketlenmemiş modülü göndermek de kullanabilirsiniz. JavaScript modüllerini kullanan mimariler genellikle ağaçlarından bazılarını oluşturmak için kullanabilirsiniz. Modül ağaçları ayrıştırıldığında, her modül bir grubu temsil eder ve ayrı bir HTTP isteği kullanıyorsanız web uygulamanızdaki etkileşim gecikmeli olarak kullanmayın. Her ne kadar Büyük modül ağaçlarını erken yüklemek için <link rel="modulepreload"> kaynak ipucu JavaScript paketlerinin, yükleme performansına göre hâlâ tercih edilmesi çok önemli.

Akış derlemesini yanlışlıkla devre dışı bırakmayın

Chromium'un V8 JavaScript motoru, kullanıma hazır birçok optimizasyon sunar JavaScript kodunuzun mümkün olduğunca verimli bir şekilde yüklendiğinden emin olun. Bu optimizasyonlardan biri akış derlemesi olarak bilinir. tarayıcıya aktarılan HTML'nin artımlı ayrıştırılması; JavaScript'i kullanır.

Akış derlemesinin, web sitenizin Chromium'daki web uygulaması:

  • JavaScript modüllerini kullanmaktan kaçınmak için üretim kodunuzu dönüştürün. Paketleyiciler JavaScript kaynak kodunuzu bir derleme hedefine göre dönüştürebilir ve belirli bir ortama özgüdür. V8, canlı oynatmayı uygular bir JavaScript kodu derlemesi yapabilir ve bunu kolayca Paketleyicinizi, JavaScript modülü kodunuzu söz dizimine dönüştürecek şekilde yapılandırın JavaScript modüllerini ve özelliklerini kullanmayanlar.
  • JavaScript modüllerini üretime göndermek istiyorsanız şunu kullanın: .mjs uzantısı. Üretim JavaScript'inizin modülleri kullanıp kullanmadığına bakılmaksızın, JavaScript yerine modül kullanan JavaScript'ler için özel bir içerik türü yoktur anlamak mümkün. V8 söz konusu olduğunda, akışın kapsamı dışında kalmayı seçmiş olursunuz. .js kullanarak JavaScript modüllerini üretimde gönderdiğinizde, derleme uzantısına sahip olur. JavaScript modülleri için .mjs uzantısını kullanırsanız V8, modül tabanlı JavaScript kodu için akış derlemesinin bozuk.

Bu hususlar sizi kod bölme özelliğini kullanmaktan caydırmasına izin vermeyin. Kodlayın bölme, kullanıcılara ilk JavaScript yüklerini azaltmanın etkili bir yoludur. Ancak bir paketleyici kullanarak ve V8'in akışını koruyarak çalışırken, üretim JavaScript kodunuzun bu şekilde olmasını sağlayabilirsiniz. hızlı olmasını sağlıyor.

Dinamik içe aktarma demosu

web paketi

webpack, SplitChunksPlugin adlı bir eklentiyle birlikte gelir. Bu eklenti, Paketleyicinin JavaScript dosyalarını nasıl böleceğini yapılandırın. webpack hem dinamik import() ve statik import ifadeleri. Kullanıcının davranışı SplitChunksPlugin, içindeki chunks seçeneği belirtilerek değiştirilebilir yapılandırma:

  • chunks: async varsayılan değerdir ve dinamik import() çağrılarını ifade eder.
  • chunks: initial, statik import çağrılarına işaret eder.
  • chunks: all, hem dinamik import() hem de statik içe aktarmaları kapsar. Böylece, grupları async ile initial içe aktarmaları arasında paylaşmak için kullanabilirsiniz.

Web paketi dinamik bir import() ifadesiyle karşılaştığında varsayılan olarak kullanılır. o o modül için ayrı bir yığın oluşturur:

/* main.js */

// An application-specific chunk required during the initial page load:
import myFunction from './my-function.js';

myFunction('Hello world!');

// If a specific condition is met, a separate chunk is downloaded on demand,
// rather than being bundled with the initial chunk:
if (condition) {
  // Assumes top-level await is available. More info:
  // https://v8.dev/features/top-level-await
  await import('/form-validation.js');
}

Önceki kod snippet'inin varsayılan web paketi yapılandırması ikiyle sonuçlanır: parçalar:

  • Web paketinin initial yığını olarak sınıflandırdığı main.js yığını main.js ve ./my-function.js modülünü içerir.
  • Yalnızca form-validation.js içeren async yığını dosya karması kullanılır). Bu yığın yalnızca indirildi condition değerinin doğru olup olmadığını kontrol edin.

Bu yapılandırma, form-validation.js yığınının yüklenmesini zaten gereklidir. Bu, komut dosyasını değerlendirme süresini artırır. Komut dosyası indirme ve değerlendirme form-validation.js parçası için bir koşul karşılandığında, Bu durumda, dinamik olarak içe aktarılan modül indirilir. Mesela bir çoklu dolgunun yalnızca belirli bir tarayıcı için indirildiği veya içe aktarılan modül kullanıcı etkileşimi için gereklidir.

Diğer yandan, SplitChunksPlugin yapılandırmasını chunks: initial, kodun yalnızca ilk parçalarda bölünmesini sağlar. Bunlar: statik olarak içe aktarılan veya web paketinin entry içinde listelenenler gibi parçalar özelliği ekleyin. Yukarıdaki örneğe göre, sonuçta ortaya çıkan parça, form-validation.js ve main.js kombinasyonunun tek bir komut dosyası içinde olması, bu da ilk sayfa yükleme performansının düşmesine neden olabilir.

SplitChunksPlugin seçenekleri, daha büyük boyutları ayırmak için de yapılandırılabilir komut dosyalarını daha küçük birden çok komut dosyasına dönüştürebilirsiniz (örneğin, maxSize seçeneğini kullanarak) parçaları ayrı dosyalara bölme talimatını vermek için maxSize tarafından belirtilmiş. Büyük komut dosyalarını küçük dosyalara bölmek Bazı durumlarda CPU'yu yoğun şekilde kullanan komut dosyası değerlendirmesi gibi, yükleme duyarlılığını iyileştirir. işler daha küçük görevlere bölünür (bunlar ana görevlerin daha uzun süreler için iş parçacığı.

Buna ek olarak, daha büyük JavaScript dosyaları oluşturmak, sorun yaşama ihtimali artar. Örneğin, çok büyük bir hem çerçeve hem de birinci taraf uygulama koduna sahip büyük komut dosyası. paket, yalnızca çerçeve güncellendiğinde geçersiz kılınabilir. kaynakta yer alır.

Öte yandan, daha küçük komut dosyası dosyaları, Ziyaretçi, kaynakları önbellekten alarak sayfaların daha hızlı yüklenmesini sağlar. yinelenen ziyaretler. Bununla birlikte, küçük dosyalar, büyük boyutlu dosyalardan daha az sıkıştırma Ardışık alçak reklam öğeleriyle sayfa yüklemelerinde ağ gidiş dönüş süresini dikkat edin. Önbelleğe alma arasında denge kurmaya dikkat edilmelidir verimi, sıkıştırma etkililiğini ve komut dosyası değerlendirme süresini takip eder.

web paketi demosu

web paketi SplitChunksPlugin demosu.

Bilginizi test etme

Kod gerçekleştirilirken hangi import ifadesi türü kullanılır? bölünüyor mu?

Statik import.
Dinamik import().

Hangi tür import ifadenin üst kısımda olması olması gerekir bir JavaScript modülünün parçası olarak mı yoksa başka bir konumda mı?

Dinamik import().
Statik import.

Webpack'te SplitChunksPlugin kullanılırken async yığını ile initial yığın mı?

async parça, dinamik import() kullanılarak yüklendi ve initial parça statik veri kullanılarak yüklenir import.
async parça, statik import kullanılarak yüklendi ve initial parça, dinamik etiket kullanılarak yüklendi import().

Sıradaki: Resimleri ve <iframe> öğeleri geç yükleme

Oldukça pahalı bir kaynak türü olsa da JavaScript aynı zamanda yüklenmesini erteleyebileceğiniz kaynak türünü seçin. Resim ve <iframe> öğeleri potansiyel olarak maliyetli kaynaklardır. JavaScript'e benzer şekilde, görsellerin ve <iframe> öğelerinin yüklenmesini geç yükleme nedeniyle erteleyebilir nasıl kullanacağınızı öğrenin.