Generating and importing a large character dictionary froze the whole
app long enough for the compositor to raise its application-not-
responding dialog over the player. Multi-hundred-MB snapshot JSONs and
the merged archive were read, written, and zipped synchronously on the
main process, and the character image / name-candidate caches re-read
every cached snapshot synchronously inside a lookup whenever the
snapshot directory changed.
- snapshot reads/writes are async; writes stream in slices and rename
into place so a crash or concurrent writer cannot tear a snapshot
- buildDictionaryZip yields between ~8MB slices and CRC32 uses the
native zlib implementation
- the image and name-candidate lookup caches rebuild in the background
and serve the previous index while the rebuild runs
Worst main-thread stall over a 1.4GB snapshot set drops from 8s+ to
under 700ms.