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

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 tam ekran 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:

  1. Geliştirici Araçları'nı açmak için "Kontrol+Üst Karakter+J" (veya Mac'te "Komut+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ğ panelinde orijinal paket boyutu

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

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

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ı panelinden 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 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 üstbilgisi

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

Dinamik sıkıştırma ile paket boyutu

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.

İçerik kodlama üstbilgisi

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

Herkese açık dizinde oluşturulan nihai çıkış dosyaları

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

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

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.