EMOM Timer - Rust + WebAssembly in Action

Posted on Sun 20 October 2024 in tech

EMOM Timer - A Rust and Yew Application

EMOM Timer

Introduction

For those who are new to EMOM workouts, EMOM stands for "Every Minute on the Minute." It's a type of interval workout that pushes your limits by requiring you to complete an exercise at the start of each minute. The leftover time in each minute is your recovery period. To make these workouts seamless, I built an EMOM Timer using Rust and WebAssembly (Wasm), combining the performance of Rust with the portability of web technologies.

In this post, I'll share updates to the EMOM Timer project, highlighting the benefits of Rust and Wasm for this type of application.

Why Rust and Wasm?

Rust is known for its memory safety, performance, and concurrency support, all without a garbage collector. When combined with Wasm, you can run Rust code efficiently in a browser, creating a highly performant and portable web application. This EMOM timer leverages both, providing near-native performance for a smooth user experience.

You can view the source code on GitHub here.

Recent Updates

In this version, I've made several enhancements to the timer:

  1. Improved Timer Logic
    The core timer logic has been reworked to ensure more precise synchronization with real-time intervals. This was done by implementing an optimized loop that works seamlessly with Rust’s multithreading model. Thanks to Rust's robust control over concurrency, the timer now handles overlapping instructions more effectively, reducing the jitter during transitions between exercises and rest periods.

  2. WebAssembly Bindgen Integration
    To further streamline the interaction between Rust and JavaScript in the browser, I improved the use of wasm-bindgen. This allowed me to directly call Rust functions from JavaScript and manipulate the DOM without performance penalties. This means smoother UI transitions and more precise control over elements like the timer countdown and start/pause functionality.

  3. Customizable Workout Configurations
    Users can now fully customize their EMOM workouts. You can input the number of intervals, workout and rest durations, and even switch between time modes like stopwatch or countdown. This feature is made possible by Rust’s type system, which ensures that user inputs are validated, preventing errors during workout setup.

  4. Responsive UI with WebAssembly
    While the previous version was more of a functional demo, I’ve now added a responsive design using wasm-bindgen to manipulate CSS directly from Rust. The app adjusts seamlessly between mobile and desktop views, making it easier to use whether you’re at the gym with your phone or at home on your laptop.

Learning Points

Throughout this project, I've learned a lot about combining the strengths of Rust with Wasm, especially when it comes to performance-critical applications like timers. Here are a few takeaways:

  • Concurrency Management in Rust: Rust's ownership model makes managing concurrent tasks (like UI updates and timing functions) much safer and easier to debug compared to JavaScript's event loop model.

  • Performance Gains: Moving the heavy lifting (like timer calculations) to Rust results in noticeable performance improvements over traditional JavaScript timers, especially when run on lower-power devices.

  • Wasm as a Future-Proofing Tool: WebAssembly isn't just a tool for today; it’s part of a future where high-performance apps can be built in languages like Rust and run across different platforms with minimal overhead.

Conclusion

The combination of Rust and WebAssembly has allowed me to create a powerful, efficient, and customizable EMOM timer that outperforms similar JavaScript-only implementations. I’m excited to keep refining this project, and I hope you find it useful for your own fitness routines.

You can check out the latest version of the EMOM Timer on GitHub here, and feel free to try it out in your browser!