Bu codelab'de, aşağıdaki uygulama için JavaScript paketini hem küçültmenin hem de sıkıştırmanın, uygulamanın istek boyutunu küçülterek sayfa performansını nasıl iyileştirdiği incelenmektedir.
Ölçüm
Optimizasyon eklemeye başlamadan önce, uygulamanın mevcut durumunu analiz etmek her zaman iyi bir fikirdir.
- Siteyi önizlemek için Uygulamayı Görüntüle'ye, ardından Tam Ekran'a basın.
"Kullanılmayan kodu kaldırma" codelab'inde de ele alınan bu uygulama, en sevdiğiniz kediye oy vermenize olanak tanır. 🐈
Şimdi bu uygulamanın ne kadar büyük olduğuna bakalım:
- Geliştirici Araçları'nı açmak için "Kontrol+Üst Karakter+J" (veya Mac'te "Komut+Option+J") tuşlarına basın.
- Ağ sekmesini tıklayın.
- Önbelleği devre dışı bırak onay kutusunu işaretleyin.
- Uygulamayı yeniden yükleyin.
"Kullanılmayan kodu kaldırın" kod laboratuvarında bu paket boyutunu küçültmek için çok ilerleme kaydedilmiş olsa da 225 KB hâlâ oldukça büyük.
Küçültme
Aşağıdaki kod bloğunu ele alalım.
function soNice() {
let counter = 0;
while (counter < 100) {
console.log('nice');
counter++;
}
}
Bu işlev kendi dosyasına kaydedilirse dosya boyutu yaklaşık 112 B (bayt) olur.
Tüm boşluklar kaldırılırsa ortaya çıkan kod şu şekilde görünür:
function soNice(){let counter=0;while(counter<100){console.log("nice");counter++;}}
Dosya boyutu yaklaşık 83 B olur. Değişken adının uzunluğu azaltılarak ve bazı ifadeler değiştirilerek daha da bozulursa nihai kod şu şekilde görünebilir:
function soNice(){for(let i=0;i<100;)console.log("nice"),i++}
Dosya boyutu artık 62 B'a ulaştı.
Her adımda kodun okunması daha da zorlaşıyor. Ancak, tarayıcının JavaScript motoru bunların her birini tam olarak aynı şekilde yorumlar. Kodda bu şekilde kod karartmanın faydası, daha küçük dosya boyutlarına ulaşmanıza yardımcı olabilir. 112 B başlangıçta çok büyük bir boyut değildi ancak yine de boyutta %50 oranında bir azalma elde edildi.
Bu uygulamada, webpack 4 sürümü modül paketleyici olarak kullanılmaktadır. İlgili sürümü package.json
sayfasında görebilirsiniz.
"devDependencies": {
//...
"webpack": "^4.16.4",
//...
}
4. sürüm, üretim modunda varsayılan olarak paketi küçültür. Terser için bir TerserWebpackPlugin
eklentisi kullanır.
Terser, JavaScript kodunu sıkıştırmak için kullanılan popüler bir araçtır.
Kodun sıkıştırılmış hâlinin nasıl göründüğüne dair fikir edinmek için DevTools Ağ panelindeyken main.bundle.js
simgesini tıklayın. Ardından Yanıt sekmesini tıklayın.
Kod, son biçiminde, sıkıştırılmış ve bozulmuş olarak yanıt gövdesinde gösterilir.
Paketin küçültülmediyse ne kadar büyük olabileceğini öğrenmek için webpack.config.js
uygulamasını açın ve mode
yapılandırmasını güncelleyin.
module.exports = {
mode: 'production',
mode: 'none',
//...
Uygulamayı yeniden yükleyin ve Geliştirici Araçları Ağ panelinden paket boyutuna tekrar göz atın
Bu oldukça büyük bir fark. 😅
Devam etmeden önce buradaki değişiklikleri geri almanız gerekir.
module.exports = {
mode: 'production',
mode: 'none',
//...
Uygulamanıza kod sıkıştırma işlemi eklemek, kullandığınız araçlara bağlıdır:
- Webpack 4 veya sonraki bir sürüm kullanılıyorsa kod üretim modunda varsayılan olarak küçültüldüğünden ek işlem yapılması gerekmez. 👍
- Web paketinin daha eski bir sürümü kullanılıyorsa
TerserWebpackPlugin
uygulamasını yükleyin ve web paketi derleme işlemine ekleyin. Bu konu dokümanlar bölümünde ayrıntılı olarak açıklanmıştır. - BabelMinifyWebpackPlugin ve ClosureCompilerPlugin gibi diğer küçültme eklentileri de kullanılabilir.
- Hiçbir modül paketleyici kullanılmıyorsa CLI aracı olarak Terser'i kullanın veya doğrudan bağımlılık olarak ekleyin.
Sıkıştırma
"Sıkıştırma" terimi, bazen kod azaltma işlemi sırasında kodun nasıl azaltıldığını açıklamak için gevşek bir şekilde kullanılsa da kod, gerçek anlamda sıkıştırılmaz.
Sıkıştırma, genellikle veri sıkıştırma algoritması kullanılarak değiştirilmiş kodu ifade eder. Mükemmel şekilde geçerli kod sağlayan sıkıştırmanın aksine, sıkıştırılmış kodun kullanılmadan önce sıkıştırmasının çözülmesi gerekir.
Tarayıcılar ve web sunucuları, her HTTP isteği ve yanıtıyla birlikte, getirilen veya alınan öğe hakkında ek bilgiler içeren üstbilgiler ekleyebilir. Bu durum, üç türün gösterildiği DevTools Ağ panelindeki Headers
sekmesinde görülebilir:
- Genel, istek-yanıt etkileşiminin tamamıyla alakalı genel başlıkları temsil eder.
- Yanıt Başlıkları, sunucudan gelen gerçek yanıta özel üstbilgilerin listesini gösterir.
- İstek Üst Bilgileri, istemci tarafından isteğe eklenen üst bilgilerin listesini gösterir.
Request Headers
'daki accept-encoding
başlığına göz atın.
accept-encoding
, tarayıcı tarafından desteklediği içerik kodlama biçimlerini veya sıkıştırma algoritmalarını belirtmek için kullanılır. Birçok metin sıkıştırma algoritması vardır ancak HTTP ağ isteklerinin sıkıştırılması (ve sıkıştırmanın açılması) için burada yalnızca üçü desteklenir:
- Gzip (
gzip
): Sunucu ve istemci etkileşimleri için en yaygın olarak kullanılan sıkıştırma biçimidir. Deflate algoritmasını temel alır ve mevcut tüm tarayıcılarda desteklenir. - Sıkıştır (
deflate
): Genellikle kullanılmaz. - Brotli (
br
): Sıkıştırma oranlarını daha da iyileştirmeyi amaçlayan daha yeni bir sıkıştırma algoritması. Bu algoritma, sayfaların daha da hızlı yüklenmesine neden olabilir. Çoğu tarayıcının en son sürümlerinde desteklenir.
Bu eğitimdeki örnek uygulama, Express'in artık bir sunucu çerçevesi olarak kullanılması dışında "Kullanılmayan kodu kaldır" codelab'inde tamamlanan uygulamayla aynıdır. Sonraki birkaç bölümde hem statik hem de dinamik sıkıştırma incelenmektedir.
Dinamik sıkıştırma
Dinamik sıkıştırma, öğelerin tarayıcı tarafından istendiği anda sıkıştırılmasını içerir.
Artıları
- Öğelerin sıkıştırılmış ve kaydedilmiş sürümlerini oluşturmak ve güncellemek gerekmez.
- Anında sıkıştırma özellikle dinamik olarak oluşturulan web sayfaları için iyi sonuç verir.
Eksileri
- Daha iyi sıkıştırma oranları elde etmek için dosyaları daha yüksek düzeylerde sıkıştırmak daha uzun sürer. Kullanıcı, sunucu tarafından gönderilmeden önce öğelerin sıkıştırılmasını beklediği için bu durum bir performans isabetine neden olabilir.
Node/Express ile dinamik sıkıştırma
server.js
dosyası, uygulamayı barındıran Node sunucusunu oluşturmaktan sorumludur.
const express = require('express');
const app = express();
app.use(express.static('public'));
const listener = app.listen(process.env.PORT, function() {
console.log('Your app is listening on port ' + listener.address().port);
});
Şu anda tüm bu işlemler, public/
dizinindeki tüm statik HTML, JS ve CSS dosyalarını yüklemek için express
içe aktarmak ve express.static
ara yazılımı kullanmaktır (bu dosyalar her derlemede web paketi tarafından oluşturulur).
Tüm öğelerin istendiğinde sıkıştırıldığından emin olmak için sıkıştırma orta katman kitaplığı kullanılabilir. package.json
'a devDependency
olarak ekleyerek başlayın:
"devDependencies": {
//...
"compression": "^1.7.3"
},
Ardından, dosyayı server.js
sunucu dosyasına aktarın:
const express = require('express');
const compression = require('compression');
Ardından, express.static
monte edilmeden önce ara yazılım olarak ekleyin:
//...
const app = express();
app.use(compression());
app.use(express.static('public'));
//...
Şimdi uygulamayı yeniden yükleyin ve Ağ panelindeki paket boyutuna bakın.
225 KB'dan 61,6 KB'ya düştü. Response Headers
şimdi, content-encoding
başlığı, sunucunun bu dosyayı gzip
ile kodlanmış olarak gönderdiğini gösterir.
Statik sıkıştırma
Statik sıkıştırmanın amacı, öğelerin önceden sıkıştırılıp kaydedilmesidir.
Artıları
- Yüksek sıkıştırma seviyelerinden kaynaklanan gecikme artık sorun olmaktan çıktı. Artık dosyalar doğrudan getirilebildiğinden, sıkıştırmak için anında bir işlem yapılması gerekmez.
Eksileri
- Öğelerin her derlemeyle sıkıştırılması gerekir. Yüksek sıkıştırma seviyeleri kullanılırsa derleme süreleri önemli ölçüde uzayabilir.
Node/Express ve webpack ile statik sıkıştırma
Statik sıkıştırma, dosyaları önceden sıkıştırmayı içerdiğinden webpack ayarları, derleme adımı kapsamında öğeleri sıkıştıracak şekilde değiştirilebilir.
CompressionPlugin
bu amaçla kullanılabilir.
package.json
'a devDependency
olarak ekleyerek başlayın:
"devDependencies": {
//...
"compression-webpack-plugin": "^1.1.11"
},
Diğer tüm webpack eklentileri gibi, bu eklentiyi de yapılandırmalar dosyasına aktarın.
webpack.config.js:
const path = require("path");
//...
const CompressionPlugin = require("compression-webpack-plugin");
Ve bunu plugins
dizisine ekleyin:
module.exports = {
//...
plugins: [
//...
new CompressionPlugin()
]
}
Eklenti, varsayılan olarak derleme dosyalarını gzip
kullanarak sıkıştırır. Farklı bir algoritma kullanma veya belirli dosyaları dahil etme/hariç tutma seçeneklerini nasıl ekleyeceğinizi öğrenmek için belgelere göz atın.
Uygulama yeniden yüklendiğinde ve yeniden oluşturulduğunda ana paketin sıkıştırılmış bir sürümü oluşturulur. Node sunucusu tarafından sunulan nihai public/
dizininin içeriğine göz atmak için Glitch Console'u açın.
- Araçlar düğmesini tıklayın.
- Konsol düğmesini tıklayın.
- Konsolda
public
dizinine gidip tüm dosyalarını görmek için aşağıdaki komutları çalıştırın:
cd public
ls
Paketin sıkıştırılmış sürümü (main.bundle.js.gz
) de buraya kaydedilir. CompressionPlugin
, varsayılan olarak index.html
öğesini de sıkıştırır.
Ardından, sunucuya orijinal JS sürümleri istendiğinde bu sıkıştırılmış dosyaları göndermesini söylemeniz gerekir. Bunu, dosyalar express.static
ile sunulmadan önce server.js
içinde yeni bir rota tanımlayarak yapabilirsiniz.
const express = require('express'); const app = express(); app.get('*.js', (req, res, next) => { req.url = req.url + '.gz'; res.set('Content-Encoding', 'gzip'); next(); }); app.use(express.static('public')); //...
app.get
, sunucuya belirli bir uç noktayla ilgili GET isteğine nasıl yanıt vereceğini bildirmek için kullanılır. Ardından, bu isteğin nasıl işleneceğini tanımlamak için bir geri çağırma işlevi kullanılır. Rota şu şekilde çalışır:
- İlk bağımsız değişken olarak
'*.js'
belirtildiğinde bu, bir JS dosyası almak için tetiklenen her uç nokta için geçerli olur. - Geri çağırma içinde
.gz
, isteğin URL'sine eklenir veContent-Encoding
yanıt başlığıgzip
olarak ayarlanır. - Son olarak
next()
, sıranın bir sonraki geri çağırma işlevine devam etmesini sağlar.
Uygulama yeniden yüklendikten sonra Network
paneline tekrar göz atın.
Daha önce olduğu gibi paket boyutu önemli ölçüde küçülecek.
Sonuç
Bu kod laboratuvarında, kaynak kodunu küçültme ve sıkıştırma süreci ele alındı. Bu tekniklerin her ikisi de günümüzde kullanılan araçların çoğunda varsayılan olarak kullanılır. Bu nedenle, araç zincirinizin bunları zaten destekleyip desteklemediğini, yoksa her iki işlemi de kendiniz uygulamaya başlamanız gerekip gerekmediğini tespit etmeniz önemlidir.