AizuDemy

SQLite WASM & OPFS: Storage Browser Performa Tinggi Off-Grid

IKLAN
IDCloudHost
๐ŸŽง
Dengarkan Artikel Ini
Suara AI Otomatis โ€ข 3 mnt baca baca
โšก TL;DR

Poin Kunci Artikel Ini:

  • Aplikasi Web Offline Lemot Saat Data Banyak?Buat aplikasi Kasir (POS) atau manajemen proyek offline-first.
  • Data naik 50.000 baris, UI patah, cari teks lambat, browser macet.Penyebab: storage bawaan browser terbatas.
  • Solusi: WebAssembly (WASM) + Origin Private File System (OPFS).
๐Ÿ“‹ Daftar Isi Materi Tutup โ–ด

Aplikasi Web Offline Lemot Saat Data Banyak?

Buat aplikasi Kasir (POS) atau manajemen proyek offline-first. Awal lancar dengan 50 data. Data naik 50.000 baris, UI patah, cari teks lambat, browser macet.

Penyebab: storage bawaan browser terbatas. Solusi: WebAssembly (WASM) + Origin Private File System (OPFS). Jalankan SQL relasional langsung di browser. Kecepatan baca-tulis dekat native.

IndexedDB Lambat, SQLite WASM + OPFS Lahir

IndexedDB biasa dipakai simpan data browser. Data besar, IndexedDB lambat:

  • Tanpa Query Declarative: Iterasi cursor manual buat filter atau JOIN. Lambat.
  • Overhead Asinkronus: Tiap IO pemicu event loop. Ubah ribuan data kunci main thread JS.
  • Indexing Terbatas: Indeks IndexedDB jauh lebih lambat dari mesin SQL SQLite.

IndexedDB seperti lemari arsip fisik. Cari file harus buka laci satu per satu. SQLite WASM di OPFS seperti mesin pencari digital cepat di ruang kerja tertutup.

OPFS (Origin Private File System) bagian File System Access API. Sediakan akses file privat cepat khusus origin web. SQLite + WASM tulis raw bytes langsung ke disk privat browser via synchronous access handle.

Setup WebWorker, Inisialisasi SQLite WASM & Integrasi OPFS

Operasi database berat wajib di Web Worker. Main thread bebas, UI tidak macet.

1. Instalasi Library

Pasang paket SQLite WASM via npm:

npm install @sqlite.org/sqlite-wasm

2. Membuat Web Worker (db.worker.js)

Buat file db.worker.js. Worker memuat SQLite, buka database OPFS, tangani pesan UI main thread.

import { sqlite3Worker1Promiser } from '@sqlite.org/sqlite-wasm';

let dbInstance = null;

async function initDatabase() {
  try {
    const sqlite3 = await sqlite3Worker1Promiser.v2();
    
    await sqlite3({
      type: 'open',
      filename: 'file:aplikasi_kita.sqlite3?vfs=opfs',
    });

    console.log('SQLite WASM + OPFS siap!');
    
    await sqlite3({
      type: 'exec',
      sql: `CREATE TABLE IF NOT EXISTS produk (
              id INTEGER PRIMARY KEY AUTOINCREMENT,
              nama TEXT NOT NULL,
              harga REAL NOT NULL,
              stok INTEGER DEFAULT 0
            );`
    });

  } catch (err) {
    console.error('Gagal memuat SQLite WASM:', err);
  }
}

self.onmessage = async (event) => {
  const { action, payload } = event.data;
  
  if (action === 'INIT') {
    await initDatabase();
    self.postMessage({ status: 'READY' });
  }
};

3. Menghubungkan Main Thread dengan Worker

Panggil worker dari main thread (app.js atau komponen React/Vue). UI lancar.

const worker = new Worker(new URL('./db.worker.js', import.meta.url), {
  type: 'module'
});

worker.onmessage = (e) => {
  if (e.data.status === 'READY') {
    console.log('Database siap transaksi!');
  }
};

worker.postMessage({ action: 'INIT' });

Handling Concurrency, Migrasi Schema, dan Header COOP/COEP

1. Konfigurasi Header Keamanan Browser (COOP & COEP)

OPFS butuh SharedArrayBuffer. Server wajib kirim dua HTTP header ini:

  • Cross-Origin-Opener-Policy: same-origin
  • Cross-Origin-Embedder-Policy: require-corp

Setting di vite.config.js:

export default {
  server: {
    headers: {
      'Cross-Origin-Opener-Policy': 'same-origin',
      'Cross-Origin-Embedder-Policy': 'require-corp',
    },
  },
};

2. Concurrency & Penguncian Berkas

OPFS kunci file eksklusif saat access handle buka. Dua tab buka bersamaan tidak bisa tulis OPFS sama tanpa koordinasi.

Solusi:

  • Single Worker Thread: Gunakan satu Web Worker terpusat atau SharedWorker antar tab.
  • Queue Pattern: Antrekan SQL query di worker. Eksekusi berurutan.

3. Skema Migrasi Database

Database SQLite di browser permanen. Perubahan tabel butuh migrasi. Gunakan PRAGMA user_version.

async function runMigrations(sqlite3) {
  const result = await sqlite3({
    type: 'exec',
    sql: 'PRAGMA user_version;',
    returnValue: 'resultRows'
  });

  let currentVersion = result.resultRows[0][0];

  if (currentVersion < 1) {
    await sqlite3({
      type: 'exec',
      sql: `
        CREATE TABLE transaksi (
          id TEXT PRIMARY KEY,
          total REAL,
          created_at DATETIME DEFAULT CURRENT_TIMESTAMP
        );
        PRAGMA user_version = 1;
      `
    });
    console.log('Migrasi versi 1 selesai.');
  }
}

Pilih Storage Mana?

  • Pakai IndexedDB jika: Simpan data simpel, config, status UI, data key-value kecil.
  • Pakai SQLite WASM + OPFS jika: App enterprise, POS offline, olah dokumen/catatan lokal, pustaka media, puluhan ribu data relasional di client.

Kesimpulan

SQLite WASM + OPFS buat browser cepat. Tidak terbatas storage bawaan lambat saat olah data berat offline.

Coba sekarang: pindahkan query lambat ke SQLite WASM Web Worker. Performa naik instan.

A
Aizu Dev

Tim penulis AizuDemy yang menyajikan tutorial teknologi, cloud, dan pengembangan perangkat lunak dalam Bahasa Indonesia.

๐Ÿ“– Artikel Terkait