We have had a really outdated version of Font Awesome directly vendored
into our repository. Not only was it outdated, but it also is shipped as
a font file, including all the icons, even though we only use a small
subset of them. By switching to Lucide, we not only are depending on
something more up to date, but now the icons can also be tree shaked.
This also updates some of our CSS to use flex box and grid instead of
manually positioning with margins.
This replaces the context menu with our own. By doing that we no longer
need to force install our npm packages, as there are no longer any
conflicts. In fact, as part of this change, I updated us to the latest
React 19 and even enabled the React compiler.
I also explored CSS modules for the first time, which are going to allow
us to reduce conflicts between CSS rules and possibly even allow us to
fully remove SASS, as the need for it is going to be reduced.
I also found out that the latest Rust nightly is broken due to their
update to LLVM 20. So I pinned the version to the last working nightly
version.
With Safari 18.2 having shipped, all browsers now support WebAssembly
Tail Calls. This allows the compiler to call a function at the end of
the current function by reusing the stack frame. This should be a tiny
bit faster and allow for recursion without stack overflows... except
that Rust doesn't have any way of guaranteeing this yet, so you can't
really rely on it.
At some point we had to switch away from `wasm-opt` automatically
detecting the WebAssembly features, because they deprecated and turned
that into a no-op. Since then we specified that it should just use all
the features. This used to work all the time, but with the introduction
of reference types it now started optimizing some of those instructions
into instructions that are only available with the `WasmGC` proposal.
This slipped through because Chrome and Firefox already support `WasmGC`
but Safari does not... yet, because they also will start to support it
very soon. In the meantime and also to ensure `wasm-opt` isn't ever
going to sneak in any unwanted features, we now explicitly specify all
the features that we want to use.
This allows us to skip letting `webpack` parse the wasm files, which
means we are not blocked by its limitations anymore. This allows us to
finally start using reference types.
With LLVM 19 they explicitly require using the `experimental-mv` ABI in
addition to the `multivalue` LLVM feature (the latter is enabled by
default now). Enabling the ABI is non-trivial and requires a full on
custom Rust target. This adds `wasm32-multivalue.json` which is
identical to `wasm32-unknown-unknown` except it sets the
`experimental-mv` ABI. The target JSON format is very experimental by
itself, so we may need to keep this up to date from time to time.
This enables the multivalue feature when building with the nightly Rust
compiler. This is because the Rust standard library is not built with
the multivalue feature enabled by default. Also we need to specifically
use the spec compliant C ABI for it to work, which is also nightly only.
This switches the rendering of the layout from using HTML and CSS to
using a canvas (technically it's two). This not only should improve the
performance but also brings the rendering in line with our native
renderers, enabling new features such as vertical resizing and
horizontal layouts. This also removes a lot of code specific to the HTML
rendering and thus greatly simplifies the codebase. There is one slight
regression in that the layout editor doesn't allow clicking and dragging
the individual components directly on the layout anymore. This is
however something we can explore directly in `livesplit-core` in the
future, so other frontends can benefit from it as well.
This allows stepping through the Rust code. `wasm-bindgen` 0.2.89 just
got released and it finally properly allows keeping the debug symbols
that Rust creates around fully. Thankfully `webpack` does not pose a
problem here and the debug symbols now properly work in Chrome, allowing
us to step through the Rust code in the developer tools.
With Safari / iOS 16.4 having released, WebAssembly SIMD is now
available on all browsers. This should help with parsing performance.
While the update released just today, we do tell people to update iOS if
they haven't already, so I believe it's fine to already publish this.
https://webkit.org/blog/13966/webkit-features-in-safari-16-4/
This updates `livesplit-core` such that we can resolve the key codes
with its built-in resolving code. Also since `livesplit-core` introduced
a `max-opt` profile, we make use of that now and on top of that also
introduce `virtual-function-elimination` for the nightly / CI builds.
This is an additional LLVM pass that tries to eliminate as many function
pointers as possible by analyzing the whole program. Locally this
reduced the size of the function pointer table from around 500 to around
400 entries. There's also a flag for using WebAssembly SIMD
instructions, as that works perfectly fine on all browsers except
Safari. Of course we won't use it for deploying until Safari supports
those instructions, but it may be useful for some local testing.
Also with this `livesplit-core` update `SpeedRunIGT` splits can now be
parsed.
We generally want the wasm file to be as compact as possible. However
because there's so many paths in Rust code that could panic, but don't
ever in practice as they are meant to signal bugs, the wasm file has to
keep around all those panic paths, and even worse, all the code for
formatting the panic messages for all those different types that could
be involved in a panic. This bloats the binary a lot. There's a nightly
feature to build the standard library as part of your compilation and
with that you can pass various features to the standard library, just
like with any other crate. And one of those features is to remove all
the formatting machinery from the panics and just immediately abort,
resulting in smaller binaries. On top of that by building the standard
library ourselves we also get to build it with all our target features,
meaning that its code will make use of all the additional WebAssembly
instructions that have been added since the MVP. So this essentially is
a big win. However this forces us to use the nightly compiler, but it
usually is actually quite stable. We won't be using any nightly features
of the language itself and only optionally use the compiler in our CI,
so the stable compiler continues to work just fine for local
development.
This updates `livesplit-core` to the latest version. This mostly adds
custom variable columns and allows for the timer to visualize the delta
for the background. There's some performance improvements as well.
Also we now build `livesplit-core` in debug mode by default when
building locally. So compilation is a little bit
faster and additional debug checks are active, such as integer
overflows.
This includes:
- Bulk memory operations
- Non-trapping float-to-int conversions
This also activates `Import & export of mutable globals`. I'm not sure
if it does anything, but LLVM supports it as well as all browsers, so we
might as well activate it too.
All browsers now support the new WebAssembly Sign Extension Instructions
which improve code that casts around between small integer types. We'd
like to activate a bunch more new WASM instructions, but Safari is
really lacking behind quite a lot. Even just activating these requires
the latest Safari / iOS version that came out just a month ago. We
notify the user to update their browser / iOS version in case they have
an outdated browser. iOS updates on its own over night, so I believe
most people should be on the latest version and shouldn't have any
problem updating in case it didn't happpen yet.
This introduces wasm-bindgen which will allow us to directly use all
kinds of JS APIs in WASM without us having to manually provide all the
functionality as imports. Instead we let wasm-bindgen handle all the
importing. Additional webpack now handles the instantiation of the wasm
module for us, which simplifies a bunch of things as well.