Belajar Capacitorjs - Performance Optimization
Episode 16 of 28

Belajar Capacitorjs - Performance Optimization

Optimasi startup time, ukuran bundle, animasi 60fps di WebView, gambar & font loading, profiling dengan Chrome DevTools remote & Safari Web Inspector, serta praktik mengurangi cold start dan jank pada aplikasi contoh.

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

Pendahuluan

Setelah di episode 15 kita memilih framework UI dan membangun layout mobile, pada episode ini kita fokus ke performance — topik yang sering diabaikan sampai user mulai komplain. Aplikasi yang lambat di mobile akan di-uninstall dalam hitungan detik.

Mengapa performance penting? Karena di mobile, resource terbatas (CPU, RAM, baterai) dan user sangat sensitif terhadap lag. Aplikasi web yang berjalan di WebView memiliki tantangan performance unik dibanding native app.

Startup Time

Cold Start vs Warm Start

  • Cold start: app di-launch dari nol (pertama kali atau setelah killed). Target: ≤ 2 detik.
  • Warm start: app di-resume dari background. Target: ≤ 500ms.

Mengurangi Cold Start

Lazy loading komponen
import { lazy, Suspense } from 'react';
 
// Load komponen hanya saat dibutuhkan
const HeavyComponent = lazy(() => import('./HeavyComponent'));
 
function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <HeavyComponent />
    </Suspense>
  );
}

Strategi lain:

  • Preload critical resources: gunakan <link rel="preload"> untuk font dan CSS kritis.
  • Code splitting: gunakan dynamic import() untuk route-based splitting.
  • Minimize bundle: pastikan build production menghilangkan dead code.
  • Cache service worker: untuk load ulang yang cepat.

Ukuran Bundle

Analisis Bundle

Analisis bundle size
npx vite-bundle-visualizer
# atau untuk webpack
npx webpack-bundle-analyzer stats.json

Strategi Reduksi

Tree shaking dan dynamic import
// Jangan import seluruh library
import { format } from 'date-fns'; // tree-shakeable
 
// Gunakan dynamic import untuk route
const SettingsPage = lazy(() => import('./pages/Settings'));
 
// Gunakan URL untuk asset besar
const heavyData = new URL('./data.json', import.meta.url);

Target Bundle Size

KategoriTarget
App shell≤ 200 KB
Route per halaman≤ 50 KB
Total initial load≤ 500 KB
Image per-load≤ 200 KB (compressed)

Animasi 60fps di WebView

Gunakan CSS Transforms

CSSAnimasi performa tinggi
.animated-element {
  /* Gunakan transform, bukan top/left/margin */
  transform: translateY(100px);
  transition: transform 0.3s ease-out;
 
  /* Hindari paint yang mahal */
  will-change: transform;
}
 
/* Hindari ini */
.bad-animation {
  top: 100px; /* triggering layout */
  margin-top: 100px; /* triggering layout */
}

Gunakan requestAnimationFrame

Animasi smooth dengan RAF
function animateScroll(element: HTMLElement, targetY: number) {
  const startY = element.scrollTop;
  const diff = targetY - startY;
  const duration = 300;
  let startTime: number | null = null;
 
  function step(timestamp: number) {
    if (!startTime) startTime = timestamp;
    const progress = Math.min((timestamp - startTime) / duration, 1);
 
    // Easing function
    const ease = 1 - Math.pow(1 - progress, 3);
    element.scrollTop = startY + diff * ease;
 
    if (progress < 1) {
      requestAnimationFrame(step);
    }
  }
 
  requestAnimationFrame(step);
}

Tip

Gunakan Chrome DevTools Performance tab untuk merekam animasi dan memeriksa frame rate. Jika frame rate turun di bawah 60fps, cari layout thrashing atau repaint yang mahal.

Profiling

Chrome DevTools Remote (Android)

  1. Buka Chrome di komputer.
  2. Navigasi ke chrome://inspect/#devices.
  3. Pastikan emulator/device terhubung via ADB.
  4. Klik "inspect" pada WebView yang sesuai.

Dari sini kalian bisa menggunakan Network, Performance, dan Memory tabs untuk profiling.

Safari Web Inspector (iOS)

  1. Buka Safari di macOS.
  2. Safari → Preferences → Advanced → "Show Develop menu".
  3. Buka Simulator iOS, buka app kalian.
  4. Safari → Develop → Simulator → WebView.

Safari Web Inspector memberikan akses ke DOM, Console, Network, dan Timeline.

Native Profiling

Untuk bottleneck di bridge layer:

  • iOS: Xcode Instruments (Time Profiler, Allocations).
  • Android: Android Studio Profiler (CPU, Memory).

Jika profiling menunjukkan bottleneck di native code (bukan JavaScript), kalian mungkin perlu optimasi plugin native — topik yang dibahas di episode 12.

Gambar dan Font Loading

Gambar

HTMLGambar optimized
<!-- Gunakan format modern -->
<picture>
  <source srcset="image.avif" type="image/avif" />
  <source srcset="image.webp" type="image/webp" />
  <img src="image.jpg" alt="Description" loading="lazy" />
</picture>

Font

CSSFont loading optimized
/* Preload font kritis */
@font-face {
  font-family: 'Inter';
  src: url('/fonts/inter-latin.woff2') format('woff2');
  font-display: swap;
  unicode-range: U+0000-007F; /* Latin only */
}

Note

Font loading di WebView bisa menjadi bottleneck pertama. Gunakan font-display: swap agar teks langsung muncul dengan fallback, lalu swap ke custom font saat loaded.

Penutup

Pada episode 16 ini, kalian telah memahami:

  • Cold start target ≤ 2 detik dengan lazy loading dan code splitting.
  • Bundle analysis dan strategi reduksi ukuran.
  • Animasi performa tinggi: CSS transforms + requestAnimationFrame.
  • Profiling: Chrome DevTools remote (Android), Safari Web Inspector (iOS).
  • Optimasi gambar dan font loading untuk WebView.

Di episode 17 selanjutnya, kita akan membahas offline-first architecture — cache-first vs network-first, service worker vs storage native, SQLite community plugin, dan praktik fitur CRUD yang tetap berfungsi tanpa jaringan. Sampai jumpa!

Belajar Capacitorjs - Performance Optimization | Belajar Capacitorjs