What happened

On the WASM/web build, emojis rendered by EmojiText (most visibly ClientScreen’s top-right view-mode/edit-mode/theme-mode toggle buttons) randomly showed as tofu boxes instead of the intended glyph, and a full page reload usually — but not always — fixed it.

Root cause

EmojiSupport.emojiFontFamily (the loaded NotoColorEmoji font family used to style emoji spans on WASM) was a plain var, not Compose snapshot state. EmojiSupport.PreloadEmojiFont() fetches the font asynchronously (Res.readBytes(...) over the network) and assigns it once the fetch resolves. EmojiText reads EmojiSupport.emojiFontFamily at composition time and only applies the emoji font to spans if that value is non-null.

Because the field wasn’t observable, any EmojiText that composed before the async fetch completed captured null and built its AnnotatedString with no emoji-font span. When the fetch later resolved and the var was reassigned, nothing told Compose to invalidate and recompose those already- composed EmojiText instances — they were stuck showing tofu until something else forced a fresh composition. A page refresh often “fixed” it purely because the browser’s HTTP cache made the second fetch resolve before the first composition pass, which is also why the bug looked random rather than consistent.

Fix

Prevention