Cara Kerja Wails
Memahami arsitektur Wails dan caranya mencapai performa native
Wails adalah kerangka kerja untuk membangun aplikasi desktop dengan Go sebagai backend dan teknologi web sebagai frontend. Namun, tidak seperti Electron, Wails tidak menyertakan browser—Wails menggunakan WebView native milik sistem operasi.
Perbedaan utama dari Electron:
| Aspek | Wails | Electron |
|---|---|---|
| Browser | WebView yang disediakan OS | Chromium yang disertakan (~100MB) |
| Backend | Go (dikompilasi) | Node.js (diinterpretasikan) |
| Komunikasi | Bridge dalam memori | IPC (antarproses) |
| Ukuran Bundel | ~15MB | ~150MB |
| Memori | ~10MB | ~100MB+ |
| Waktu mulai | <0.5s | 2-3s |
Komponen Inti
1. WebView Native
Wails menggunakan mesin perender web bawaan sistem operasi:
WebView2 (Microsoft Edge WebView2)
- Berbasis Chromium (sama seperti browser Edge)
- Sudah terinstal di Windows 10/11
- Pembaruan otomatis melalui Windows Update
- Dukungan penuh untuk standar web modern
WebKit (mesin perender Safari)
- Terintegrasi dalam macOS
- Mesin yang sama dengan browser Safari
- Performa dan daya tahan baterai yang sangat baik
- Dukungan penuh untuk standar web modern
WebKitGTK (port GTK dari WebKit)
- Diinstal melalui pengelola paket
- Mesin yang sama dengan GNOME Web (Epiphany)
- Dukungan standar yang baik
- Ringan dan berperforma tinggi
Mengapa hal ini penting:
- Tanpa browser yang disertakan → Ukuran aplikasi lebih kecil
- Native pada OS → Integrasi dan performa lebih baik
- Pembaruan otomatis → Patch keamanan dari pembaruan OS
- Perenderan yang familier → Sama seperti browser sistem
2. Bridge Wails
Bridge adalah inti Wails—komponen ini memungkinkan komunikasi langsung antara Go dan JavaScript.
Cara kerjanya:
- Frontend memanggil metode Go (melalui binding yang dibuat otomatis)
- Bridge mengodekan pemanggilan ke JSON (nama metode + argumen)
- Router menemukan metode Go dalam layanan yang terdaftar
- Metode Go dijalankan dan mengembalikan nilai
- Bridge mendekode hasil dan mengirimkannya kembali ke frontend
- Promise diselesaikan di JavaScript dengan hasil tersebut
Karakteristik performa:
- Dalam memori: Tanpa overhead jaringan, tanpa HTTP
- Tanpa penyalinan jika memungkinkan (untuk data berukuran besar)
- Asinkron secara default: Tidak memblokir di kedua sisi
- Aman secara tipe: Definisi TypeScript dibuat otomatis
3. Sistem Layanan
Layanan adalah cara yang direkomendasikan untuk mengekspos fungsionalitas Go ke frontend.
// Define a service (just a regular Go struct)
type GreetService struct {
prefix string
}
// Methods with exported names are automatically available
func (g *GreetService) Greet(name string) string {
return g.prefix + name + "!"
}
func (g *GreetService) GetTime() time.Time {
return time.Now()
}
// Register the service
app := application.New(application.Options{
Services: []application.Service{
application.NewService(&GreetService{prefix: "Hello, "}),
},
})Penemuan layanan:
- Wails memindai struct Anda saat mulai dijalankan
- Metode yang diekspor dapat dipanggil dari frontend
- Informasi tipe diekstrak untuk binding TypeScript
- Penanganan kesalahan berlangsung otomatis (error Go → exception JS)
Binding TypeScript yang dihasilkan:
// Auto-generated in frontend/bindings/GreetService.ts
export function Greet(name: string): Promise<string>
export function GetTime(): Promise<Date>Mengapa menggunakan layanan?
- Aman terhadap tipe: Dukungan penuh untuk TypeScript
- Penemuan otomatis: Tidak perlu mendaftarkan metode secara manual
- Terorganisasi: Kelompokkan fungsionalitas yang terkait
- Dapat diuji: Layanan hanyalah struct Go
Pelajari layanan lebih lanjut →
4. Sistem Peristiwa
Peristiwa memungkinkan komunikasi publikasi/langganan antarkomponen.
Kasus penggunaan:
- Komunikasi antarjendela: Satu jendela memberi tahu jendela lainnya
- Tugas latar belakang: Layanan Go memberi tahu UI tentang progres
- Sinkronisasi status: Jaga agar beberapa jendela tetap sinkron
- Kopling longgar: Komponen tidak memerlukan referensi langsung
Contoh:
// Go: Emit an event
app.Event.Emit("user-logged-in", user)// JavaScript: Listen for event
import { Events } from '@wailsio/runtime'
Events.On('user-logged-in', (user) => {
console.log('User logged in:', user)
})Pelajari peristiwa lebih lanjut →
Siklus Hidup Aplikasi
Memahami siklus hidup membantu Anda mengetahui kapan harus menginisialisasi dan membersihkan sumber daya.
Hook siklus hidup:
app := application.New(application.Options{
Name: "My App",
// Cleanly intercept quit requests (e.g. unsaved changes).
ShouldQuit: func() bool { return true },
// Called when the app is confirmed to be quitting — save state, close connections, etc.
OnShutdown: func() {},
})Tidak ada bidang OnStartup pada application.Options. Pekerjaan saat startup harus ditempatkan dalam ServiceStartup(ctx, options) milik layanan, dalam callback yang didaftarkan melalui app.Event.OnApplicationEvent(events.Common.ApplicationStarted, ...), atau cukup dijalankan sebelum app.Run().
Pelajari siklus hidup lebih lanjut →
Proses Build
Memahami cara Wails mem-build aplikasi Anda:
Langkah-langkah build:
- Analisis kode Go
- Pindai metode yang diekspor dalam layanan
- Ekstrak tipe parameter dan nilai kembalian
- Buat signature metode
- Buat binding TypeScript
- Buat file
.tsuntuk setiap layanan - Sertakan definisi tipe lengkap
- Tambahkan komentar JSDoc
- Bangun frontend
- Jalankan bundler Anda (Vite, webpack, dan sebagainya)
- Minifikasi dan optimalkan
- Keluarkan hasil ke
frontend/dist/
- Kompilasi Go
- Kompilasi dengan pengoptimalan (
-ldflags="-s -w") - Sertakan metadata build
- Kompilasi khusus platform
- Sematkan aset
- Sematkan file frontend ke dalam biner Go
- Kompres aset
- Buat satu file yang dapat dieksekusi
Hasil: Satu file native yang dapat dieksekusi dengan semua komponen tertanam di dalamnya.
Pelajari proses build lebih lanjut →
Pengembangan vs Produksi
Wails berperilaku berbeda dalam lingkungan pengembangan dan produksi:
Karakteristik:
- Hot reload: Perubahan frontend langsung dimuat ulang
- Source map: Lakukan debugging menggunakan kode sumber asli
- DevTools: DevTools browser tersedia
- Pencatatan log: Pencatatan log mendetail diaktifkan
- Frontend eksternal: Disajikan dari server pengembangan (Vite)
Cara kerjanya:
Manfaat:
- Umpan balik seketika atas perubahan
- Kemampuan debugging lengkap
- Iterasi lebih cepat
Karakteristik:
- Aset tertanam: Frontend disertakan dalam biner saat build
- Dioptimalkan: Diminifikasi dan dikompresi
- Tanpa DevTools: Dinonaktifkan secara default
- Pencatatan log minimal: Hanya kesalahan
- Satu file: Semuanya terdapat dalam satu file yang dapat dieksekusi
Cara kerjanya:
Manfaat:
- Distribusi dalam satu file
- Ukuran lebih kecil (diminifikasi)
- Performa lebih baik
- Tanpa dependensi eksternal
Model Memori
Memahami penggunaan memori membantu Anda membangun aplikasi yang efisien.
Wilayah memori:
- Heap Go
- Layanan dan status aplikasi Anda
- Dikelola oleh pengumpul sampah Go
- Biasanya 5-10 MB untuk aplikasi sederhana
- Memori WebView
- DOM, heap JavaScript, CSS
- Dikelola oleh mesin WebView
- Biasanya 10-20 MB untuk aplikasi sederhana
- Memori Bridge
- Buffer pesan untuk komunikasi
- Overhead minimal (<1 MB)
- Tanpa penyalinan untuk data berukuran besar jika memungkinkan
Tips pengoptimalan:
- Hindari transfer data berukuran besar: Teruskan ID, ambil detail sesuai kebutuhan
- Gunakan event untuk pembaruan: Jangan lakukan polling dari frontend
- Streaming file berukuran besar: Jangan muat seluruhnya ke dalam memori
- Bersihkan listener: Hapus event listener setelah selesai
Pelajari lebih lanjut tentang performa →
Model Keamanan
Wails menyediakan arsitektur yang aman secara bawaan:
Fitur keamanan:
- Daftar putih metode
- Hanya metode yang diekspor yang dapat dipanggil
- Metode privat tidak dapat diakses
- Pendaftaran layanan secara eksplisit diperlukan
- Validasi tipe
- Argumen diperiksa berdasarkan tipe Go
- Tipe yang tidak valid ditolak
- Mencegah serangan injeksi
- Tanpa eval()
- Frontend tidak dapat menjalankan kode Go arbitrer
- Hanya metode yang telah ditentukan sebelumnya yang dapat dipanggil
- Tidak ada eksekusi kode dinamis
- Isolasi konteks
- Setiap jendela memiliki konteksnya sendiri
- Layanan dapat memeriksa konteks pemanggil
- Izin per jendela dapat diterapkan
Praktik terbaik:
- Validasi input pengguna di Go (jangan percayai frontend)
- Gunakan konteks untuk autentikasi/otorisasi
- Sanitasi jalur file sebelum operasi file
- Batasi laju operasi yang mahal
Pelajari lebih lanjut tentang keamanan →
Langkah Berikutnya
Siklus Hidup Aplikasi - Pahami proses startup, shutdown, dan hook siklus hidup Pelajari Lebih Lanjut →
Bridge Go-Frontend - Pelajari secara mendalam cara kerja bridge Pelajari Lebih Lanjut →
Sistem Build - Pahami cara Wails membangun aplikasi Anda Pelajari Lebih Lanjut →
Mulai Membangun - Terapkan yang telah Anda pelajari dalam tutorial Tutorial →
Ada pertanyaan tentang arsitektur? Tanyakan di Discord atau lihat referensi API.