Episode ini membahas optimasi performa: profiling dengan Angular DevTools, strategi change detection Default versus OnPush, trackBy dan lazy loading untuk code splitting, serta analisis bundle dan optimasi production.

Aplikasi yang fiturnya lengkap tidak ada artinya jika lambat dimuat dan terasa berat saat dipakai. Performa adalah bagian dari pengalaman pengguna, dan Angular menyediakan alat serta strategi untuk menjaganya tetap cepat.
Episode 15 membahas profiling dengan Angular DevTools, strategi change detection Default versus OnPush, trackBy dan lazy loading untuk code splitting, serta analisis bundle dan optimasi production. Optimasi dilakukan dengan data, bukan asumsi.
Angular DevTools adalah ekstensi browser untuk Chrome dan Firefox. Setelah dipasang, buka tab Angular di DevTools saat aplikasi berjalan. Di sana ada panel Profiler yang merekam aktivitas change detection.
ng.profiler.timeChangeDetection()ng.profiler.timeChangeDetection() di console menjalankan beberapa siklus change detection dan mengembalikan statistik durasi. Ini cara cepat untuk mengetahui apakah aplikasi melakukan pekerjaan yang terlalu banyak saat mendeteksi perubahan.
Panel Profiler menampilkan diagram flame — berapa lama tiap komponen menghabiskan waktu di change detection. Komponen yang tebal dan sering muncul adalah kandidat optimasi. Fokus pada yang paling mahal, bukan sekadar yang paling banyak.
Secara default Angular memeriksa semua komponen saat ada perubahan. Semakin banyak komponen, semakin mahal. Strategi OnPush membatasi pemeriksaan hanya ketika salah satu kondisi terpenuhi: input berubah, event dipicu di dalam komponen, atau signal berubah.
import { Component, ChangeDetectionStrategy, signal } from '@angular/core';
@Component({
selector: 'app-item',
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
template: `<p>{{ item().nama }}</p>`,
})
export class ItemComponent {
readonly item = signal({ nama: 'Kopi', harga: 25000 });
}ChangeDetectionStrategy.OnPush membuat komponen hanya di-render ulang saat benar-benar perlu. Dengan signal, Angular tahu persis dependency mana yang berubah — kombinasi OnPush dan signal menghasilkan aplikasi yang jauh lebih efisien.
Default tetap valid untuk komponen kecil yang jarang diperbarui atau bergantung pada banyak faktor eksternal. Aturan praktisnya: pakai OnPush sebagai default untuk komponen baru, dan ukur dampaknya dengan Profiler.
Saat daftar berubah, Angular harus mencocokkan item lama dan baru. Tanpa track, Angular memakai identitas referensi objek. Dengan track, Angular memakai nilai yang stabil sehingga hanya item yang berubah yang di-render ulang:
@for (produk of daftarProduk(); track produk.id) {
<app-kartu-produk [produk]="produk" />
}track produk.id memberitahu Angular untuk melacak item berdasarkan id, bukan referensi objek. Untuk daftar klasik, *ngFor memakai trackBy. Dampaknya paling terasa pada daftar yang sering diperbarui atau item yang bisa disusun ulang.
Code splitting memecah bundle menjadi chunk per fitur. Di Angular, ini dilakukan lewat loadComponent pada route (episode 9):
{
path: 'laporan',
loadComponent: () =>
import('./laporan/laporan.component').then((m) => m.LaporanComponent),
}Kode halaman laporan diunduh hanya saat pengguna membukanya. Initial load menjadi lebih ringan, dan halaman yang jarang dikunjungi tidak membebani pengguna pertama kali.
Gunakan source-map-explorer untuk melihat isi bundle:
ng build --configuration=production
npx source-map-explorer dist/toko-online/browser/*.jssource-map-explorer menampilkan bagian mana yang paling besar di bundle — library mana yang membebani. Temuan umum: library besar yang hanya dipakai beberapa fungsi, atau duplikasi dependency.
Setel budgets di angular.json agar build gagal saat bundle melewati batas. Budget default sudah ada; kalian bisa menyesuaikan:
"budgets": [
{ "type": "initial", "maximumWarning": "500kb", "maximumError": "1mb" }
]Dengan budget maximumError: '1mb', build akan gagal jika bundle awal melebihi 1 MB. Ini memaksa tim menjaga ukuran bundle sejak awal, bukan mengejar optimasi di akhir.
Selain budget: aktifkan optimasi dan hashing, pertimbangkan lazy load untuk library berat, hindari import yang tidak dipakai (tree shaking sudah dijalankan build optimizer), dan pindahkan dependensi besar ke halaman yang tepat. Ukur ulang setelah setiap perubahan untuk memastikan perbaikan nyata.
Inti yang harus dibawa pulang:
ng.profiler.timeChangeDetection() memberi gambaran cepat beban deteksi.track pada @for mencegah render ulang item yang tidak berubah.loadComponent memecah bundle sesuai rute yang diakses.Di episode 16 selanjutnya kita akan membahas testing dan quality — unit testing komponen dan service, menguji pipes, directives, dan guards, integration testing dengan TestBed, serta end-to-end testing dengan Cypress atau Playwright.