Lewati ke konten
RazinSaid

Optimasi Ukuran & Performa Aplikasi Electron

RS
Razin Said
6 menit baca
Bagian 11 dari 12 · Seri Belajar Electron dari Nol sampai Mahir

Cepat atau lambat, urusan optimasi ukuran dan performa bakal kamu temui juga waktu bikin aplikasi Electron. Bayangin aja: installer ratusan megabyte, jendela yang lama kebukanya — pengguna bisa kabur duluan sebelum sempat nyoba aplikasimu. Untungnya, kebanyakan masalah kayak gini nggak butuh nulis ulang aplikasi kok. Kamu cuma perlu tahu di mana titik gemuknya. Nah, kalau kamu udah ngikutin bahasan soal package & distribusi aplikasi Electron, anggap aja artikel ini lanjutannya — kali ini fokusnya ke ukuran sama kecepatan.

Kenapa aplikasi Electron cenderung besar & berat

Akar masalahnya cuma satu: tiap aplikasi Electron itu bawa Chromium dan Node.js sendiri. Jadi sebelum kamu nulis satu baris kode pun, ukuran dasarnya udah puluhan megabyte. Ya mau gimana lagi, itu harga yang harus dibayar — soalnya aplikasimu pada dasarnya adalah sebuah browser mini yang lengkap.

Tapi di luar itu, banyak aplikasi jadi makin gemuk gara-gara hal yang sebenarnya bisa dikontrol. Misalnya seluruh isi folder node_modules ikut kebungkus, file sumber yang berserakan, sampai aset gambar segede gaban. Numpuk semua. Nah, justru bagian "tambahan" inilah yang bisa kamu pangkas. Chromium sih emang nggak bisa dihindari, tapi sisanya masih sangat bisa dirapikan.

Memperkecil ukuran (prod deps saja, asar, files allowlist, bundling)

Yang paling ngefek pertama kali: pastiin cuma dependency produksi yang ikut dikemas. Kuncinya, pisahin dengan benar antara dependencies dan devDependencies di package.json. Tool kayak webpack, esbuild, atau eslint kan cuma dipakai pas build, jadi tempatnya di devDependencies. Enaknya, electron-builder otomatis cuma nyertain dependency produksi waktu ngemas. Jadi begitu pemisahan ini rapi, kamu udah motong banyak berat tanpa usaha tambahan.

{
  "dependencies": {
    "electron-updater": "^6.3.0"
  },
  "devDependencies": {
    "electron": "^31.0.0",
    "electron-builder": "^24.13.3",
    "vite": "^5.4.0"
  }
}

Habis itu, bungkus kode sumbermu ke format asar. Intinya asar itu nggabungin banyak file kecil jadi satu arsip. Dia nggak beneran "ngompres" ya, tapi bikin akses file lebih cepat sekaligus ngerapiin struktur. electron-builder sebenernya udah ngaktifin asar secara default, tapi nggak ada salahnya kamu pastiin sendiri secara eksplisit.

{
  "build": {
    "appId": "com.contoh.app",
    "asar": true
  }
}

Lanjut, manfaatin opsi files sebagai allowlist. Daripada nyomot semua isi proyek, mending sebutin aja yang bener-bener kepakai pas runtime. Cara ini ampuh banget buat nendang README, file test, konfigurasi, sama folder dokumentasi yang suka ikut nyangkut.

{
  "build": {
    "files": [
      "dist/**/*",
      "package.json",
      "!**/*.map",
      "!node_modules/**/{test,__tests__,docs,example,examples}/**"
    ]
  }
}

Terus, jangan lupa perhatiin format installer dan kompresinya. electron-builder ngasih kamu kontrol buat ngatur tingkat kompresi. Pilih maximum, installer-nya bakal lebih kecil — konsekuensinya proses build agak lebih lama dikit. Buat rilis publik sih, ini biasanya sepadan.

{
  "build": {
    "compression": "maximum"
  }
}

Terakhir, bundling kode juga ngebantu banget. Gabungin kode JavaScript kamu pakai bundler kayak esbuild atau Vite. Hasilnya, kode kena tree-shaking, modul yang nggak kepakai dibuang, dan output-nya jadi jauh lebih ramping ketimbang harus bawa ratusan file mentah.

# contoh sederhana memakai esbuild untuk proses main
npx esbuild src/main.js --bundle --platform=node --outfile=dist/main.js

Performa: jangan bebani main process

Oke, ukuran udah rapi. Sekarang giliran ngomongin kecepatan. Aturan emas nomor satu: jangan pernah blok main process. Anggap main process itu otaknya aplikasimu. Kalau dia lagi sibuk ngerjain tugas berat, seluruh jendela ikut nge-freeze dan berasa "nggantung".

Makanya, tugas berat kayak proses file gede, parsing data segunung, atau enkripsi mending dipindahin ke tempat lain. Kamu bisa pakai worker_threads bawaan Node atau jalanin child process. Dengan gitu, komputasi beratnya jalan terpisah dan UI tetep responsif.

const { Worker } = require('worker_threads')

function jalankanTugasBerat(data) {
  return new Promise((resolve, reject) => {
    const worker = new Worker('./worker-tugas.js', { workerData: data })
    worker.on('message', resolve)
    worker.on('error', reject)
  })
}

Prinsipnya gampang kok: main process itu buat koordinasi, bukan buat kerja otot. Biarin dia tetep ringan, biar respons aplikasimu berasa instan.

Optimasi startup & lazy load

Kesan pertama pengguna itu dari seberapa cepat aplikasimu kebuka. Jadi, kurangin kerjaan pas startup. Nggak usah muat semua modul, baca semua file, dan nyiapin semua fitur sekaligus di awal. Kenyataannya, banyak hal yang sebenernya belum dibutuhin sampai penggunanya beneran makai.

Di sisi UI, terapin lazy load. Bagian yang berat — misalnya editor, grafik, atau panel pengaturan — baru di-load pas dibuka. Bundler modern udah support ini lewat dynamic import.

// modul berat baru di-load saat tombol ditekan
tombol.addEventListener('click', async () => {
  const { bukaEditor } = await import('./editor.js')
  bukaEditor()
})

Di sisi main process, tunda hal-hal yang nggak mendesak. Misalnya ngecek update atau nyambung ke layanan eksternal — nggak perlu langsung jalan begitu jendela muncul. Kasih jeda dikit biar jendelanya nongol dulu, baru deh tugas latar belakang nyusul. Pengguna bakal ngerasa aplikasimu "langsung siap".

Satu lagi: perhatiin berapa banyak BrowserWindow yang kamu buka. Tiap jendela itu proses renderer sendiri-sendiri yang makan memori dan CPU. Kalau masih bisa diakalin pakai satu jendela dengan beberapa tampilan, itu jauh lebih hemat daripada buka banyak jendela barengan.

Menjaga penggunaan memori

Memory leak itu musuh yang diam-diam. Gejalanya khas: aplikasi berasa enteng pas baru dibuka, tapi makin lama dipakai malah makin lemot. Biang keroknya yang paling sering? Listener yang nggak pernah dilepas.

Tiap kali kamu masang listener event — entah di main process atau renderer — pastiin kamu juga ngelepasnya waktu udah nggak dibutuhin. Soalnya listener yang numpuk bakal terus nahan objek di memori, jadinya nggak bisa dibersihin.

function pasangListener(win) {
  const handler = () => console.log('jendela fokus')
  win.on('focus', handler)

  // lepas saat jendela ditutup agar tidak menumpuk
  win.on('closed', () => {
    win.removeListener('focus', handler)
  })
}

Hal yang sama berlaku buat timer, interval, sama subscription IPC. Bersihin pas komponen atau jendelanya ditutup. Selain itu, hindari nyimpen referensi gede yang sebenernya udah nggak kepakai — kayak buffer data raksasa yang masih dipegang variabel global. Kebiasaan kecil kayak gini yang bikin memori tetep stabil walau dipakai lama.

Cara mengukur (DevTools & process metrics)

Jangan main tebak-tebakan, mending diukur. Electron punya Task Manager bawaan yang nampilin tiap proses lengkap sama pemakaian memori dan CPU-nya. Ini cara paling cepet buat ngeliat jendela atau proses mana yang paling rakus.

const { app, Menu } = require('electron')
// buka Task Manager bawaan Electron lewat menu aplikasi, atau panggil secara programatik
app.on('browser-window-created', () => {
  // pada build dev, kamu bisa membuka DevTools untuk profiling renderer
})

Buat renderer, pakai DevTools — persis kayak di Chrome. Tab Performance ngebantu kamu bedah waktu render, sementara tab Memory bisa ngambil snapshot heap buat ngelacak kebocoran. Kalau satu snapshot terus membengkak tiap kali kamu ngulang aksi yang sama, kemungkinan besar ada yang nggak kebersihin.

Kamu juga bisa baca metrik proses secara programatik lewat app.getAppMetrics(). Fungsi ini ngebalikin daftar proses lengkap sama pemakaian CPU dan memorinya — kepake banget buat logging atau mantau kondisi aplikasi pas udah di tangan pengguna.

const { app } = require('electron')

setInterval(() => {
  const metrik = app.getAppMetrics()
  metrik.forEach((p) => {
    console.log(p.type, Math.round(p.memory.workingSetSize / 1024), 'MB')
  })
}, 10000)

Dengan data beneran di tangan, kamu bisa mrioritasin perbaikan yang paling ngefek, bukan sekadar ngikutin feeling.

Kesimpulan

Optimasi Electron itu soal kebiasaan, bukan trik ajaib. Buat mangkas ukuran: pisahin dependency produksi, aktifin asar, atur allowlist files, dan bundle kodemu. Buat performa: jaga main process biar tetep ringan, tunda kerjaan pas startup, lazy-load bagian yang berat, dan rapiin listener biar memori nggak bocor. Terus, biasain selalu ukur pakai Task Manager bawaan sama DevTools — sebelum dan sesudah tiap perubahan.

Nah, kalau setelah semua usaha ini aplikasimu masih berasa kelewat berat buat kebutuhanmu, mungkin ini saatnya nimbang alternatif lain. Lanjut aja ke bab pamungkas seri ini, Electron vs Tauri: pilih mana, buat ngebandingin plus-minus keduanya. Atau kamu bisa balik ke halaman seri Belajar Electron kalau mau ngulang bab-bab sebelumnya.

Bagikan: XWhatsAppFacebookLinkedIn

Artikel terkait