Dalam codelab ini, tingkatkan performa aplikasi berikut dengan menghapus dependensi yang tidak digunakan dan tidak diperlukan.
Ukur
Sebaiknya ukur terlebih dahulu performa situs sebelum menambahkan pengoptimalan.
- Untuk melihat pratinjau situs, tekan Lihat Aplikasi. Kemudian, tekan
Layar Penuh
.
Lanjutkan dan klik anak kucing favorit Anda. Realtime Database Firebase digunakan dalam aplikasi ini, sehingga skor diperbarui secara real-time dan disinkronkan dengan setiap orang yang menggunakan aplikasi. 🐈
- Tekan `Control+Shift+J` (atau `Command+Option+J` di Mac) untuk membuka DevTools.
- Klik tab Jaringan.
- Centang kotak Nonaktifkan cache.
- Muat ulang aplikasi.
Hampir 1 MB JavaScript dikirim untuk memuat aplikasi sederhana ini.
Lihat peringatan project di DevTools.
- Klik tab Console.
- Pastikan
Warnings
diaktifkan di dropdown tingkat di samping inputFilter
.
- Lihat peringatan yang ditampilkan.
Firebase, yang merupakan salah satu library yang digunakan dalam aplikasi ini, bertindak sebagai penolong yang baik dengan memberikan peringatan kepada developer agar tidak mengimpor seluruh paketnya, tetapi hanya komponen yang digunakan. Dengan kata lain, ada library yang tidak digunakan yang dapat dihapus di aplikasi ini agar aplikasi dimuat lebih cepat.
Ada juga contoh saat library tertentu digunakan, tetapi mungkin ada alternatif yang lebih sederhana. Konsep menghapus library yang tidak diperlukan akan dibahas lebih lanjut dalam tutorial ini.
Menganalisis paket
Ada dua dependensi utama dalam aplikasi:
- Firebase: platform yang menyediakan sejumlah layanan berguna untuk aplikasi iOS, Android, atau web. Di sini, Realtime Database-nya digunakan untuk menyimpan dan menyinkronkan informasi setiap anak kucing secara real time.
- Moment.js: library utilitas yang mempermudah penanganan tanggal di JavaScript. Tanggal lahir setiap anak kucing disimpan di database Firebase, dan
moment
digunakan untuk menghitung usianya dalam minggu.
Bagaimana hanya dua dependensi dapat berkontribusi pada ukuran paket hampir 1 MB? Nah, salah satu alasannya adalah setiap dependensi dapat memiliki dependensinya sendiri, sehingga jumlahnya lebih dari dua jika setiap kedalaman/cabang "pohon" dependensi dipertimbangkan. Aplikasi dapat menjadi besar dengan mudah relatif cepat jika banyak dependensi disertakan.
Analisis bundler untuk lebih memahami apa yang terjadi. Ada sejumlah alat buatan komunitas yang berbeda-beda yang dapat membantu melakukan hal ini, seperti webpack-bundle-analyzer
.
Paket untuk alat ini sudah disertakan dalam aplikasi sebagai devDependency
.
"devDependencies": {
//...
"webpack-bundle-analyzer": "^2.13.1"
},
Artinya, file tersebut dapat digunakan langsung dalam file konfigurasi webpack.
Impor di awal webpack.config.js
:
const path = require("path");
//...
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
.BundleAnalyzerPlugin;
Sekarang tambahkan sebagai plugin di bagian paling akhir file dalam array plugins
:
module.exports = {
//...
plugins: [
//...
new BundleAnalyzerPlugin()
]
};
Saat aplikasi dimuat ulang, Anda akan melihat visualisasi seluruh paket, bukan aplikasi itu sendiri.
Tidak selucu melihat anak kucing 🐱, tetapi tetap sangat membantu. Dengan mengarahkan kursor ke salah satu paket, Anda dapat melihat ukurannya yang ditampilkan dalam tiga cara berbeda:
Ukuran statistik | Ukuran sebelum minifikasi atau kompresi. |
---|---|
Ukuran yang diuraikan | Ukuran paket sebenarnya dalam bundle setelah dikompilasi. Webpack versi 4 (yang digunakan dalam aplikasi ini) meminimalkan file yang dikompilasi secara otomatis, sehingga ukurannya lebih kecil daripada ukuran stat. |
Ukuran yang di-gzip | Ukuran paket setelah dikompresi dengan encoding gzip. Topik ini dibahas dalam panduan terpisah. |
Dengan alat webpack-bundle-analyzer, Anda dapat lebih mudah mengidentifikasi paket yang tidak digunakan atau tidak diperlukan yang membentuk sebagian besar paket.
Menghapus paket yang tidak digunakan
Visualisasi menunjukkan bahwa paket firebase
terdiri dari banyak hal, bukan hanya database. Hal ini mencakup paket tambahan seperti:
firestore
auth
storage
messaging
functions
Semua layanan ini adalah layanan luar biasa yang disediakan oleh Firebase (dan lihat dokumentasi untuk mempelajari lebih lanjut), tetapi tidak ada satu pun yang digunakan dalam aplikasi, jadi tidak ada alasan untuk mengimpor semuanya.
Kembalikan perubahan di webpack.config.js
untuk melihat aplikasi lagi:
- Hapus
BundleAnalyzerPlugin
dalam daftar plugin:
plugins: [
//...
new BundleAnalyzerPlugin()
];
- Sekarang hapus impor yang tidak digunakan dari bagian atas file:
const path = require("path");
//...
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
Aplikasi sekarang akan dimuat secara normal. Ubah src/index.js
untuk memperbarui
impor Firebase.
import firebase from 'firebase';
import firebase from 'firebase/app';
import 'firebase/database';
Sekarang, saat aplikasi dimuat ulang, peringatan DevTools tidak akan ditampilkan. Membuka panel Network DevTools juga menunjukkan pengurangan ukuran paket yang cukup signifikan:
Lebih dari separuh ukuran paket dihapus. Firebase menyediakan banyak layanan yang berbeda dan memberi developer opsi untuk hanya menyertakan layanan yang benar-benar diperlukan. Dalam aplikasi ini, hanya firebase/database
yang digunakan untuk menyimpan dan menyinkronkan semua data. Impor firebase/app
, yang menyiapkan platform API untuk
setiap layanan yang berbeda, selalu diperlukan.
Banyak library populer lainnya, seperti lodash
, juga memungkinkan developer
mengimpor berbagai bagian paket mereka secara selektif. Tanpa banyak melakukan pekerjaan, memperbarui impor library di aplikasi agar hanya menyertakan apa yang digunakan dapat menghasilkan peningkatan performa yang signifikan.
Meskipun ukuran paket telah berkurang cukup banyak, masih ada pekerjaan yang harus dilakukan. 😈
Menghapus paket yang tidak diperlukan
Tidak seperti Firebase, mengimpor bagian library moment
tidak dapat dilakukan dengan mudah, tetapi mungkin library tersebut dapat dihapus sepenuhnya?
Tanggal lahir setiap anak kucing lucu disimpan dalam format Unix (milidetik) di database Firebase.
Ini adalah stempel waktu dari tanggal dan waktu tertentu yang diwakili oleh jumlah milidetik yang telah berlalu sejak 1 Januari 1970 00.00 UTC. Jika tanggal dan waktu saat ini dapat dihitung dalam format yang sama, fungsi kecil untuk menemukan usia setiap anak kucing dalam minggu mungkin dapat dibuat.
Seperti biasa, jangan menyalin dan menempel saat Anda mengikuti langkah-langkah di sini. Mulailah dengan
menghapus moment
dari impor di src/index.js
.
import firebase from 'firebase/app';
import 'firebase/database';
import * as moment from 'moment';
Ada pemroses peristiwa Firebase yang menangani perubahan nilai dalam database kita:
favoritesRef.on("value", (snapshot) => { ... })
Di atasnya, tambahkan fungsi kecil untuk menghitung jumlah minggu dari tanggal tertentu:
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);
}
Dalam fungsi ini, perbedaan dalam milidetik antara tanggal dan
waktu saat ini (new Date).getTime()
dan tanggal lahir (argumen birthDate
, sudah
dalam milidetik) dihitung dan dibagi dengan jumlah milidetik dalam
satu minggu.
Terakhir, semua instance moment
dapat dihapus di pemroses peristiwa dengan memanfaatkan fungsi ini:
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> `}) });
Sekarang muat ulang aplikasi dan lihat panel Network sekali lagi.
Ukuran bundle kami berkurang lebih dari separuhnya lagi.
Kesimpulan
Dengan codelab ini, Anda akan memiliki pemahaman yang cukup baik tentang cara menganalisis bundle tertentu dan alasan penghapusan paket yang tidak digunakan atau tidak diperlukan dapat sangat berguna. Sebelum Anda mulai mengoptimalkan aplikasi dengan teknik ini, penting untuk mengetahui bahwa hal ini dapat menjadi jauh lebih rumit dalam aplikasi yang lebih besar.
Terkait menghapus library yang tidak digunakan, coba cari tahu bagian paket yang digunakan dan bagian yang tidak digunakan. Untuk paket yang terlihat misterius dan sepertinya tidak digunakan di mana pun, mundur selangkah dan periksa dependensi tingkat teratas mana yang mungkin memerlukannya. Coba temukan cara untuk memisahkan keduanya.
Terkait menghapus library yang tidak diperlukan, situasinya bisa menjadi sedikit lebih
rumit. Anda harus bekerja sama dengan tim dan melihat apakah ada potensi untuk menyederhanakan bagian codebase. Menghapus moment
dalam aplikasi ini mungkin terlihat seperti hal yang tepat untuk dilakukan setiap saat, tetapi bagaimana jika ada zona waktu dan lokalitas yang berbeda yang perlu ditangani? Atau
bagaimana jika ada manipulasi tanggal yang lebih rumit? Prosesnya bisa sangat
rumit saat memanipulasi dan mengurai tanggal/waktu, dan library seperti moment
dan date-fns
menyederhanakannya secara signifikan.
Semua hal adalah pertukaran, dan penting untuk mengukur apakah kompleksitas dan upaya untuk meluncurkan solusi kustom sepadan dengan hasilnya dibandingkan mengandalkan library pihak ketiga.