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
Optimizasyonlar eklemeden önce, uygulamanın mevcut durumunu analiz etmek her zaman iyi bir fikirdir.
- Siteyi önizlemek için Uygulamayı Görüntüle'ye basın. Ardından, Tam ekran
düğmesine basın.
"Kullanılmayan kodu kaldırın" codelab'inde de ele alınan bu uygulama, en sevdiğiniz kedi yavrusu için 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 "Control+Üst Karakter+J" (veya Mac'te "Command+Option+J") tuşlarına basın.
- Ağ sekmesini tıklayın.
- Önbelleği devre dışı bırak onay kutusunu seçin.
- Uygulamayı yeniden yükleyin.
Bu paket boyutunu küçültmek için "Kullanılmayan kodu kaldırın" codelab'inde epey ilerleme kaydedilse de 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 elde edilen kod aşağıdaki gibi görünür:
function soNice(){let counter=0;while(counter<100){console.log("nice");counter++;}}
Şimdi dosya boyutu 83 B civarında olur. Değişken adının uzunluğunun azaltılması ve bazı ifadelerin değiştirilmesiyle daha fazla karışması durumunda, nihai kod aşağıdaki gibi görünebilir:
function soNice(){for(let i=0;i<100;)console.log("nice"),i++}
Dosya boyutu artık 62 B'ye ulaşıyor.
Her adımla birlikte kodun okunması 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 pek fazla bir şey değildi ancak yine de boyutta %50'lik bir küçülme söz konusuydu.
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",
//...
}
Sürüm 4, üretim modunda paketi varsayılan olarak küçültmektedir. 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.
Küçültülmüş kodun nasıl göründüğü hakkında fikir edinmek için Geliştirici Araçları Ağ panelindeyken main.bundle.js
simgesini tıklayın. Şimdi Yanıt sekmesini tıklayın.
Son hali olan kod küçültülmüş ve karıştırılmış, 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 aldığınızdan emin olun.
module.exports = {
mode: 'production',
mode: 'none',
//...
Uygulamanızda kodu küçültme işlemi eklemek, kullandığınız araçlara bağlıdır:
- Web paketi v4 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. Belgelerde bu durum ayrıntılı olarak açıklanmaktadır. - BabelMinifyWebpackPlugin ve ClosureCompilerPlugin gibi başka küçültme eklentileri de mevcuttur ve kullanılabilir.
- Bir modül paketleyici hiç kullanılmıyorsa Terser'ı CLI aracı olarak kullanın veya doğrudan bir bağımlılık olarak ekleyin.
Sıkıştırma
"Sıkıştırma" terimi bazen kodun küçültme işlemi sırasında nasıl azaltıldığını açıklamak için kullanılsa da aslında gerçek anlamda sıkıştırılmaz.
Sıkıştırma genellikle bir veri sıkıştırma algoritması kullanılarak değiştirilen kod anlamına gelir. Son derece geçerli kod sağlayan küçültmenin aksine, sıkıştırılmış kodun kullanılmadan önce sıkıştırması 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 headers ekleyebilir. Bu, Geliştirici Araçları Ağı panelindeki Headers
sekmesinde görülebilir. Burada üç tür gösterilir:
- 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 Başlıkları, istemci tarafından isteğe eklenen başlıkların listesini gösterir.
Request Headers
içindeki accept-encoding
başlığına göz atın.
accept-encoding
, tarayıcı tarafından hangi içerik kodlama biçimlerini veya sıkıştırma algoritmalarını desteklediğini belirtmek için kullanılır. Kullanabileceğiniz çok sayıda metin sıkıştırma algoritması vardır ancak HTTP ağ isteklerinin sıkıştırılması (ve sıkıştırılması) için burada desteklenen yalnızca üç algoritma bulunmaktadır:
- Gzip (
gzip
): Sunucu ve istemci etkileşimleri için en yaygın olarak kullanılan sıkıştırma biçimi. Söndürme algoritmasını temel alır ve mevcut tüm tarayıcılarda desteklenir. - Söndür (
deflate
): Yaygın olarak kullanılmaz. - Brotli (
br
): Sıkıştırma oranlarını daha da iyileştirerek sayfaların daha da hızlı yüklenmesini sağlayabilecek yeni bir sıkıştırma algoritmasıdır. Ç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 incelenecektir.
Dinamik sıkıştırma
Dinamik sıkıştırma, tarayıcı tarafından istenen öğelerin anında sıkıştırılmasını içerir.
Artıları
- Öğelerin kaydedilmiş sıkıştırılmış sürümlerini oluşturma ve güncelleme işleminin tamamlanması 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 daha yüksek düzeylerde dosyaların sıkıştırılması 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.
Düğüm/Ekspres ile dinamik sıkıştırma
server.js
dosyası, uygulamayı barındıran Düğüm sunucusunu ayarlamaktan 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).
Her istendiğinde tüm öğelerin sıkıştırıldığından emin olmak için sıkıştırma ara katman yazılımı kitaplığı kullanılabilir. package.json
hesabına 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');
express.static
eklenmeden önce bunu bir ara katman 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'tan 61,6 KB'ye! Response Headers
öğesinde artık content-encoding
başlığı, sunucunun gzip
ile kodlanmış bu dosyayı gönderdiğini gösterir.
Statik sıkıştırma
Statik sıkıştırmanın arkasındaki fikir, öğelerin sıkıştırılması ve zamandan tasarruf edilmesidir.
Artıları
- Yüksek sıkıştırma seviyeleri nedeniyle yaşanan gecikme artık sorun değil. O anda doğrudan getirilebildiğinden dosyaları sıkıştırmak için herhangi bir işlem yapılması gerekmez.
Eksileri
- Her derlemede öğelerin sıkıştırılması gerekir. Yüksek sıkıştırma seviyeleri kullanılırsa derleme süreleri önemli ölçüde uzayabilir.
Düğüm/Ekspres ve webpack ile statik sıkıştırma
Statik sıkıştırma, dosyaların önceden sıkıştırılmasını gerektirdiğinden web paketi ayarları, derleme adımı kapsamında öğeleri sıkıştıracak şekilde değiştirilebilir.
Bunun için CompressionPlugin
kullanılabilir.
package.json
hesabına devDependency
olarak ekleyerek başlayın:
"devDependencies": {
//...
"compression-webpack-plugin": "^1.1.11"
},
Diğer web paketi eklentilerinde olduğu gibi onu da yapılandırma 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()
]
}
Varsayılan olarak eklenti, 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, artık ana paketin sıkıştırılmış bir sürümü oluşturulur. Düğüm sunucusu tarafından sunulan son public/
dizininin içinde neler olduğuna bakmak için Glitch Console'u açın.
- Araçlar düğmesini tıklayın.
- Konsol düğmesini tıklayın.
public
dizinini değiştirmek ve tüm dosyalarını görmek için konsolda aşağıdaki komutları çalıştırın:
cd public
ls
Paketin gzip ile sıkıştırılmış sürümü (main.bundle.js.gz
) artık buraya da kaydedilir. CompressionPlugin
, varsayılan olarak index.html
öğesini de sıkıştırır.
Yapılması gereken bir sonraki şey, sunucuya orijinal JS sürümleri her istendiğinde bu gzip uygulanmış dosyaları göndermesini söylemektir. Bu işlem, dosyalar express.static
ile sunulmadan önce server.js
ürününde yeni bir rota tanımlanarak yapılabilir.
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ç nokta için GET isteğine nasıl yanıt vereceğini bildirmek amacıyla kullanılır. Daha sonra, 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'
belirtilmesi, JS dosyasını getirmek üzere tetiklenen her uç nokta için bu işlevin çalışacağı anlamına gelir. - Geri çağırmada isteğin URL'sine
.gz
eklenir veContent-Encoding
yanıt başlığıgzip
olarak ayarlanır. - Son olarak
next()
, adım sırasının bir sonraki geri çağırmaya devam etmesini sağlar.
Uygulama yeniden yüklendikten sonra Network
paneline tekrar bakın.
Daha önce olduğu gibi paket boyutu önemli ölçüde küçülecek.
Sonuç
Bu codelab'de, kaynak kodu küçültme ve sıkıştırma süreci ele alınmıştır. Her iki teknik de bugün mevcut araçların çoğunda varsayılan hale gelmektedir. Bu nedenle, araç zincirinizin bunları zaten destekleyip desteklemediğini veya her iki işlemi de kendiniz uygulamaya başlamanız gerekip gerekmediğini tespit etmeniz önemlidir.