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

Ölçüm
Optimizasyon eklemeden önce her zaman bir web sitesinin ne kadar iyi performans gösterdiğini ölçmek iyi bir fikirdir.
- Siteyi önizlemek için Uygulamayı Görüntüle'ye basın. Ardından Tam Ekran'a
basın.
En sevdiğiniz yavru kediyi tıklayın. Bu uygulamada Firebase'in Realtime Database ürünü kullanılıyor. Bu sayede puanlar gerçek zamanlı olarak güncelleniyor ve uygulamayı kullanan diğer herkesle senkronize ediliyor. 🐈
- Geliştirici Araçları'nı açmak için `Ctrl+Üst Karakter+J` (veya Mac'te `Command+Option+J`) tuşlarına basın.
- Ağ sekmesini tıklayın.
- Önbelleği devre dışı bırak onay kutusunu işaretleyin.
- Uygulamayı yeniden yükleyin.

Bu basit uygulamayı yüklemek için neredeyse 1 MB JavaScript gönderiliyor.
Geliştirici Araçları'ndaki proje uyarılarına göz atın.
- Console (Konsol) sekmesini tıklayın.
Filtergirişinin yanındaki düzeyler açılır listesindeWarningsseçeneğinin etkinleştirildiğinden emin olun.

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

Bu uygulamada kullanılan kitaplıklardan biri olan Firebase, geliştiricilere tüm paketi değil, yalnızca kullanılan bileşenleri içe aktarmaları gerektiğini bildiren bir uyarı vererek iyi bir iş çıkarıyor. Başka bir deyişle, bu uygulamada daha hızlı yüklenmesi için kaldırılabilecek kullanılmayan kitaplıklar var.
Belirli bir kitaplığın kullanıldığı ancak daha basit bir alternatifin olabileceği durumlar da vardır. Gereksiz kitaplıkları kaldırma kavramı bu eğitimin ilerleyen bölümlerinde ele alınacaktır.
Paket analiz ediliyor
Uygulamada iki ana bağımlılık vardır:
- Firebase: iOS, Android veya web uygulamaları için çeşitli faydalı hizmetler sunan bir platformdur. Burada, her yavru kediyle ilgili bilgileri gerçek zamanlı olarak depolamak ve senkronize etmek için Realtime Database kullanılıyor.
- Moment.js: JavaScript'te tarihleri işlemeyi kolaylaştıran bir yardımcı program kitaplığı. Her yavru kedinin doğum tarihi Firebase veritabanında saklanır ve
moment, yaşını hafta cinsinden hesaplamak için 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ının olabilmesidir. Bu nedenle, bağımlılık "ağacının" her derinliği/dalı dikkate alınırsa ikiden çok daha fazla bağımlılık vardır. Çok sayıda bağımlılık varsa uygulamanın nispeten hızlı bir şekilde büyümesi kolaydır.
Neler olduğunu daha iyi anlamak için paketleyiciyi analiz edin. Bunu yapmanıza yardımcı olabilecek, topluluk tarafından geliştirilmiş çeşitli araçlar vardır. Örneğin, webpack-bundle-analyzer.
Bu aracın paketi, uygulamaya devDependency olarak zaten eklenmiş.
"devDependencies": {
//...
"webpack-bundle-analyzer": "^2.13.1"
},
Bu, doğrudan webpack yapılandırma dosyasında kullanılabileceği anlamına gelir.
webpack.config.js dosyasının en başına aktarın:
const path = require("path");
//...
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
.BundleAnalyzerPlugin;
Şimdi bunu, dosyanın en sonunda plugins dizisi içinde bir eklenti olarak ekleyin:
module.exports = {
//...
plugins: [
//...
new BundleAnalyzerPlugin()
]
};
Uygulama yeniden yüklendiğinde, uygulamanın kendisi yerine tüm paketin görselleştirmesini görürsünüz.

Yavru kedi görmek 🐱 kadar sevimli olmasa da son derece faydalı. Fare imlecini paketlerden birinin üzerine getirdiğinizde paketin boyutu üç farklı şekilde gösterilir:
| İstatistik boyutu | Sadeleştirme veya sıkıştırma işleminden önceki boyut. |
|---|---|
| Ayrıştırılmış boyut | Derlendikten sonra paketteki gerçek paketin boyutu. Webpack'in 4. sürümü (bu uygulamada kullanılan sürüm), derlenen dosyaları otomatik olarak sadeleştirir. Bu nedenle, bu boyut stat boyutundan daha küçüktür. |
| Gzip ile 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 belirlemek daha kolaydır.
Kullanılmayan paketleri kaldırma
Görselleştirmede, firebase paketinin yalnızca bir veritabanından ibaret olmadığı, çok daha fazlasını içerdiği gösteriliyor. Aşağıdakiler gibi ek paketler içerir:
firestoreauthstoragemessagingfunctions
Bunların hepsi Firebase tarafından sağlanan muhteşem hizmetlerdir (daha fazla bilgi edinmek için belgelere bakın) ancak hiçbiri uygulamada kullanılmadığından hepsini içe aktarmanız gerekmez.
Uygulamayı tekrar görmek için webpack.config.js uygulamasındaki değişiklikleri geri alın:
- Eklenti listesinden
BundleAnalyzerPluginöğesini kaldırın:
plugins: [
//...
new BundleAnalyzerPlugin()
];
- Şimdi de dosyanın üst kısmındaki kullanılmayan içe aktarma işlemini kaldırın:
const path = require("path");
//...
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
Uygulama artık normal şekilde yüklenecektir. Firebase içe aktarma işlemlerini güncellemek için src/index.js öğesini değiştirin.
import firebase from 'firebase';
import firebase from 'firebase/app';
import 'firebase/database';
Uygulama yeniden yüklendiğinde Geliştirici Araçları uyarısı gösterilmez. Geliştirici Araçları'nın Ağ panelini açtığınızda paket boyutunda önemli bir azalma olduğunu da görebilirsiniz:

Paket boyutunun yarısından fazlası kaldırıldı. 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ı. Her bir farklı hizmet 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 da geliştiricilerin paketlerinin farklı bölümlerini seçerek içe aktarmasına olanak tanır. Çok fazla iş yapmadan, bir uygulamadaki kitaplık içe aktarmalarını yalnızca kullanılanları içerecek şekilde güncellemek, önemli performans iyileştirmeleri sağlayabilir.
Paket boyutu oldukça küçültülmüş olsa da yapılması gereken daha çok şey 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 belki tamamen kaldırılabilir.
Her sevimli kedinin doğum günü, Firebase veritabanında Unix biçiminde (milisaniye) saklanır.

Bu, 1 Ocak 1970 00:00 UTC'den bu yana geçen milisaniye sayısıyla temsil edilen belirli bir tarih ve saatin zaman damgasıdır. Geçerli tarih ve saat aynı biçimde hesaplanabiliyorsa her bir yavru kedinin yaşını hafta cinsinden bulmak için küçük bir işlev oluşturulabilir.
Her zaman olduğu gibi, buradaki adımları uygularken kopyalayıp yapıştırmamaya çalışın. src/index.js içindeki içe aktarma işlemlerinden moment öğesini 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 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 (milisaniye cinsinden birthDate bağımsız değişkeni) arasındaki fark milisaniye cinsinden hesaplanır ve bir haftadaki milisaniye sayısına bölünür.
Son olarak, etkinlik işleyicideki tüm moment örnekleri, bunun yerine aşağıdaki işlev kullanılarak 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 Ağ paneline bir kez daha bakın.

Paketimizin boyutu bir kez daha yarıdan fazla küçüldü.
Sonuç
Bu codelab'i tamamladığınızda, belirli bir paketi nasıl analiz edeceğinizi ve kullanılmayan veya gereksiz paketleri kaldırmanın neden çok yararlı olabileceğini iyi bir şekilde anlamış olursunuz. Bu teknikle bir uygulamayı optimize etmeye başlamadan önce, bu işlemin daha büyük uygulamalarda çok daha karmaşık olabileceğini bilmeniz önemlidir.
Kullanılmayan kitaplıkları kaldırma konusunda, bir paketin hangi bölümlerinin kullanıldığını ve hangi bölümlerinin kullanılmadığını öğrenmeye çalışın. Hiçbir yerde kullanılmıyor gibi görünen gizemli bir paket için bir adım geri çekilin ve hangi üst düzey bağımlılıkların buna ihtiyacı olabileceğini kontrol edin. Bunları birbirinden ayırmanın bir yolunu bulmaya çalışın.
Gereksiz kitaplıkları kaldırma konusu biraz daha karmaşık olabilir. Ekibinizle yakın bir şekilde çalışarak kod tabanının bazı bölümlerini basitleştirme imkanı olup olmadığını görmek önemlidir. Bu uygulamada moment'i kaldırmak her zaman doğru bir işlem gibi görünebilir ancak saat dilimleri ve farklı yerel ayarların işlenmesi gerekiyorsa ne olur? Ya da daha karmaşık tarih işlemleri olsaydı ne olurdu? Tarihleri/saatleri değiştirirken ve ayrıştırırken işler çok zorlaşabilir. moment ve date-fns gibi kitaplıklar bu süreci önemli ölçüde basitleştirir.
Her şey bir ödünleşimdir ve üçüncü taraf kitaplığına güvenmek yerine özel bir çözüm sunmak için karmaşıklığa ve çabaya değip değmeyeceğini ölçmek önemlidir.