Yosuke Onoue - Think About Front-end Web Development with Rust — RustFest Global 2020
Hello. The title of this presentation is ‘Think about Front-End Web Development with Rust’. I’m Onoue. In this session, I’ll talk about front-end web development through technological progress like WebAssembly in Rust. A bit about me, I work in research and education as an Associate Professor at Nihon University. My research is on information visualization and I mainly develop visual analytic systems with web technology. I follow the cutting-edge web technology like Rust to achieve high-speed web applications.
This talk will be on front-end development on Rust, what it can and can’t do, and web development trends. First, I’ll explain about recent front-end technology. Web application architecture for front-end technology has drastically developed and changed in the last 10 years. This was the typical web application configuration: It linked the application server to PHP or Python Ruby and used a template engine to assemble HTML from information loaded from a database. Then it transmitted this HTML to the client web browser.
This talk will be on how to write these overall with Rust. Let’s discuss the architecture adopted in the previously mentioned frameworks: React, Angular, and Vue. This is not always the case, but a model architecture centered on a virtual DOM is becoming widespread. This architecture describes how to assemble the user interface from the app with declarative programming.
The virtual DOM has an algorithm to effectively update the user interface based on changes in the application. These updates are significant, but over the years they have taken various approaches with them. A typical example of these approaches is called Elm architecture which has a state update system and is adopted in Elm with an AltJS.
First, View constructs the user interface in the Elm architecture. The user performs an operation from the constructed UI and the operation conveys this as a message to the app. The app state update occurs based on this message and reconstructs the user interface to match its new state. This detaches the screen construction and app state management and keeps app development scalable. This modern front-end framework architecture has high-level abstraction to manage complexities.
The graph on the right shows GitHub stars. Yew, Percy, Seed, Dodrio, and Sauron are comparatively popular. They have more than 1000 stars. Within these Yew is by far the most well-liked, so we’ll cover it in more detail. Yew was developed when WebAssembly debuted and has a component-based framework like React and Elm.
It provides HTML macros like React and JSX and can construct a UI declaratively from the app state. It introduces state management system inspired by Elm architecture. It has various functions. The router is the most essential equipment for the front-end framework.
The embedded router enables a transition between multiple pages within the app. Yew is equipped with many functions needed in modern front-end web development. Currently, it is under active development as seen from the GitHub star rating.
Let’s look at a brief sample code for app development on Yew. This code has a simple counter with a plus and minus button. This model shows its components which are achieved by implementing the Component trait.
It uses HTML macro to mark up the components within the View function which is one of several functions. A noteworthy function is the Create function at the top. It initializes the component here. Here, the Value field is initialized. It holds this as a component state, so it can look up the current field value from within View and then display it. Next, let’s look at the state management system.
The Update function is implemented as a function to update the component state. The function receives messages and updates the component based on message’s type and content. There are two buttons constructed with View. When this is clicked, a message is issued from a click event. The sent message is received by the Update function and a state update is made for the value.
A ShouldRender value is rendered to determine whether the View function needs to be restarted with an update. This is abstracted with ShouldRender. The simplest method is rendering either true or false. If it renders ‘true’, then the View function is restarted. I focused on Yew due to time constraints, but most frameworks have UI construction and state updates. There are already several sophisticated frameworks like Yew. We know we’re getting close to achieving front-end development on Rust.
Animation processing also multiples on the web app. If the main thread is overloaded, issues arise like a degraded animation framerate. The concept called off the main thread has been proposed for this.
For this, I’ll introduce Agents in Yew as an interesting approach to off-the-main-thread in Rust. Agents is a system that provides a service available from the overall application with an actor model. Agents provides various implementations with an abstracted interface including the use of WebWorkers.
This enables processing to be delegated from the main thread without being conscious of WebWorkers. We’ll look at this code on processing with Agents. A SentToWorker message is issued when you click on the button. Once it receives the message, it issues a GetDataFromServer request to Worker.
Worker receives this request and renders the processing results to the main thread. The processing results from Worker is processed with call-back and renders the call-back message. It issues a DataReceive message here. Then, the update function can reflect the processing results from that message in the state. Next is working with CSS which is indispensable in constructing a web app. As the front-end grows in scale, several issues arise surrounding CSS.
A typical example of this is when the CSS selector unexpectedly crashes and the website design breaks down. Performance is essential on recent browsers, requiring asset optimization to remove unnecessary style. Several approaches, like the CSS Modules and CSS-in-JS, have been undertaken in modern front-end development. I’ll introduce a few approaches for CSS on Rust. Firstly, several methods seem to have a similar approach to CSS Modules, in which they incorporate it in asset after generating other elements and unduplicated identifiers for the styles written within the front-end app on Rust.
It has an independent crate called CSS macro in Percy and CSSinRust and is applicable to this method. Let’s look at code using CSS in Rust. As you see at the top, first it wraps the style string then generates a style instance. The style instance generates a class name for the applicable element without duplicating other elements. The style itself is added to the head element in the output HTML. I’ll introduce a crate called RUSS as an approach to CSS like Rust.
Looking at the Isomorphic example that includes Percy, there are 2 place holders in the HTML file for its template. One has initial content to display on the page, whereas the other becomes the app state needed to construct this. When a request arrives from the browser, the server renders the generated results applying the template. The one on the browser makes this its initial state and operates the continuing app on the browser.
Currently, I believe, even front-end frameworks on Rust are becoming more aware of SRR. They’re taking into account the SRR compatibility with Yew. If we imagine the near future of front-end development, Jamstack will continue gaining traction as a system to achieve a high-performance web app with SRR. Jamstack is characterized by a configuration with a content delivery network to facilitate high-speed content to users. Next.js is a typical example of a framework for current Jamstack. Next.js supports SSR and static site generation with a framework based on React.
In the future, a single-step high-level framework may become necessary to construct a practical web app in Rust more so than the current ones. Finally, let’s discuss WebComponents. As many of you may know, WebComponents is a standard system to componentize websites. It’s configured from 4 specifications: Custom Elements, Shadow DOM, ES Modules, and HTML Template.
If we take this a step further, this will cover creating part of the interface on Rust and embedding this on the app. A trend that merits attention is micro frontends. The system splits the currently enlarged front-end into several micro frontends so that the backend app changes from a monolithic one to a microservice.
Then, this integrates a large web app. This is the trend for micro frontends. Interestingly enough, the micro front-end configuring the app could be disconnected from the implementation. These micro frontends could be written with Agular or with React. Micro frontends also include things that can be created with Rust and WebAssembly. WebComponents is not the only method to achieve micro frontends, but it’s an example of an effective tool for it.
Once WebComponents is possible on Rust, it surely has the potential to create part of the app user interface on Rust. To conclude this is an opportunity to leverage powerful language like Rust on complex front-end development. Front-end development with Rust is close to fruition with the debut of WebAssembly toolchains and frameworks.
There are still discrepancies, but we need to try out the best practices cultivated thus far on Rust in order to achieve full-blown front-end development on Rust. There are still many issues to address when you attempt to work on the front-end with Rust, so I’d like to challenge everyone here today to try your hand at tackling these. That’s it. Thank you.