gzip ile ağ yüklerini küçültün ve sıkıştırın

Houssein Djirdeh
Houssein Djirdeh

Bu codelab'de, aşağıdaki uygulama için JavaScript paketinin hem küçültülmesinin hem de sıkıştırılmasının, uygulamanın istek boyutunu küçülterek sayfa performansını nasıl artırdığı ele alınmaktadır.

Uygulama ekran görüntüsü

Ö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 basın. Ardından Tam Ekran'a basın. tam ekran

"Kullanılmayan kodu kaldırma" adlı codelab'de de ele alınan bu uygulama, en sevdiğiniz yavru kediye oy vermenizi sağlar. 🐈

Şimdi bu uygulamanın ne kadar büyük olduğuna bakın:

  1. Geliştirici Araçları'nı açmak için `Control+Shift+J` (veya Mac'te `Command+Option+J`) tuşlarına basın.
  2. sekmesini tıklayın.
  3. Önbelleği devre dışı bırak onay kutusunu işaretleyin.
  4. Uygulamayı yeniden yükleyin.

Ağ panelindeki orijinal paket boyutu

Bu paket boyutunu küçültmek için "Kullanılmayan kodu kaldırma" codelab'inde önemli ölçüde ilerleme kaydedilmiş olsa da 225 KB hâlâ oldukça büyük bir boyut.

Sadeleştirme

Aşağıdaki kod bloğunu inceleyin.

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ılıp bazı ifadeler değiştirilerek daha da bozulursa 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'a ulaşıyor.

Her adımda kodun okunması zorlaşıyor. Ancak tarayıcının JavaScript motoru, bunların her birini aynı şekilde yorumlar. Bu şekilde kodu karartmanın avantajı, daha küçük dosya boyutları elde etmeye yardımcı olabilir. 112 B zaten çok büyük bir boyut değildi ancak yine de %50 oranında küçülme oldu.

Bu uygulamada, modül paketleyici olarak webpack sürüm 4 kullanılır. Belirli sürümü package.json adresinde görebilirsiniz.

"devDependencies": {
  //...
  "webpack": "^4.16.4",
  //...
}

4. sürüm, üretim modunda paketi varsayılan olarak zaten küçültür. TerserWebpackPlugin Terser için bir eklenti kullanıyorsanız 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üğüne dair fikir edinmek için Geliştirme Araçları panelindeyken main.bundle.js simgesini tıklayın. Şimdi Yanıt sekmesini tıklayın.

Küçültülmüş yanıt

Son biçimindeki, küçültülmüş ve bozulmuş kod, yanıt gövdesinde gösterilir. Paketin küçültülmemiş olması durumunda ne kadar büyük olabileceğini öğrenmek için webpack.config.js dosyası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ı paneli üzerinden paket boyutuna tekrar göz atın.

767 KB&#39;lık paket boyutu

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şlemini dahil etme, kullandığınız araçlara bağlıdır:

  • webpack v4 veya daha yeni bir sürüm kullanılıyorsa üretim modunda kod varsayılan olarak küçültüldüğünden ek bir işlem yapılması gerekmez. 👍
  • webpack'in eski bir sürümü kullanılıyorsa TerserWebpackPlugin öğesini yükleyip webpack derleme işlemine dahil edin. Bu konu, dokümanlarda ayrıntılı olarak açıklanmaktadır.
  • BabelMinifyWebpackPlugin ve ClosureCompilerPlugin gibi başka küçültme eklentileri de vardır ve bunlar da kullanılabilir.
  • Hiçbir modül paketleyici kullanılmıyorsa Terser'i bir CLI aracı olarak kullanın veya doğrudan bağımlılık olarak ekleyin.

Sıkıştırma

"Sıkıştırma" terimi bazen küçültme işlemi sırasında kodun nasıl azaltıldığını açıklamak için gevşek bir şekilde kullanılsa da aslında kelimenin tam anlamıyla sıkıştırılmaz.

Sıkıştırma genellikle bir veri sıkıştırma algoritması kullanılarak değiştirilmiş kodu ifade eder. Mükemmel şekilde geçerli kod sağlayan küçültme işleminin aksine, sıkıştırılmış kodun kullanılmadan önce açılması gerekir.

Tarayıcılar ve web sunucuları, her HTTP isteği ve yanıtında üst bilgiler ekleyerek getirilen veya alınan öğe hakkında ek bilgiler sağlayabilir. Bu durum, Geliştirici Araçları Ağ panelindeki Headers sekmesinde görülebilir. Burada üç tür gösterilir:

  • Genel, tüm istek-yanıt etkileşimiyle alakalı genel üstbilgileri ifade eder.
  • Yanıt Başlıkları, sunucudan gelen gerçek yanıta özel başlıkların listesini gösterir.
  • İstek Başlıkları, istemci tarafından isteğe eklenen başlıkların listesini gösterir.

Request Headers bölümündeki accept-encoding başlığına göz atın.

Accept-Encoding üstbilgisi

accept-encoding, tarayıcı tarafından hangi içerik kodlama biçimlerinin veya sıkıştırma algoritmalarının desteklendiğini belirtmek için kullanılır. Piyasada 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 üç algoritma desteklenir:

  • Gzip (gzip): Sunucu ve istemci etkileşimlerinde en yaygın kullanılan sıkıştırma biçimidir. Deflate algoritması üzerine kurulmuştur ve mevcut tüm tarayıcılarda desteklenir.
  • Sıkıştırma (deflate): Yaygın olarak kullanılmaz.
  • Brotli (br): Sıkıştırma oranlarını daha da iyileştirmeyi amaçlayan yeni bir sıkıştırma algoritmasıdır. Bu algoritma, sayfa yüklemelerinin daha da hızlı olmasını sağlayabilir. Çoğu tarayıcının en yeni sürümlerinde desteklenir.

Bu eğitimdeki örnek uygulama, Express artık sunucu çerçevesi olarak kullanılması dışında, "Kullanılmayan kodu kaldırma" codelab'inde tamamlanan uygulamayla aynıdır. Sonraki birkaç bölümde hem statik hem de dinamik sıkıştırma ele alınmaktadır.

Dinamik sıkıştırma

Dinamik sıkıştırma, öğeler tarayıcı tarafından istendikçe 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şlemi yapılmaz.
  • Anında sıkıştırma, özellikle dinamik olarak oluşturulan web sayfalarında 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. Bu durum, kullanıcı sunucu tarafından gönderilmeden önce öğelerin sıkıştırılmasını beklediği için performansın düşmesine neden olabilir.

Node/Express ile dinamik sıkıştırma

server.js dosyası, uygulamayı barındıran Node 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 bu işlem yalnızca express öğesini içe aktarıp express.static ara yazılımını kullanarak public/ dizinindeki tüm statik HTML, JS ve CSS dosyalarını yükler (bu dosyalar her derlemede webpack tarafından oluşturulur).

Tüm öğelerin her istendiğinde sıkıştırıldığından emin olmak için sıkıştırma ara yazılım kitaplığı kullanılabilir. Öncelikle package.json listesine devDependency olarak ekleyin:

"devDependencies": {
  //...
  "compression": "^1.7.3"
},

Ardından, server.js sunucu dosyasına aktarın:

const express = require('express');
const compression = require('compression');

Ayrıca, express.static monte edilmeden önce ara katman yazılımı olarak ekleyin:

//...

const app = express();

app.use(compression());

app.use(express.static('public'));

//...

Şimdi uygulamayı yeniden yükleyin ve Network panelindeki paket boyutuna göz atın.

Dinamik sıkıştırmalı paket boyutu

225 KB'tan 61,6 KB'a! Response Headers bölümünde, content-encoding başlığı, sunucunun bu dosyayı gzip ile kodlanmış olarak gönderdiğini gösteriyor.

İçerik kodlama üstbilgisi

Statik sıkıştırma

Statik sıkıştırmanın temelinde, öğelerin önceden sıkıştırılıp kaydedilmesi fikri yatar.

Artıları

  • Yüksek sıkıştırma seviyelerinden kaynaklanan gecikme artık sorun değil. Artık dosyalar doğrudan getirilebildiğinden, sıkıştırmak için anında işlem yapılması gerekmez.

Eksileri

  • Öğelerin her derlemede sıkıştırılması gerekir. Yüksek sıkıştırma seviyeleri kullanıldığında derleme süreleri önemli ölçüde artabilir.

Node/Express ve webpack ile statik sıkıştırma

Statik sıkıştırma, dosyaların önceden sıkıştırılmasını içerdiğinden webpack ayarları, derleme adımının bir parçası olarak öğeleri sıkıştıracak şekilde değiştirilebilir. CompressionPlugin bu amaçla kullanılabilir.

Öncelikle package.json listesine devDependency olarak ekleyin:

"devDependencies": {
  //...
  "compression-webpack-plugin": "^1.1.11"
},

Diğer tüm webpack eklentileri gibi, yapılandırma dosyasına aktarın, webpack.config.js:

const path = require("path");

//...

const CompressionPlugin = require("compression-webpack-plugin");

Aşağıdaki 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 kullanmak veya belirli dosyaları dahil etmek/hariç tutmak için seçenekleri nasıl ekleyeceğinizi öğrenmek üzere 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 son 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 geçmek ve tüm dosyalarını görmek için aşağıdaki komutları çalıştırın:
cd public
ls

Herkese açık dizindeki son çıktı dosyaları

Paketin gzip ile sıkıştırılmış sürümü, main.bundle.js.gz, artık buraya da kaydediliyor. CompressionPlugin, varsayılan olarak index.html öğesini de sıkıştırır.

Yapılması gereken bir sonraki işlem, sunucuya orijinal JS sürümleri istendiğinde bu gzip'li dosyaları göndermesini söylemektir. Bu işlem, dosyalar server.js ile sunulmadan önce server.js içinde yeni bir rota tanımlanarak yapılabilir.express.static

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 söylemek 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' belirtmek, bir JS dosyası getirmek için tetiklenen her uç nokta için geçerli olduğu anlamına gelir.
  • Geri çağırmada, .gz isteğin URL'sine eklenir ve Content-Encoding yanıt başlığı gzip olarak ayarlanır.
  • Son olarak, next(), sıranın bir sonraki geri çağırmayla devam etmesini sağlar.

Uygulama yeniden yüklendikten sonra Network paneline tekrar göz atın.

Statik sıkıştırmayla paket boyutunu küçültme

Tıpkı daha önce olduğu gibi, paket boyutunda önemli bir azalma elde ettik.

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 mevcut olan birçok araçta varsayılan olarak kullanılmaya başlandı. Bu nedenle, araç zincirinizin bu teknikleri destekleyip desteklemediğini veya her iki süreci de kendiniz uygulamaya başlayıp başlamayacağınızı öğrenmeniz önemlidir.