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öster'e, ardından Tam Ekran'a tam ekran basın.

En sevdiğiniz kedi yavrusunu tıklayın. Bu uygulamada Firebase'in Realtime Database'i kullanılır. Bu nedenle puan, gerçek zamanlı olarak güncellenir ve uygulamayı kullanan diğer kişilerle senkronize edilir. 🐈

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

992 KB orijinal paket boyutu

Bu basit uygulamayı yüklemek için yaklaşık 1 MB'lık JavaScript kodu 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 öğesinin etkinleştirildiğinden emin olun.

Uyarı filtresi

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

Konsol uyarısı

Bu uygulamada kullanılan kitaplıklardan biri olan Firebase, geliştiricilere paketinin tamamını değil, yalnızca kullanılan bileşenleri içe aktarmaları gerektiğini bildiren bir uyarı sunarak iyi bir fayda sağlar. Başka bir deyişle, bu uygulamayı daha hızlı yüklemek için kaldırabileceğiniz kullanılmayan kitaplıklar vardır.

Belirli bir kitaplığın kullanıldığı ancak daha basit bir alternatifin de kullanılabileceği durumlar da vardır. Gereksiz kitaplıkları kaldırma kavramı bu eğiticinin ilerleyen kısımlarında ele alınmaktadır.

Paket analiz ediliyor

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

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

Sadece iki bağımlılık neredeyse 1 MB'lik bir paket boyutuna nasıl katkıda bulunabilir? Bunun nedenlerinden biri, her bağımlılığın kendine özgü bağımlılıkları olmasıdır. Bu nedenle, bağımlılık "ağacının" her derinliği/kolları dikkate alınırsa ikiden çok daha fazlası olur. Birçok bağımlılık dahil edilirse 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. Topluluk tarafından oluşturulmuş, size yardımcı olabilecek webpack-bundle-analyzer gibi çeşitli araçlar mevcuttur.

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

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

Bu, paketin doğrudan web paketi yapılandırma dosyasında kullanılabileceği anlamına gelir. webpack.config.js dosyasının en başında içe aktar:

const path = require("path");

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

Şimdi plugins dizisinin içinde, dosyanın en sonuna eklenti olarak ekleyin:

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

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

Web Paketi Paket Analiz Aracı

Birkaç yavru kedi görmek kadar şirin 🐱 değil, ama yine de inanılmaz faydalı. Paketlerden herhangi birinin üzerine geldiğinizde, paketin boyutu üç 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. Web paketinin (bu uygulamada kullanılan) 4 sürümü, derlenen dosyaları otomatik olarak küçülttüğünden istatistik boyutundan daha küçüktür.
Gzip ile sıkıştırılmış boyut gzip kodlamasıyla sıkıştırıldıktan sonraki paketin boyutu. Bu konu, ayrı bir kılavuzda ele alınmıştır.

Web paketi-paket analiz aracı sayesinde, paketin büyük bir bölümünü oluşturan kullanılmayan veya ihtiyaç duyulmayan paketleri belirlemek daha kolaydır.

Kullanılmayan paketleri kaldırma

Görselleştirme, firebase paketinin bir veritabanından çok daha fazlasını içerdiğini göstermektedir. Şunlar gibi ek paketleri içerir:

  • firestore
  • auth
  • storage
  • messaging
  • functions

Bunların hepsi Firebase tarafından sağlanan muhteşem hizmetlerdir (daha fazla bilgi edinmek için belgeleri inceleyebilirsiniz) ancak hiçbiri uygulamada kullanılmadığı için tümünün içe aktarılmasına gerek yoktur.

Uygulamayı tekrar görmek için webpack.config.js üzerinde yapılan değişiklikleri geri alın:

  • Eklenti listesinden BundleAnalyzerPlugin öğesini kaldırın:
plugins: [
  //...
  new BundleAnalyzerPlugin()
];
  • Şimdi, kullanılmayan içe aktarmayı dosyanın en üstünden kaldırın:
const path = require("path");

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

Uygulamanın artık normal bir şekilde yüklenmesi gerekir. Firebase içe aktarmalarını güncellemek için src/index.js üzerinde değişiklik yapın.

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

Artık uygulama yeniden yüklendiğinde Geliştirici Araçları uyarısı gösterilmiyor. DevTools panelini açtığınızda paket boyutunda iyi bir küçülme de gösterilmektedir:

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

Paket boyutunun yarısından fazlası kaldırılmış. Firebase birçok farklı hizmet sunar ve geliştiricilere yalnızca gerçekten ihtiyaç duyulan hizmetleri dahil etme 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 birçok popüler kitaplık, geliştiricilerin paketlerinin farklı parçalarını seçerek içe aktarmasına da 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ştirmeleri sağlayabilir.

Paket boyutu epey küçültülmüş olsa da hâlâ yapılacak çok iş var. 😈

Gereksiz paketleri kaldırma

Firebase'in aksine, moment kitaplığının bazı bölümlerinin içe aktarılması kolay bir şekilde yapılamaz, ancak tamamen kaldırılabilir mi?

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

Unix biçiminde depolanan doğum tarihleri

Belirli bir tarih ve saatin, 1 Ocak 1970 00:00 UTC saatinden itibaren geçen milisaniye sayısıyla temsil edilen zaman damgasıdır. Güncel tarih ve saat aynı biçimde hesaplanabilirse muhtemelen her bir yavru kedinin yaşını haftalar içinde bulmak için küçük bir işlev oluşturulabilir.

Her zaman olduğu gibi, burada anlatıldığı şekilde kopyalayıp yapıştırmamaya çalışın. moment dosyasını src/index.js içindeki içe aktarmalardan 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 işleyen bir Firebase etkinlik işleyicisi bulunmaktadır:

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

Belirli bir tarihten itibaren hafta sayısını hesaplamak için bunun üstüne 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 (zaten milisaniye cinsinden birthDate bağımsız değişkeni) arasındaki milisaniye cinsinden fark, tek bir haftadaki milisaniye sayısına bölünür.

Son olarak, bunun yerine bu işlevden yararlanarak etkinlik işleyicideki tüm moment örnekleri 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;a düşürüldü

Paketimizin boyutu yine yarıdan fazla küçültüldü!

Sonuç

Bu codelab ile belirli bir paketi nasıl analiz edeceğinizi ve kullanılmayan ya da gereksiz paketleri kaldırmanın neden bu kadar faydalı olabileceğini iyice anladı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 konusunda, paketin hangi bölümlerinin kullanıldığını ve hangi parçalarının kullanılmadığını öğrenmeye çalışın. Hiçbir yerde kullanılmadığı görülen gizemli görünümlü bir paket için durup hangi üst düzey bağımlılıklarda bu ihtiyaç olabileceğini kontrol edin. Hepsini birbirinden ayırmak için bir yol bulmaya çalışın.

Gereksiz kitaplıkları kaldırmak konusunda ise işler biraz daha karmaşık hale gelebilir. Ekibinizle yakın bir şekilde çalışmak ve kod tabanının parçalarını basitleştirme potansiyeli olup olmadığını görmek önemlidir. Bu uygulamada moment öğesinin kaldırılması her seferinde yapılması gereken doğru bir şey gibi görünebilir, ancak işlenmesi gereken saat dilimleri ve farklı yerel ayarlar varsa ne olur? Ya da daha karmaşık tarih manipülasyonları olsaydı? Tarihleri/saatleri değiştirirken ve ayrıştırırken işler zorlaşabilir. moment ve date-fns gibi kitaplıklar ise bunu önemli ölçüde basitleştirir.

Her şey bir dengedir. Bu nedenle, üçüncü taraf kitaplığına güvenmek yerine özel bir çözümü kullanıma sunmanın karmaşıklığına ve çabasına değip değmeyeceğini ölçmek önemlidir.