Kullanılmayan kodu kaldırın

Bu codelab'de, kullanılmayan ve gereksiz bağımlılıkları kaldırarak aşağıdaki uygulamanın performansını iyileştirin.

Uygulama ekran görüntüsü

Ölçüm

Optimizasyon eklemeden önce bir web sitesinin ne kadar iyi performans gösterdiğini ölçmek her zaman iyi bir fikirdir.

  • Siteyi önizlemek için Uygulamayı Görüntüle'ye, ardından Tam Ekran'a tam ekran basın.

En sevdiğiniz kediyi tıklayın. Bu uygulamada Firebase'in Realtime Database hizmeti kullanıldığı için puan gerçek zamanlı olarak güncellenir ve uygulamayı kullanan diğer tüm kullanıcılarla senkronize edilir. 🐈

  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 seçin.
  4. Uygulamayı yeniden yükleyin.

Orijinal paket boyutu 992 KB

Bu basit uygulamayı yüklemek için neredeyse 1 MB'lık JavaScript gönderiliyor.

Geliştirici Araçları'ndaki proje uyarılarına göz atın.

  • Konsol sekmesini tıklayın.
  • Filter girişinin yanındaki seviyeler açılır menüsünde Warnings'ün etkinleştirildiğinden emin olun.

Uyarılar filtresi

  • Gösterilen uyarıya göz atın.

Konsol uyarısı

Bu uygulamada kullanılan kitaplıklardan biri olan Firebase, geliştiricilere paketin tamamını değil, yalnızca kullanılan bileşenleri içe aktarmamaları gerektiğini bildiren bir uyarı sağlayarak iyi bir samaritan örneği gösteriyor. Başka bir deyişle, bu uygulamada uygulamanın daha hızlı yüklenmesini sağlamak için kaldırılabilecek kullanılmayan kitaplıklar vardır.

Belirli bir kitaplığın kullanıldığı, ancak daha basit bir alternatifin de olabileceği durumlar vardır. Gereksiz kitaplıkları kaldırma kavramı bu eğitimde daha sonra ele alınacaktır.

Paketi analiz etme

Uygulamada iki temel bağımlılık vardır:

  • Firebase: iOS, Android veya web uygulamaları için çeşitli faydalı hizmetler sunan bir platformdur. Burada, her bir yavru kedinin bilgilerini gerçek zamanlı olarak depolamak ve senkronize etmek için Realtime Database kullanılır.
  • Moment.js: JavaScript'te tarihleri işlemeyi kolaylaştıran bir yardımcı kitaplıktır. Her yavru kedinin doğum tarihi Firebase veritabanında saklanır ve yaşını hafta cinsinden hesaplamak için moment kullanılır.

Yalnızca iki bağımlılık, yaklaşık 1 MB'lık bir paket boyutuna nasıl katkıda bulunabilir? Bunun nedenlerinden biri, her bağımlılığın kendi bağımlılıkları olabileceğidir. Bu nedenle, bağımlılık "ağacının" her derinliği/dalını dikkate alırsak ikiden çok bağımlı vardır. Çok sayıda bağımlılık eklenirse bir uygulamanın nispeten hızlı bir şekilde büyük hale gelmesi kolaydır.

Neler olduğunu daha iyi anlamak için paketleyiciyi analiz edin. Bunu yapmanıza yardımcı olabilecek, topluluk tarafından oluşturulmuş çeşitli araçlar vardır (ör. webpack-bundle-analyzer).

Bu aracın paketi, uygulamaya devDependency olarak zaten eklenmiştir.

"devDependencies": {
  //...
  "webpack-bundle-analyzer": "^2.13.1"
},

Yani doğrudan web paketi yapılandırma dosyasında kullanılabilir. webpack.config.js öğesinin en başında içe aktarın:

const path = require("path");

//...
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
  .BundleAnalyzerPlugin;

Şimdi bu işlevi, dosyanın en sonuna plugins dizisine eklenecek bir eklenti olarak ekleyin:

module.exports = {
  //...
  plugins: [
    //...
    new BundleAnalyzerPlugin()
  ]
};

Uygulama yeniden yüklendiğinde, uygulamanın kendisi yerine paketin tamamının görselleştirmesini görürsünüz.

Webpack Bundle Analiz Aracı

Kedi yavrusu kedileri görmek kadar sevimli değil 😅 ama yine de çok faydalı. Fareyle paketlerin üzerine geldiğinizde boyutları üç farklı şekilde gösterilir:

İstatistik boyutu Herhangi bir küçültme veya sıkıştırma işleminden önceki boyut.
Ayrıştırılmış boyut Derlendikten sonra paket içindeki gerçek paketin boyutu. Bu uygulamada kullanılan webpack'in 4. sürümü, derlenmiş dosyaları otomatik olarak küçültür. Bu nedenle, bu dosya istatistik boyutundan daha küçüktür.
Sıkıştırılmış boyut gzip kodlamasıyla sıkıştırıldıktan sonra paketin boyutu. Bu konu ayrı bir kılavuzda ele alınmıştır.

webpack-bundle-analyzer aracıyla, paketin büyük bir yüzdesini oluşturan kullanılmayan veya gereksiz paketleri tespit etmek daha kolaydır.

Kullanılmayan paketleri kaldırma

Görselleştirme, firebase paketinin yalnızca bir veritabanından çok daha fazlasını içerdiğini gösterir. Buna aşağıdakiler gibi ek paketler dahildir:

  • firestore
  • auth
  • storage
  • messaging
  • functions

Bunların tümü Firebase tarafından sağlanan muhteşem hizmetlerdir (daha fazla bilgi edinmek için dokümanlara göz atın). Ancak bunların hiçbiri uygulamada kullanılmadığından tümünün içe aktarılmasına gerek yoktur.

Uygulamayı tekrar görmek için webpack.config.js uygulamasında değişiklikleri geri alın:

  • Eklenti listesinden BundleAnalyzerPlugin'ü kaldırın:
plugins: [
  //...
  new BundleAnalyzerPlugin()
];
  • Ardından, kullanılmayan içe aktarma işlemini dosyanın üst kısmından kaldırın:
const path = require("path");

//...
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

Uygulama artık normal bir şekilde yüklenmelidir. Firebase içe aktarma işlemlerini güncellemek için src/index.js değerini değiştirin.

import firebase from 'firebase';
import firebase from 'firebase/app';
import 'firebase/database';

Artık uygulama yeniden yüklendiğinde DevTools uyarısı gösterilmiyor. Geliştirici Araçları paneli açıldığında paket boyutunun güzel bir şekilde küçüldüğü gösterilir:

Paket boyutu 480 KB'a düşürüldü

Paket boyutunun yarısından fazlası kaldırıldı. Firebase birçok farklı hizmet sunar ve geliştiricilere yalnızca gerçekten gerekli olanları ekleme seçeneği sunar. Bu uygulamada, tüm verileri depolamak ve senkronize etmek için yalnızca firebase/database kullanıldı. Farklı hizmetlerin her biri için API yüzeyini ayarlayan firebase/app içe aktarma işlemi her zaman gereklidir.

lodash gibi diğer popüler kitaplıklar da geliştiricilerin paketlerinin farklı bölümlerini seçerek içe aktarmasına olanak tanır. Çok fazla çalışma yapmadan, bir uygulamadaki kitaplık içe aktarma işlemlerini yalnızca kullanılanları içerecek şekilde güncellemek önemli performans iyileştirmelerine neden olabilir.

Paket boyutu oldukça küçültülmüş olsa da yapılması gereken daha çok iş var. 😈

Gereksiz paketleri kaldırma

Firebase'den farklı olarak, moment kitaplığının bölümlerini içe aktarmak o kadar kolay değildir ancak tamamen kaldırılabilir mi?

Her sevimli yavru kedinin doğum günü, Firebase veritabanında Unix biçiminde (milisaniye) depolanır.

Unix biçiminde depolanan doğum tarihleri

Bu, 1 Ocak 1970 00:00 UTC tarihinden itibaren geçen milisaniye sayısıyla temsil edilen belirli bir tarih ve saatin zaman damgası. Mevcut tarih ve saat aynı biçimde hesaplanabiliyorsa her yavrunun yaşını hafta cinsinden bulmak için küçük bir işlev oluşturulabilir.

Her zaman olduğu gibi, bu adımları uygularken kopyalayıp yapıştırmamaya çalışın. moment dosyasını src/index.js kapsamındaki içe aktarma işlemlerinden kaldırarak başlayın.

import firebase from 'firebase/app';
import 'firebase/database';
import * as moment from 'moment';

Veritabanımızdaki değer değişikliklerini yöneten bir Firebase etkinlik işleyicisi vardır:

favoritesRef.on("value", (snapshot) => { ... })

Bunun üzerine, belirli bir tarihten itibaren hafta sayısını hesaplamak için küçük bir işlev ekleyin:

const ageInWeeks = birthDate => {
  const WEEK_IN_MILLISECONDS = 1000 * 60 * 60 * 24 * 7;
  const diff = Math.abs((new Date).getTime() - birthDate);
  return Math.floor(diff / WEEK_IN_MILLISECONDS);
}

Bu işlevde, geçerli tarih ve saat (new Date).getTime() ile doğum tarihi (birthDate bağımsız değişkeni, milisaniye cinsinden) arasındaki milisaniye farkı hesaplanır ve tek bir haftadaki milisaniye sayısına bölünür.

Son olarak, bunun yerine şu işlevden yararlanılarak tüm moment örnekleri etkinlik işleyiciden kaldırılabilir:

favoritesRef.on("value", (snapshot) => {
  const { kitties, favorites, names, birthDates } = snapshot.val();
  favoritesScores = favorites;

  kittiesList.innerHTML = kitties.map((kittiePic, index) => {
    const birthday = moment(birthDates[index]);

    return `
      <li>
        <img src=${kittiePic} onclick="favKittie(${index})">
        <div class="extra">
          <div class="details">
            <p class="name">${names[index]}</p>
            <p class="age">${moment().diff(birthday, 'weeks')} weeks old</p>
            <p class="age">${ageInWeeks(birthDates[index])} weeks old</p>
          </div>
          <p class="score">${favorites[index]} ❤</p>
        </div>
      </li>
    `})
});

Şimdi uygulamayı yeniden yükleyin ve paneline bir kez daha göz atın.

Paket boyutu 225 KB&#39;ye düşürüldü

Paketimizin boyutu yine yarıdan fazla azaldı.

Sonuç

Bu kod laboratuvarını tamamladığınızda, belirli bir paketin nasıl analiz edileceğini ve kullanılmayan veya gereksiz paketlerin neden kaldırılmasının çok yararlı olabileceğini iyice anlamış olacaksınız. Bu teknikle bir uygulamayı optimize etmeye başlamadan önce, bunun daha büyük uygulamalarda çok daha karmaşık olabileceğini bilmeniz önemlidir.

Kullanılmayan kitaplıkları kaldırma ile ilgili olarak, paketin hangi bölümlerinin kullanıldığını ve hangi bölümlerinin kullanılmadığını bulmaya çalışın. Hiçbir yerde kullanılmadığı anlaşılan gizemli görünümlü bir paket için bir adım geri çekilin ve hangi üst düzey bağımlılıkların buna ihtiyaç duyabileceğini kontrol edin. Bunları birbirinden ayırmanın bir yolunu bulmaya çalışın.

Gereksiz kitaplıkları kaldırma söz konusu olduğunda işler biraz daha karmaşık olabilir. Ekibinizle yakın bir şekilde çalışmak ve kod tabanının bölümlerini basitleştirmenin mümkün olup olmadığını görmeniz önemlidir. Bu uygulamada moment değerini kaldırmak her zaman doğru bir işlem gibi görünebilir ancak ele alınması gereken saat dilimleri ve farklı yerel ayarlar varsa ne olur? Ya da daha karmaşık tarih işlemleri varsa? Tarihleri/saatleri değiştirirken ve ayrıştırırken işler çok karmaşık hale gelebilir. moment ve date-fns gibi kitaplıklar bu süreci önemli ölçüde basitleştirir.

Her şey bir ödün vermektir ve üçüncü taraf kitaplıklara güvenmek yerine özel bir çözüm sunmanın karmaşıklığına ve çabasına değip değmeyeceğini ölçmek önemlidir.