Next.js ve Gatsby'deki daha yeni bir web paketi parçalama stratejisi, sayfa yükleme performansını iyileştirmek için yinelenen kodları en aza indirir.
Chrome, Chrome'un sunduğu araçlarla birlikte ve çerçevelerini nasıl belirleyeceğinizi öğrendiniz. Yakın zamanda bir dizi yeni optimizasyon Next.js ve yükleme performansını iyileştirmek için Gatsby Bu makalede, iyileştirilmiş bir ayrıntılı parçalama stratejisi açıklanmaktadır. Bu çerçeve artık her iki çerçevede de varsayılan olarak sunulmaktadır.
Giriş
Birçok web çerçevesi gibi Next.js ve Gatsby da temel olarak webpack'i kullanır.
paketleyicidir. webpack v3 kullanıma sunuldu
CommonsChunkPlugin
ile şunları yapabilirsiniz:
tek bir (veya birkaç) "ortak" değerde farklı giriş noktaları arasında paylaşılan çıkış modülleri parça (veya
parçalar). Paylaşılan kod ayrı olarak indirilebilir ve tarayıcı önbelleğinde erkenden saklanabilir. Böylece,
daha iyi yükleme performansı sağlar.
Bu kalıp, bir giriş noktası benimseyen ve birçok tek sayfalık uygulama çerçevesinin kullanıldığı paket yapılandırmasını şu şekilde görebilirsiniz:
Paylaşılan tüm modül kodlarını tek bir parçada toplamak pratik olsa da,
sınırlamaları vardır. Her giriş noktasında paylaşılmayan modüller, bunları kullanmayan rotalar için indirilebilir
Bu da gerekenden daha fazla kod indirilmesine neden oluyor. Örneğin, page1
yüklendiğinde
common
parçasını kullanmadığınızda, page1
moduleC
kullanmasa bile moduleC
kodunu yükler.
Bu nedenle, webpack v4, birkaç diğer eklentiyle birlikte eklentiyi yeni bir eklentiyle kaldırıyor.
bir: SplitChunksPlugin
.
İyileştirilmiş Chunking
SplitChunksPlugin
için varsayılan ayarlar çoğu kullanıcı için uygundur. Birden çok bölünmüş parça
bir dizi koşula bağlı olarak oluşturulur
birden fazla rotada yinelenen kod alınmasını önlemek için.
Ancak bu eklentiyi kullanan birçok web çerçevesi hâlâ "tek ortak" bir yaklaşım izler. parçaya yaklaşım
bölme. Örneğin Next.js,commons
sayfaların% 50'sinden fazlasında ve tüm çerçeve bağımlılıklarında (react
, react-dom
vb.) kullanılıyor.
const splitChunksConfigs = {
…
prod: {
chunks: 'all',
cacheGroups: {
default: false,
vendors: false,
commons: {
name: 'commons',
chunks: 'all',
minChunks: totalPages > 2 ? totalPages * 0.5 : 2,
},
react: {
name: 'commons',
chunks: 'all',
test: /[\\/]node_modules[\\/](react|react-dom|scheduler|use-subscription)[\\/]/,
},
},
},
Çerçeveye bağlı kodu paylaşılan bir parçaya dahil etmek, ilgili kodun indirilebilir ve herhangi bir giriş noktası için önbelleğe alınmış, sayfaların yarısı çok etkili değildir. Bu oranın değiştirilmesi, yalnızca şu iki sonuçtan biriyle sonuçlanır:
- Bu oranı düşürürseniz daha fazla gereksiz kod indirilir.
- Bu oranı artırırsanız birden fazla rotada daha fazla kod yinelenir.
Bu sorunu çözmek için Next.js, farklı bir yaklaşım
SplitChunksPlugin
için yapılandırmanın
gereksiz koda ihtiyacınız yok.
- Yeterli büyüklükte olan üçüncü taraf modülleri (160 KB'tan büyük), kendi bağımsız modüllerine bölünür parça
- Çerçeve bağımlılıkları (
react
,react-dom
veframeworks
vb.) - Gerektiği kadar paylaşılan parça oluşturulur (en fazla 25)
- Yığının oluşturulması için minimum boyut 20 KB olarak değiştirildi
Bu ayrıntılı parçalama stratejisi şu avantajları sağlar:
- Sayfa yüklenme süreleri iyileştirildi. Tek bir parça yerine birden çok paylaşılan parça göndermek, herhangi bir giriş noktası için gereksiz (veya yinelenen) kod miktarını en aza indirir.
- Gezinme sırasında daha iyi önbellek kullanımı. Büyük kitaplıkları ve çerçeve bağımlılıklarını bölme çok küçük parçalara ayırması önbelleğin geçersiz kılınma olasılığını azaltır. Çünkü bunların her ikisi de değişiklik yapılana kadar değişiklik gösterebilir.
Next.js'nin benimsediği yapılandırmanın tamamını webpack-config.ts
'te görebilirsiniz.
Diğer HTTP istekleri
SplitChunksPlugin
, ayrıntılı parçalamanın temelini tanımlamış ve bu yaklaşımı
çerçevesi tamamen yeni bir kavram değildi. Ancak birçok çerçeve yine de
tek bir bulgusal ve "ortak" kullanın birkaç nedene dayanır. Bu, proje yöneticisinin
HTTP isteği sayısının artması site performansını olumsuz yönde etkileyebilir.
Tarayıcılar tek bir kaynağa (Chrome için 6) yalnızca sınırlı sayıda TCP bağlantısı açabilir. bir paketleyici tarafından üretilen parçaların sayısını en aza indirmek, toplam istek sayısının bu eşiğin altında kalır. Ancak bu yalnızca HTTP/1.1 için geçerlidir. HTTP/2'de Multiplexleme Tek bir bağlantı üzerinden tek bir bağlantı kullanarak birden fazla isteğin paralel olarak akışına olanak tanır. kaynak. Diğer bir deyişle, genellikle parça sayısını sınırlama konusunda endişelenmemize gerek kalmaz yayınlanmıştır.
Başlıca tarayıcıların tümü HTTP/2'yi desteklemektedir. Chrome ve Next.js ekipleri
Next.js'nin tek "ortak" öğelerini bölerek istek sayısını artırıp artırmadığını görmek istedim grup
ayırabilmeniz, yükleme performansını herhangi bir şekilde etkileyecektir. İlk olarak
aynı site bağlantısını kullanarak maksimum paralel istek sayısını değiştirirken
maxInitialRequests
Tek bir web sayfasında yapılan birden fazla denemenin ortalama olarak üç kez çalıştırılmasında,
load
,
start-render
ve First Contentful Paint süreleri, maksimum başlangıç değeri değiştirilirken yaklaşık olarak aynı kaldı.
istek sayısı (5 ila 15). İşin ilginç yanı, bu modelde yalnızca biraz performansın
bölünmesinin ardından %65'lik bir artışa yol açabilir.
Bu veriler, güvenilir bir eşiğin (20~25 istek) altında kalmanın doğru dengeyi yakaladığını gösterdi.
performansı ve önbellek verimliliği arasında
bir denge kurmak için idealdir. Bazı temel testlerden sonra 25 katılımcı
maxInitialRequest
sayısı.
Paralel olarak gerçekleşen maksimum istek sayısının değiştirilmesi, birden fazla istekle sonuçlandı ve bunları her giriş noktası için uygun şekilde ayırmak, paylaşılan pakete gerekli olmayan kod miktarını belirleyin.
Bu deneme yalnızca, istek sayısında değişiklik yapılıp yapılmayacağını görmekle ilgiliydi.
sayfa yükleme performansını olumsuz etkiler. Sonuçlar, maxInitialRequests
politikasının
Test sayfasındaki 25
, JavaScript yük boyutunu yavaşlatmadan küçülttüğü için optimumdu
bir şeyler üretebilirsiniz. Sayfayı sadeleştirmek için gereken toplam JavaScript miktarı hâlâ mevcut
hemen hemen aynıdır; bu da sayfa yükleme performansının, yüklemelerdeki düşüşle birlikte
gerekir.
webpack, bir parçanın oluşturulması için varsayılan minimum boyut olarak 30 KB kullanır. Ancak, bir
Minimum 20 KB boyuta sahip 25 maxInitialRequests
değeri, bunun yerine daha iyi önbelleğe almayla sonuçlandı.
Ayrıntılı parçalarla boyut küçültme
Next.js dahil olmak üzere birçok çerçeve, komut dosyası etiketleri oluşturmanız gerekir. Peki bu dinamik parçaları derleme sırasında nasıl önceden belirleyebilirler?
Next.js, hangi çıktı parçalarının kullanıldığını belirlemek için sunucu tarafı bir derleme manifesti dosyası kullanır: giriş noktalarından yararlanabilirsiniz. Bu bilgiyi müşteriye de sağlamak için kısaltılmış istemci tarafı her giriş noktasında tüm bağımlıların eşlenmesi için derleme manifest dosyası oluşturuldu.
// Returns a promise for the dependencies for a particular route
getDependencies (route) {
return this.promisedBuildManifest.then(
man => (man[route] && man[route].map(url => `/_next/${url}`)) || []
)
}
![Bir Next.js uygulamasında birden fazla paylaşılan parçanın çıkışı.](https://web.dev/static/articles/granular-chunking-nextjs/image/output-multiple-shared-c-772d7dc79d8af.png?authuser=5&hl=tr)
Bu yeni ayrıntılı parçalama stratejisi, ilk olarak Next.js'de bir işaretin arkasında kullanıma sunuldu. Bu strateji, ilk olarak ilk kullanıcılardan oluşur. Pek çok kişi, Arkadaş Bitkiler projesinde kullanılan toplam JavaScript tüm site:
Web sitesi | Toplam JS Değişikliği | % Farkı |
---|---|---|
https://www.barnebys.com/ | -238 KB | -%23 |
https://sumup.com/ | -220 KB | -%30 |
https://www.hashicorp.com/ | -11 MB | -%71 |
Nihai sürüm 9.2 sürümünde varsayılan olarak kullanıma sunulmuştur.
Gatsby
Gatsby eskiden, kullanıma dayalı bir dönüşüm yönetimi yaklaşımı genel modülleri tanımlamak için sezgisel:
config.optimization = {
…
splitChunks: {
name: false,
chunks: `all`,
cacheGroups: {
default: false,
vendors: false,
commons: {
name: `commons`,
chunks: `all`,
// if a chunk is used more than half the components count,
// we can assume it's pretty global
minChunks: componentsCount > 2 ? componentsCount * 0.5 : 2,
},
react: {
name: `commons`,
chunks: `all`,
test: /[\\/]node_modules[\\/](react|react-dom|scheduler)[\\/]/,
},
Ayrıca, web paketi yapılandırmasını benzer bir ayrıntılı parçalama stratejisi benimseyecek şekilde optimize ederek JavaScript'in pek çok büyük sitede büyük oranda azaldığını fark ettik:
Web sitesi | Toplam JS Değişikliği | % Farkı |
---|---|---|
https://www.gatsbyjs.org/ | -680 KB | -%22 |
https://www.thirdandgrove.com/ | -390 KB | -%25 |
https://ghost.org/ | -1,1 MB | -%35 |
https://reactjs.org/ | -80 KB | -%8 |
Bu politikaların nasıl uygulandığını anlamak için PR'ye 2.20.7 sürümünde varsayılan olarak gönderilen web paketi yapılandırmasına bu mantığı uyguladı.
Sonuç
Ayrıntılı parçaları gönderme kavramı Next.js, Gatsby'ye, hatta webpack'e özgü değildir. Herkes geniş bir "ortak paydada" buluşması durumunda, uygulamanın parçalama stratejisini iyileştirmeyi düşünmelidirler. paket yaklaşımını kullanmanız gerekir.
- Aynı parçalama optimizasyonlarının vanilla React uygulamasına uygulanmasını görmek isterseniz bu örnek React'e göz atın uygulamasında gösterilir. Bir ayrıntılı parçalama stratejisinin basitleştirilmiş sürümüdür ve aynısını uygulamaya başlamanıza bir anlam ifade eder.
- Birleştirme için parçalar varsayılan olarak ayrıntılı bir şekilde oluşturulur. Şu bilgileri inceleyin:
Manuel olarak etkinleştirmek için
manualChunks
ve davranışı yapılandırın.