Skip to content

Kotlin-compose: update to Compose 1.13.0-beta01 and Kotlin 2.4.20 - #331

Open
danleh wants to merge 1 commit into
WebKit:mainfrom
danleh:wasm-kotlin-compose-update
Open

danleh wants to merge 1 commit into
WebKit:mainfrom
danleh:wasm-kotlin-compose-update

Conversation

@danleh

@danleh danleh commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Part of #277. cc @bashor @eymar @terrakok

Build the Compose Multiplatform benchmarks from upstream master (1574503571) instead of the JetStream 3.0 hotfix branch (ok/jetstream3_hotfix, 84dad4d3f6), overriding compose.version to 1.13.0-beta01. This updates Kotlin from 2.2.20-Beta2 to 2.4.20, Compose from 1.8.2 to 1.13.0-beta01 (including JetBrains/compose-multiplatform-core#3411), and Skiko from a custom 0.9.4.3 build to 0.156.0, and emits standard Wasm exnref (try_table, 0 legacy try instructions) via JetBrains/compose-multiplatform#5787.

To review (9 files, +190/−141; the other 6 files are build output):

  • Removed: the hotfix branch and its custom Skiko build, use-beta-toolchain.patch, jstag-workaround.patch (WebKit bugs 297126 and 297127, fixed in August 2025), hook-print.patch, and the unused skipFunMain global.
  • Kept and rebased: empty-main-function.patch and skiko-disable-instantiate.patch.
  • Added: compiler-options.patch passing -Xwasm-kclass-fqn=false to work around KT-91066 (KClassImpl.hashCode() allocating "$packageName.$typeName" on every modifier node lookup), a sed step in build.sh rewriting the static import statements in Kotlin 2.4's compose-benchmarks-benchmarks.import-object.mjs, direct Wasm instantiation in benchmark.js (replacing .uninstantiated.mjs), and polyfills/overrides in benchmark.js (AbortController, Blob, addEventListener/postMessage, and disabling window.caches so Compose 1.12+'s ResourceWebCache uses the in-memory preload fetch polyfill in browsers just as in JS shells).

Binaries: 2.67 MB smaller in total (compose-benchmarks-benchmarks.wasm: 5.65 MB → 5.24 MB; skiko.wasm: 9.72 MB → 7.46 MB).

Scores vs. JetStream 3.0 (<shell> cli.js --test=Kotlin-compose-wasm on a Linux x64 workstation, 5 interleaved rounds):

Test d8 (15.9.60) jsc (306270) SpiderMonkey (146.0a1)
Kotlin-compose-wasm −2.7% −3.8% −8.9%
First and Average subscores
Test d8 First / Average jsc First / Average SpiderMonkey First / Average
Kotlin-compose-wasm −5.5% / −1.7% −6.9% / −2.5% −11.5% / −7.1%

First is slower because Skiko 0.156.0 links skiko.wasm with Emscripten -s MAIN_MODULE=2 (JetBrains/skiko#1213) and the modules have 11% more functions to compile. In Average, MultipleComponents and LazyGrid are faster than in 3.0, while AnimatedVisibility does more per-frame work in Compose 1.12/1.13 (GapComposer, SnapshotStateObserver.observeReads) and Kotlin 2.4 (KT-73452 array bounds checks).

TODOs once upstream releases ship:

  • Update CMP_REV in build.sh once Compose 1.13.0 is stable (~mid-December 2026) and drop -Pcompose.version=1.13.0-beta01.
  • Drop compiler-options.patch (-Xwasm-kclass-fqn=false) once KT-91066 is fixed.

@danleh
danleh requested review from eqrion and kmiller68 November 3, 2026 17:34
@netlify

netlify Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for webkit-jetstream-preview ready!

Name Link
🔨 Latest commit d4e293b
🔍 Latest deploy log https://app.netlify.com/projects/webkit-jetstream-preview/deploys/6aea7135e2f8ff82835c6a53
😎 Deploy Preview https://deploy-preview-331--webkit-jetstream-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@danleh danleh added the v3.1 label Nov 3, 2026
@danleh
danleh force-pushed the wasm-kotlin-compose-update branch from bf19e61 to 60e51ff Compare November 3, 2026 21:43
Build the Compose Multiplatform benchmarks from upstream master (1574503571,
which includes JetBrains/compose-multiplatform#5787 passing
-Xwasm-use-new-exception-proposal to the Wasm linkTask) instead of the
JetStream 3.0 hotfix branch (ok/jetstream3_hotfix, 84dad4d3f6), overriding
compose.version to 1.13.0-beta01. This moves Kotlin from 2.2.20-Beta2 to
2.4.20 (stable), Compose from 1.8.2 to 1.13.0-beta01 (which includes the PR
#3411 fix for per-frame JobCancellationException/Error stack allocation in
RectManager and PR #3269/#3484 Skia wrapper reuse fixes), and Skiko from a
custom 0.9.4.3 build to 0.156.0, while emitting standard WebAssembly exnref
(try_table/throw_ref) with zero legacy try/catch instructions.

Compiler option added in compiler-options.patch (both on compile and
KotlinJsIrLink tasks):
- -Xwasm-kclass-fqn=false: Works around KT-91066, where Kotlin 2.3+'s
  KClassImpl.hashCode() allocates and hashes "$packageName.$typeName" on
  every call (triggered on every Compose modifier node lookup).

Removed workarounds:
- The hotfix branch and its custom Skiko build.
- use-beta-toolchain.patch: master uses a stable Kotlin (2.4.20).
- jstag-workaround.patch: Safari's WebAssembly.JSTag fixes have shipped.
- hook-print.patch: Kotlin's glue logs through console, and benchmark.js
  now silences console.log and console.warn unless verbose is set.
- The skipFunMain global in benchmark.js, which nothing reads.

Kept, rebased: empty-main-function.patch and
skiko-disable-instantiate.patch (updated for Skiko 0.156.0's
awaitSkikoCore). Also rewrite static imports in Kotlin 2.4's
compose-benchmarks-benchmarks.import-object.mjs via sed in build.sh,
instantiate compose-benchmarks-benchmarks.wasm directly in benchmark.js
(replacing compose-benchmarks-benchmarks.uninstantiated.mjs), and disable
window.caches in benchmark.js so Compose 1.12+'s ResourceWebCache uses the
in-memory preload fetch polyfill in browsers just as in JS shells.

TODOs once upstream updates ship:
- Update CMP_REV to a newer compose-multiplatform commit once Compose
  1.13.0 is stable (~mid-December 2026) and drop the explicit
  -Pcompose.version=1.13.0-beta01 override in build.sh.
- Remove compiler-options.patch (-Xwasm-kclass-fqn=false) once KT-91066 is
  fixed and backported.

Part of WebKit#277.
@danleh
danleh force-pushed the wasm-kotlin-compose-update branch from 60e51ff to d4e293b Compare November 3, 2026 23:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant