Belajar Desktop Developer - Performance Desktop
Episode 16 of 28

Belajar Desktop Developer - Performance Desktop

Membuat CatatanKu cepat: mengelola memori tanpa kebocoran, mempercepat startup time, dan memakai CPU & GPU profiler untuk menemukan bottleneck, dengan prinsip ukur-dulu-baru-optimasi

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Di episode 1 kita menempatkan performa sebagai tanggung jawab inti desktop developer. Kini kita membuktikannya. Aplikasi desktop diukur dari persepsi: seberapa cepat muncul setelah diklik, seberapa mulus scroll, seberapa besar memori yang dipakai saat 10.000 catatan terbuka. Web bisa memaafkan lambat — desktop tidak, karena pengguna bisa melihat proses lain di layar yang sama.

Episode ini membangun disiplin performa CatatanKu dengan urutan yang benar: ukur dulu, optimasi kemudian. Tanpa pengukuran, optimasi hanyalah tebakan — dan tebakan biasanya salah sasaran. Kita bahas tiga domain utama: memori, startup time, dan CPU — plus tool profiling tiap framework.

Prinsip: Ukur Dulu, Baru Optimasi

Tiga Pertanyaan Sebelum Optimasi

  1. Apa yang diukur? — metrik konkret: startup (ms), memori puncak (MB), frame drop, durasi operasi tertentu.
  2. Bagaimana baseline-nya? — tanpa angka awal, tidak ada cara tahu apakah optimasi berhasil.
  3. Di mana bottleneck-nya? — profiler, bukan intuisi.
Metrik target CatatanKu
Startup → ≤ 1.5 detik sampai window interaktif
Memori  → ≤ 150 MB idle dengan 10.000 catatan
Pencarian → ≤ 50 ms untuk query FTS pada 10.000 catatan
Scroll  → 0 frame drop saat menggulir daftar panjang

Jadikan metrik ini regression guard: jalankan di CI (episode 17), gagalkan build jika melampaui ambang. Performa yang tidak diukur akan menguap perlahan tanpa disadari.

Memori: Kebocoran yang Diam-diam

Memahami Siklus Hidup

Kebocoran memori di desktop terjadi saat objek tidak lagi dipakai tetapi tetap dirujuk — GC (JS/Dart) atau refcount (Rust) tidak bisa membebaskannya. Gejalanya: aplikasi makin berat seiring pemakaian, hingga "out of memory".

Polanya sulit dirasakan dalam sesi pendek — itulah mengapa pemantauan jangka panjang penting. Tiga pola umum di CatatanKu:

JSKebocoran umum: listener tanpa pembersihan
// ❌ tambah listener tiap render, tidak pernah dibersihkan
function initEvents() {
  window.addEventListener("resize", onResize);
}
 
// ✅ kembalikan cleanup, panggil saat tidak dibutuhkan
function initEvents() {
  window.addEventListener("resize", onResize);
  return () => window.removeEventListener("resize", onResize);
}
Kebocoran umum: interval berjalan tanpa batas
// ❌ interval tetap hidup setelah fitur mati
setInterval(() => checkSync(), 5000);
 
// ✅ simpan id dan clear saat fitur tidak aktif
const syncTimer = setInterval(() => checkSync(), 5000);
// ... clearInterval(syncTimer) saat logout / window ditutup
Kebocoran umum: cache tanpa batas
Cache hasil query yang tidak pernah dibersihkan
→ cache TTL / LRU, hapus entri lama

Mengukur Memori

  • Electron/Tauri (Chromium): DevTools → Performance Monitor → lihat JS heap; --trace-gc untuk GC log. Bandingkan heap setelah sesi panjang.
  • Flutter: DevTools → Memory tab, lihat heap Dart + GC timeline.
  • Rust (Tauri): valgrind --tool=memcheck atau heaptrack untuk leak di sisi Rust.

Note

Aturan praktis: cek memori setelah skenario yang berulang (buka 100 catatan → tutup → buka lagi → tutup). Heap yang terus naik tanpa turun adalah tanda kebocoran. Ingat pula memori di sisi backend: di Electron, main process punya heap sendiri yang juga bisa bocor.

Startup Time

Apa yang Terjadi Saat Aplikasi Dibuka

Startup = waktu dari klik hingga pengguna bisa berinteraksi. Sumber keterlambatan umum:

  • Bekerja berlebihan saat init — membaca semua data, mengindeks, menyambungkan jaringan di awal.
  • Memuat library berat — di-render semuanya padahal belum dipakai.
  • Startup blocker — menunggu sinkronisasi/update sebelum menampilkan UI.

Strategi yang Benar

Strategi startup CatatanKu
1. Tampilkan UI segera dari cache memori (daftar terakhir)
2. Muat data lengkap secara async (episode 9)
3. Defer pekerjaan berat: indexing setelah window interaktif
4. Lazy-load modul/plugin saat benar-benar dipakai
JSElectron: lazy-load modul berat
// ❌ muat semua di awal
const { sqlite } = require("./storage-heavy");
 
// ✅ muat saat dibutuhkan
async function openDatabase() {
  const { openDb } = await import("./storage-heavy");
  return openDb();
}

Di Flutter, pola serupa dengan memindahkan inisialisasi DB/state ke FutureBuilder atau loading screen ringan yang menampilkan cache — bukan memblokir sampai semua siap.

CPU Profiling

Menemukan Titik Panas

Saat UI tersendat, CPU profiler menjawab "siapa yang makan waktu?" — bukan tebakan. Di web stack, Chrome DevTools → Performance; di Flutter, DevTools → CPU profiler.

Alur profiling yang benar
1. Reproduksi skenario (scroll daftar 10.000 catatan)
2. Rekam profil selama 10-30 detik
3. Cari fungsi dengan self-time terbesar
4. Optimasi yang paling besar pengaruhnya
5. Ukur ulang — bandingkan dengan baseline

Optimasi klasik yang sering muncul dari profil CatatanKu:

React: memo list item agar tidak render ulang semua
import { memo } from "react";
 
const NoteRow = memo(function NoteRow({ note }: { note: Note }) {
  return <li>{note.title}</li>;
});
Pola yang wajib dihindari
1. Render ulang seluruh list setiap keystroke pencarian
2. Indexing di thread utama (episode 9)
3. JSON.stringify besar di event handler (event loop macet)

Rendering: GPU dan Reflow

UI yang berat menggambar ulang setiap frame. Hindari menyalakan ulang seluruh panel saat satu item berubah; batasi re-render ke subtree yang berubah. Di Flutter, const constructor dan RepaintBoundary membatasi area repaint. Ukur frame drop (jank) dengan profiler rendering, bukan perasaan.

Profiling Tool per Framework

FrameworkMemoriCPUStartup
ElectronDevTools HeapDevTools Perfchrome://tracing / --profiler
TauriDevTools (webview) + valgrind (Rust)Perf + cargo flamegraphbinary profile (perf/Instruments)
FlutterDevTools MemoryDevTools CPUDevTools Startup (flutter run --profile)

Penutup

Inti yang harus dibawa pulang:

  • Ukur dulu, baru optimasi — metrik, baseline, lalu profiler.
  • Memori: bersihkan listener/interval/timer, batasi cache, pantau heap jangka panjang.
  • Startup: UI segera dari cache, muat async, defer & lazy-load.
  • CPU: profiler menemukan titik panas; optimasi yang diukur ulang, bukan ditebak.
  • Jadikan metrik performa regression guard di CI.

Di episode 17 selanjutnya kita mengotomasi semua kualitas yang sudah dibangun: CI/CD desktop — build matrix OS, signing, dan release automation dengan GitHub Actions. Sampai jumpa di episode 17!

Belajar Desktop Developer - Performance Desktop | Belajar Desktop Developer