diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 0000000..3a9fd3c --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,3 @@ +## 2024-05-24 - WasmJs localStorage JSON parsing overhead +**Learning:** JSON decoding in Kotlin Multiplatform for WasmJs targets carries significant overhead. Parsing the same JSON manifest from localStorage repeatedly causes a measurable performance bottleneck. +**Action:** Use an in-memory cache initialized via `by lazy` to avoid redundant localStorage parsing for frequently accessed metadata like manifests. diff --git a/halogen-engine/src/wasmJsMain/kotlin/halogen/engine/LocalStorageThemeCache.kt b/halogen-engine/src/wasmJsMain/kotlin/halogen/engine/LocalStorageThemeCache.kt index aba1f32..6351715 100644 --- a/halogen-engine/src/wasmJsMain/kotlin/halogen/engine/LocalStorageThemeCache.kt +++ b/halogen-engine/src/wasmJsMain/kotlin/halogen/engine/LocalStorageThemeCache.kt @@ -49,17 +49,21 @@ public class LocalStorageThemeCache( private val json = Json { ignoreUnknownKeys = true } private val manifestKey = "${prefix}__keys__" - // ── Manifest helpers ──────────────────────────────────────────────── - - private fun readManifest(): MutableSet { - val raw = jsGetItem(manifestKey.toJsString())?.toString() ?: return mutableSetOf() - return try { + private val inMemoryManifest: MutableSet by lazy { + val raw = jsGetItem(manifestKey.toJsString())?.toString() ?: return@lazy mutableSetOf() + try { json.decodeFromString>(raw).toMutableSet() } catch (_: Exception) { mutableSetOf() } } + // ── Manifest helpers ──────────────────────────────────────────────── + + private fun readManifest(): MutableSet { + return inMemoryManifest + } + private fun writeManifest(keys: Set) { val encoded = json.encodeToString(keys) jsSetItem(manifestKey.toJsString(), encoded.toJsString()) @@ -154,6 +158,7 @@ public class LocalStorageThemeCache( for (key in manifest) { removeEntry("$prefix$key") } + manifest.clear() jsRemoveItem(manifestKey.toJsString()) _changes.tryEmit(CacheEvent.Cleared) }