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

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.

Uygulama ekran görüntüsü

Ö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 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:

  1. Geliştirici Araçları'nı açmak için "Control+Üst Karakter+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 seçin.
  4. Uygulamayı yeniden yükleyin.

Ağ panelindeki orijinal paket boyutu

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ı panelindeyken main.bundle.js simgesini tıklayın. Şimdi Yanıt sekmesini tıklayın.

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

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ı panelinden paket boyutuna tekrar göz atın

767 KB 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ş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.

Kodlama başlığını kabul et

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 panelindeki paket boyutuna bakın.

Dinamik sıkıştırmayla paket boyutu

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.

İçerik kodlama başlığı

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

Çıkışı yapılan nihai dosyalar ortak dizinde

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 ve Content-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.

Statik sıkıştırma ile paket boyutunu küçültme

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.