Membangun aplikasi offline-first di React Native membutuhkan strategi resolusi konflik data saat perangkat tersambung kembali ke jaringan. Dua pendekatan dominan untuk menyelesaikan konflik state terdistribusi ini adalah Conflict-free Replicated Data Types (CRDT) dan Last-Write-Wins (LWW). Pemilihan antara keduanya berdampak langsung pada performa JavaScript runtime Hermes, frame rate tampilan, konsumsi baterai, serta arsitektur storage backend.

Karakteristik Mekanisme Resolusi

LWW menyelesaikan konflik dengan membandingkan timestamp mutasi. State dengan timestamp paling baru menimpa state lama. Pendekatan ini deterministik dan cepat, namun rentan kehilangan data (data loss) akibat penimpaan mutasi konkuren (silent overwrites).

CRDT menyelesaikan konflik secara matematis menggunakan semantik semilattice join (monotonik naik) tanpa kehilangan data. Setiap perubahan diperlakukan sebagai operasi penambahan atau pembaruan berbasis identitas unik node. Kompleksitas komputasi dan metadata berpindah sepenuhnya ke penyimpanan dan eksekusi lokal.

Analisis Performa Client: Hermes Engine, RAM, dan Baterai

React Native menjalankan logika aplikasi di atas JavaScript engine Hermes. Karakteristik single-thread pada thread JavaScript menjadikan performa merge algoritma sinkronisasi krusial terhadap kestabilan antarmuka pengguna.

Beban CPU Hermes

Pada LWW, operasi merge bernilai O(1) per atribut. Hermes hanya melakukan perbandingan numerik antar integer/string timestamp lalu mengeksekusi mutasi baris di local storage (seperti SQLite atau MMKV).

Pada CRDT (khususnya Operation-based atau Delta-state CRDT), proses integrasi state memerlukan traversal graf atau sorting vector clock. Hermes harus mengevaluasi array metadata yang besar. Komputasi rekursif berulang membebani runtime JS, memicu Garbage Collection (GC) pauses berkala yang membekukan thread eksekusi.

Footprint Memori dan Konsumsi Baterai

CRDT membutuhkan alokasi memori substansial untuk menyimpan metadata history, identifier node, dan tombstones (penanda entitas yang telah dihapus). Pada perangkat low-end Android, akumulasi ribuan tombstones di memori JavaScript dapat memicu Out Of Memory (OOM) crash.

Aktivitas CPU yang intensif saat parsing delta payload berukuran megabyte di thread JS juga mencegah CPU masuk ke low-power mode, mempercepat pengeringan daya baterai saat sinkronisasi massal.

Mitigasi Frame Drop di UI Thread React Native

Karena arsitektur React Native mengeksekusi JavaScript di satu thread terpisah (sebelum dikirim ke thread render via Fabric/Shadow Tree), pemblokiran JS thread oleh sinkronisasi berat tetap menyebabkan degradasi interaksi: gesture membeku, animasi terputus, dan touch event tertunda.

Terapkan pola berikut untuk mengisolasi operasi merge:

  1. Chunking via InteractionManager: Pecah delta state sinkronisasi menjadi batch kecil dan jadwalkan eksekusi setelah transisi layar selesai menggunakan InteractionManager.runAfterInteractions atau requestIdleCallback polyfill.
  2. Off-JS-Thread Processing (Native JSI): Pindahkan logika merge CRDT dari Hermes ke native C++ layer via React Native JSI (JavaScript Interface). Integrasikan engine seperti Y-CRDT (Rust/C++) atau Automerge Core (C via JSI bindings). Algoritma merge berjalan di thread latar belakang OS (worker thread) tanpa membebani Hermes.

Dampak Backend: Penyimpanan Metadata vs Mitigasi Clock Drift

Backend CRDT: Masalah Tombstone Bloat

Dalam CRDT, data tidak boleh langsung dihapus fisik (hard delete) secara terdistribusi karena node yang offline dapat mengirimkan kembali state lama tersebut. Solusinya menggunakan tombstone. Konsekuensi operasional backend:

  • Storage database membengkak secara eksponensial seiring tingginya mutasi delete.
  • Diperlukan protokol Garbage Collection Tombstone terdistribusi. Backend harus mengetahui batas minimal vector clock (stable checkpoint) yang sudah diterima oleh seluruh node sebelum membersihkan tombstone secara aman.

Backend LWW: Masalah Clock Drift

LWW bergantung pada keandalan waktu. Jam lokal pada perangkat mobile rentan terhadap clock drift, manipulasi manual oleh user, atau desinkronisasi NTP (Network Time Protocol). Timestamp lokal murni tidak dapat dipercaya untuk konsistensi kausal.

Mitigasi clock drift pada LWW:

  • Hybrid Logical Clocks (HLC): Gabungkan physical timestamp dengan counter logical untuk menjamin urutan kausalitas bahkan ketika physical clock melenceng mundur.
  • Server-Authoritative Ordering: Klien mencatat urutan lokal sementara, namun backend menetapkan sequence ID atau server timestamp saat payload pertama kali mencapai ingestion gateway.

Implementasi Minimal Struktur Payload Sinkronisasi

Berikut adalah perbandingan skema payload JSON minimal antara LWW berbasis HLC dan Delta-State CRDT.

Payload LWW dengan Hybrid Logical Clock (HLC)

interface LWWPayload {
  entityId: string;
  table: string;
  data: Record<string, unknown>;
  // Format HLC: "<physical_millis>:<logical_counter>:<client_id>"
  hlc: string;
  isDeleted: boolean;
}

// Logika komparasi mutasi LWW di SQLite
function shouldApplyMutation(incomingHLC: string, currentHLC: string | null): boolean {
  if (!currentHLC) return true;
  return incomingHLC > currentHLC;
}

Payload Delta-State CRDT (LWW-Element-Set)

interface CRDTActor {
  clientId: string;
  seq: number;
}

interface CRDTExtensibleRegister {
  field: string;
  value: unknown;
  clock: Record<string, number>; // Vector Clock
  updatedAt: number;
}

interface CRDTDeltaPayload {
  documentId: string;
  // Metadata mutasi per-field untuk menghindari penimpaan seluruh record
  fields: CRDTExtensibleRegister[];
  // Identitas baris yang dihapus beserta bukti kausalitas
  tombstones: {
    field: string;
    clock: Record<string, number>;
    deletedAt: number;
  }[];
}

Maintainability, Migrasi Skema, dan Debugging

Skema Migrasi

Pada LWW yang diimplementasikan di atas SQLite lokal (seperti WatermelonDB atau op-sqlite), migrasi skema berjalan standar menggunakan statement ALTER TABLE atau data transformation script. Pemetaan skema antar-versi mudah diselaraskan.

Pada CRDT, perubahan skema dokumen kompleks. Jika versi aplikasi klien berbeda, perubahan tipe data (misal: string menjadi object) dapat merusak fungsi join semilattice. Migrasi memerlukan adapter backward-compatible pada level decoding delta binary.

Debugging Desinkronisasi

Debugging LWW mudah: bandingkan record database lokal klien dengan snapshot PostgreSQL backend menggunakan SQL query sederhana. Jika ada selisih, identifikasi nilai timestamp.

Debugging CRDT membutuhkan penelusuran seluruh riwayat mutation dag/vector log. Ketika dua klien menunjukkan output visual berbeda pada dokumen yang sama, engineer harus mengekstraksi raw binary state vektor untuk menganalisis missing causal updates.

Matriks Keputusan Arsitektur

Kriteria EvaluasiLast-Write-Wins (LWW)CRDT (State / Op-based)
Overhead CPU HermesMinimal (operasi primitif O(1))Tinggi (graf parsing, array search)
Beban RAM ClientRendah (hanya state aktual)Tinggi (state + history + tombstone)
Toleransi Konflik DataRendah (terjadi silent overwrite)Sempurna (zero data loss)
Kompleksitas BackendRendah (standar RDBMS)Tinggi (log compaction, storage bloat)
Mitigasi TimestampWajib HLC / Server IngestionOtomatis via Vector Clocks
Kesesuaian PenggunaanCRUD bisnis, formulir, e-commerceText editor kolaboratif, canvas, kanban multi-user

Gunakan LWW dengan Hybrid Logical Clock untuk mayoritas aplikasi mobile bisnis yang dominan operasi CRUD discrete. Alokasikan resource untuk mengadopsi CRDT hanya jika domain aplikasi menuntut kolaborasi real-time tanpa hierarki sentral (seperti text editor atau collaborative whiteboard) di mana kehilangan satu mutasi konkuren tidak dapat ditoleransi oleh bisnis.