Gain Performance! Take Your Run Time to Build Time

This ad is not shown to multipass and full ticket holders
JSNation US
JSNation US 2025
November 17 - 20, 2025
New York, US & Online
See JS stars in the US biggest planetarium
Learn More
In partnership with Focus Reactive
Upcoming event
JSNation US 2025
JSNation US 2025
November 17 - 20, 2025. New York, US & Online
Learn more
Bookmark
Rate this content

The talk is focused on the trend in the industry towards build time operations.And aims to provide the starting point for the viewers to understand this better. Now since every major library is adopting the build time strategy to add performance gains. It's high time that everyone should understand how these things work and how to make a build time solution.

This talk has been presented at React Advanced 2024, check out the latest edition of this React Conference.

FAQ

API Weeds is a tool developed by Rohit that allows users to watch, test, and document APIs, similar to what Postman offers.

Gluestack Style was built to enhance styling performance by calculating styling essentials statically, addressing the performance issues faced with NativeBase V3.

Build time optimizations improve application performance by offloading heavy computations to build time, reduce runtime workload, and enable earlier error detection and smaller bundle sizes.

NativeWin brings Tailwind styling to React Native by heavily relying on build time optimizations and compilers.

React Native UStyle is a drop-in replacement for React Native, allowing developers to use aliases and theme tokens. It uses build time features to handle styling, adding zero code to the bundle size.

Babel is a JavaScript transpiler that allows developers to write modern JavaScript features while maintaining compatibility with a wide range of browsers. It enables moving computational tasks to build time.

Compilers transform source code into a lower-level language executable by a computer, while transpilers convert code from one language to another of similar abstraction level.

Bundlers like Webpack process code starting from an entry point, build a dependency graph, and bundle connected modules into optimized output files, using loaders and plugins for additional functionality.

Developers can create a custom Babel plugin by defining a function that returns an object with a visitor property. This visitor listens for specific node types (e.g., member expression) and modifies them as needed.

Rohit is a founding engineer at Tria, working on transforming onboarding and asset management across blockchains for Web 3.

Rohit Singh
Rohit Singh
24 min
28 Oct, 2024

Comments

Sign in or register to post your comment.
Video Summary and Transcription
I'm Rohit, a founding engineer at Tria. We're working on bringing the world to web 3 using names. The talk focuses on optimizing performance by shifting from runtime to build time. Build time optimization improves performance, error detection, and bundle size. Case studies include GlueStack and React Native UStyle. React Native UStyle allows importing virtual components, while compilers transform source code and transpilers manipulate code structure. Babel is a JavaScript transpiler that offers benefits for React. AST Explorer is used to build a custom Babel plugin for removing console logs. The talk also covers bundlers like webpack, modules, loaders, and plugins in the bundling process.

1. Introduction to Tria and Web 3

Short description:

I'm Rohit, a founding engineer at Tria. We're working on bringing the world to web 3 using names. I've worked on products like API Weeds and NativeBase V3. Now, I'm focused on building Tria and providing unmatched UX and DX for our mobile app and SDKs.

Namaste. My name is Rohit. I'm a founding engineer at Tria. We are working on bringing the world to web 3 using names. You can follow me and DM me on the social platforms, so do check them out. And let's connect.

A bit more about me. I've worked on products like API Weeds, which is a tool to watch, test, and document APIs, somewhat like Postman. Then I built NativeBase V3, which didn't go as planned, and we got stuck with a lot of performance issues. Therefore, Gluestack Style came into the picture. We built this to completely change how we can handle styling with giving utmost importance to performance and how we can calculate most of the essentials statically. Well, those who aren't aware, NativeBase was a component library meant for all the platforms Web, React, and iOS and Android. Then using that, using Gluestack Style, we built Gluestack UI, the successor of NativeBase, which I'll touch upon later. And now I'm working on building Tria. At Tria, we are trying to solve one of the most challenging problems of Web 3, that is, we are transforming onboarding and asset management across blockchains. My main focus here is to provide every user with unmatched UX and DX when they use our mobile app or mobile SDKs.

2. Optimizing Performance with Build Time

Short description:

My talk is about gaining performance and taking a runtime to build time. We'll explore the build time trend and case studies of front-end libraries leveraging build time optimization. We'll also cover Babel, bundlers, and the shift towards build time optimization. This approach improves performance, allows for earlier error detection, and leads to smaller bundle sizes.

So my talk is about how you can gain performance and take a runtime to build time. So let's get started. In the agenda for this talk, we have the following things. We'll look into the build time trend, then I'll try to make you understand why there's all this hype and why you should be bothered by it. Then we'll look into some case studies, where we'll look into some front-end libraries that are leveraging a build time optimization or build time altogether. And after that, we'll understand what is Babel and touch upon abstract syntax tree. And after that, we'll make one small Babel plugin as well. Then comes bundlers, we'll try to understand the core concepts and check out a custom Webpack plugin.

Okay. And yeah, so you must be seeing my Twitter handle on few slides. You know what you have to do. Do follow me. I have some exciting things coming up, which I will be sharing on Twitter. So don't forget to connect with me. Let's begin by making sense of this upward trend in libraries and understand why authors are pushing for build time optimizations. So in recent years, we have seen an increasing number of front-end libraries shifting towards build time optimizations. This trend underlines the tech industry's growing emphasis on performance and efficiency. And you can clearly see this if you are following the latest React updates, you must be aware of React has announced the launch of a new React compiler. This is a major development that indicates a significant shift towards build time optimizations and within the React ecosystem itself. Other libraries like Tamag, UI Glowstack and NativeWin are also prioritizing build time over runtime. These libraries are all incorporating compilers into their core structure and demonstrating a clear industry trend towards this approach. The shift towards build time optimization is reshaping the front-end landscape. And as we continue to embrace these modern architectures, we can expect to see further improvements in performance and efficiency.

As more and more front-end tools are now moving their processes to build time, now it's high time for every developer to understand what all this hype is about and how you can leverage this knowledge in your projects. Plus, you will need this knowledge for debugging issues related to these build time solutions you will be using. So let's start by seeing what build time brings to the table. First, it significantly improves the performance of the application by offloading heavy computations and tasks to build time. We reduce the workload during runtime, resulting in a smoother and faster UX. Secondly, it allows for earlier error detection. Third, build time optimization can lead to smaller bundle sizes.

3. Case Studies and Cool Features

Short description:

The tasks like minification, tree shaking can reduce code size, leading to quicker load times and less data usage. Build time optimization allows for more predictable software and improves performance, efficiency, and reliability. Case studies include GlueStack, which leverages a Babel plugin for build time styling computation, and React Native UStyle, with features such as aliases and virtual components.

The tasks like minification, tree shaking can significantly reduce the final size of the code. But you have a lot of power. You can also analyze what part of code is not used and even strip that out on top of optimization done by your bundlers. Hence, leading to quicker load times and less data usage for the end user.

Lastly, it allows for more predictable software. By doing as much as possible during the build time, we can have a better understanding of how our software will behave in production. In conclusion, the shift toward build time optimization is a natural progression and as we try to improve more and more on performance, efficiency and reliability. In software development, this trend is only going to go up from here.

Now, let's take a look at some case studies. So, first we have GlueStack. So, GlueStack UI v1 is used GlueStack style which has the capability to compute most of your styling needs at build time using a Babel plugin. This helped us to improve the performance of BISEX to 7x. Like we were converting all the computation of your theme tokens or your color mode styling, all those things at build time. And although now v1 is archived, but v2 also provides the same performance with the help of NativeWin. NativeWin is a package that aims to bring Tailwind styling to React Native and it heavily relies on build time using a compiler to do so. And we all love Tailwind and hence NativeWin, we all love too.

And then we have React Native UStyle. This is something I'm building in my free time lately and I'll quickly show you some of its cool features and how they are working internally. So, this is the React Native UStyle website and I'll quickly jump to the documentation. So, if you go to the usage, so this is the basic thing that it does is to, it's a drop in... First thing is it is a dropping replacement for React Native. So whatever you can import from React Native, you can import from React Native UStyle. And secondly, so if you were importing view, you can just write React Native UStyle and now your view will have this power to write aliases and theme tokens. So here, bg is background color and this is a theme token, then p is padding and so on. And you can define your tokens and aliases like this in a config file and this is fully typed. Okay, this is the first feature and the second feature is virtual components. So, this is something I'm excited about. So, what it does is you can define a component in your theme, like my view and you can provide this a tag. So, my view is tag view.

4. View Imports and Understanding Compilers

Short description:

React Native UStyle allows you to import VC, which fully supports my view. The library adds zero code to your bundle size and uses existing components from React Native. Tamagui is a solid competitor. Compilers transform source code into a lower-level language, while transpilers convert code between similar abstraction levels. Transpilers use abstract syntax trees (ASTs) to understand and manipulate code structure.

So, my view is tag view. Okay. And you can provide the base style, variants and all those stuff, which you can provide to any other component. And what this does is, so now from React Native UStyle, you can import VC and that VC has my view. This is fully typed. You can write whatever you want and this will work. So now you can write my view in your code and after running the bundle, after running the Bevel plugin, this code will be converted into this.

Okay. So, your VC and all those stuff will be gone and your view will be imported. And whatever tag you declared in your config that will be used from React Native and the style, appropriate style will be applied here. So, this is something I'm using build time for and this allows me to handle everything on build time and it ships zero code to like my library React Native UStyle adds zero code to your bundle size and uses already existing components from React Native. And lastly, I would like to mention Tamagui as well, as it has been the major competitor in this space and I personally am very impressed by what Nate has been able to build. This is a solid package.

Now let's build a basic understanding of terms compiler and transpilers. What are they and how are they different? As you can see on the screen, compilers transform source code written in one programming language into another language. Basically a lower level language that can be directly executed by a computer and transpilers on the other hand convert your source code from one programming language to another of similar abstraction level. So for example, it converts your ES6 to ES5 or lower levels, or maybe your TypeScript code to JS code. Now the next thing that we need to know is how these transpilers mainly understand or read our code base. Like do they do a read file operation and then do some string manipulation and all? Well, the answer is yes and no, both. So transpilers mainly use a data structure known as abstract syntax tree or AST.

This tree is generated by reading your file and then understanding it to create nodes of this tree. An abstract syntax tree is a tree structure representing the grammatical structure of your code, focusing on relationships between elements not formatting details. And it's like a map of your code showing how expressions and statements fit together. So let's see how this tree looks for a piece of code. So yeah, so if you can see this is the code of normal JavaScript code and on the right side is the AST. So if I directly click on JSON, this is the whole tree that is getting created for this particular lines of codes. And if I hover over like if I click tips and click on tree, then this will tell me what kind of node that particular selection is. If I select this whole thing, this is a like variable declarator and then inside that declaration variable declarator, another variable declarator, and then in it, array expression since it's an array and then string literals are there. So all this data is getting stored in this tree and you can pass over this tree in your Babel plugin and then manipulate this data very easily. So let's get back to our talk.

5. Understanding Babel and Building a Custom Plugin

Short description:

Babel is a JavaScript transpiler that revolutionized React and JSX syntax. It offers benefits like leveraging JavaScript features, maintaining browser compatibility, and moving computational heavy tasks to build time. In the demo, we will build a custom Babel plugin using the visitor pattern to remove console logs from a React application.

So now let's quickly take a high-level understanding of Babel as well. Babel is a free and open source JavaScript transpiler that has been revolutionary in the development of React and JSX syntax. Some key benefits of Babel include leveraging JavaScript features for cleaner and more efficient code, maintaining compatibility with a wider range of browsers, and moving computational heavy tasks to build time. Now, let's move on to the demo and build our custom Babel plugin.

When using AST Explorer, you can see the original code and the transformed code, which represents the Babel plugin. I have copied a basic code of a React application and I want to remove console logs from it while leaving console.errors or console.warn in the code. To achieve this, I wrote a Babel plugin that uses a visitor pattern. The visitor pattern allows you to select specific types of nodes in the AST, such as member expressions. By identifying the object and property names associated with console.log, I can listen to all member expressions in the file and get the path.

6. Using AST Explorer and Building a Babel Plugin

Short description:

AST Explorer is used to view ASTs and the transform code. The goal is to remove console logs from a React application while keeping console.errors or console.warn. A Babel plugin is created using the visitor pattern to listen to member expressions in the file and remove console logs based on specific conditions.

Yeah, so this is AST Explorer that we see, we use to see the ASTs and when you click on transform here, so you get this view here is your original code and this is the transform code and this is your Babel plugin actually. And this is again the tree structure that we used previously.

So I've copied a basic code of a React application. What I want to make is I want to remove console logs from here and leave console.errors or console.warn all those stuff in the code. But I want to remove just the logs. OK, so for that I wrote this Babel plugin.

So essentially Babel plugins are a function and it returns object which has a property visitor. This is the main thing. So this visitor pattern that we call so visitor can take in multiple types of nodes. So here the member expression is a type of node. If you if you see. So how I go about building this. So first I will select this console.log whole thing. OK. Then I'll see what I can distinguish, how I can distinguish this thing from any other code. So for me that there should be an object and that object has should have a property called log and that object's name should be console.

So I'll go here and I will see that this has a callee, like function call and that that is of type member expression. And then inside that member expression, I see an object that has a name console and a property that has the name log. So I'll simply see any call. I'll tap like I'll assign a listener. This is like a listener and I listen to all the member expression in this file and get the path. And whenever this condition satisfies. So what this condition is, it just checks some of the null things. And then finally it checks like path dot node dot object dot name is console. That means the path is basically the member expression node. OK. So if I scroll here. So. Where did it went. OK.

7. Removing Console Logs and Understanding Bundlers

Short description:

This part discusses how to remove console logs using a Babel plugin. It explains the process of identifying and removing console logs using the visitor pattern. The talk then transitions to the topic of bundlers, using webpack as an example and explaining the concept of entry point and modules.

So this member expression, this callee is the node and then this path dot node dot object dot object dot name is console. And similarly I check for the property value and property is named log. Then I will delete this. I will delete this declaration. OK. So this path dot parent dot path dot remove does that same thing. So what it does is since we are this path is the member expression. So if you see this member expression, the parent of this is the call expression. When I select the call expression, this whole console log, he is getting highlighted. So which means this call expression is the thing that we want to remove. That's why I'm going to the parent path. Sorry. And that's why I'm going to the parent path and removing that. I am calling the remove function to delete that particular node. And that's how this whole wave plugin will work. So whenever I write any console log, if you can see in the transformed file, there won't be any console logs, but the original file has console log. So that's a simple wave plugin that you will be using or you can use if you are not.

And yeah, then let's come back to the talk. I hope I was able to make you understand what wave plugins are and how you can build one. Now let's move on and see how the thing which is responsible for running these wave plugins that is a bundler's work. To keep things simple, I'll take the example of a pack which is a very common bundler. And let's start by understanding basics of how it works and what are the core concepts that you must know. So every bundler has an entry point. Imagine your application as a house. Okay. And all bundler needs a starting point like a front door. This is the entry point or a single Javascript file where your application execution begins. So bundlers like a webpack starts processing code from here and identifies all the connected modules.

So and these modules are like your rooms of your house and essentially your Javascript files. So each Javascript file in your project is considered a module.

8. Understanding Bundlers and the Bundling Process

Short description:

This part explains the role of modules, loaders, and plugins in the bundling process. It discusses how bundlers build a dependency graph to understand module connections and the importance of loaders for file transformation. It also highlights the functionality of plugins in extending a bundler's capabilities and the bundler's role in optimizing and bundling modules into output files for the browser.

These modules can contain code data or assets like images and modules can also import functionality from other modules. As the bundler processes these modules, it builds a dependency graph. This graph maps all the connection between modules and showing how they rely on each other. And this allows your bundler to understand the order in which to process which module and bundle them together.

Now since all bundlers don't understand everything that is written in your code. Some loaders are also required. Loaders are like translators for your bundler and they can transform files like CSS images or even data into a format that the bundler can understand and use within your application bundle. Then we have the most important things that is a plugin. Plugins are powerful tools that extend a bundler's functionality beyond basic bundling and they can perform various tasks like code minification, tree shaking and image optimization etc. And some bundlers also provide you the ability to configure its behavior for different environments and like development and production and enable features like source maps or code splitting for better performance. And finally the bundler takes all the process and transform modules and bundles them into one or more optimized output files like a Javascript bundle or CSS bundle. And this makes it easier for the browser to load and execute your application.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Vite: Rethinking Frontend Tooling
JSNation Live 2021JSNation Live 2021
31 min
Vite: Rethinking Frontend Tooling
Top Content
Vite is a next-generation build tool that leverages native ES modules for improved performance. It eliminates the need for bundling and improves hot module replacement. Vite provides an opinionated default configuration while still allowing advanced customization through plugins. It is framework agnostic and can be used for React and other applications. Vite is being adopted by Next.js and Create React App, and integration with Nuxt 3 offers significant speed improvements.
A Guide to React Rendering Behavior
React Advanced 2022React Advanced 2022
25 min
A Guide to React Rendering Behavior
Top Content
This transcription provides a brief guide to React rendering behavior. It explains the process of rendering, comparing new and old elements, and the importance of pure rendering without side effects. It also covers topics such as batching and double rendering, optimizing rendering and using context and Redux in React. Overall, it offers valuable insights for developers looking to understand and optimize React rendering.
React Compiler - Understanding Idiomatic React (React Forget)
React Advanced 2023React Advanced 2023
33 min
React Compiler - Understanding Idiomatic React (React Forget)
Top Content
Watch video: React Compiler - Understanding Idiomatic React (React Forget)
Joe Savona
Mofei Zhang
2 authors
The Talk discusses React Forget, a compiler built at Meta that aims to optimize client-side React development. It explores the use of memoization to improve performance and the vision of Forget to automatically determine dependencies at build time. Forget is named with an F-word pun and has the potential to optimize server builds and enable dead code elimination. The team plans to make Forget open-source and is focused on ensuring its quality before release.
Speeding Up Your React App With Less JavaScript
React Summit 2023React Summit 2023
32 min
Speeding Up Your React App With Less JavaScript
Top Content
Watch video: Speeding Up Your React App With Less JavaScript
Mishko, the creator of Angular and AngularJS, discusses the challenges of website performance and JavaScript hydration. He explains the differences between client-side and server-side rendering and introduces Quik as a solution for efficient component hydration. Mishko demonstrates examples of state management and intercommunication using Quik. He highlights the performance benefits of using Quik with React and emphasizes the importance of reducing JavaScript size for better performance. Finally, he mentions the use of QUIC in both MPA and SPA applications for improved startup performance.
React Concurrency, Explained
React Summit 2023React Summit 2023
23 min
React Concurrency, Explained
Top Content
Watch video: React Concurrency, Explained
React 18's concurrent rendering, specifically the useTransition hook, optimizes app performance by allowing non-urgent updates to be processed without freezing the UI. However, there are drawbacks such as longer processing time for non-urgent updates and increased CPU usage. The useTransition hook works similarly to throttling or bouncing, making it useful for addressing performance issues caused by multiple small components. Libraries like React Query may require the use of alternative APIs to handle urgent and non-urgent updates effectively.
How React Compiler Performs on Real Code
React Advanced 2024React Advanced 2024
31 min
How React Compiler Performs on Real Code
Top Content
I'm Nadia, a developer experienced in performance, re-renders, and React. The React team released the React compiler, which eliminates the need for memoization. The compiler optimizes code by automatically memoizing components, props, and hook dependencies. It shows promise in managing changing references and improving performance. Real app testing and synthetic examples have been used to evaluate its effectiveness. The impact on initial load performance is minimal, but further investigation is needed for interactions performance. The React query library simplifies data fetching and caching. The compiler has limitations and may not catch every re-render, especially with external libraries. Enabling the compiler can improve performance but manual memorization is still necessary for optimal results. There are risks of overreliance and messy code, but the compiler can be used file by file or folder by folder with thorough testing. Practice makes incredible cats. Thank you, Nadia!

Workshops on related topic

React Performance Debugging Masterclass
React Summit 2023React Summit 2023
170 min
React Performance Debugging Masterclass
Top Content
Featured Workshop
Ivan Akulov
Ivan Akulov
Ivan’s first attempts at performance debugging were chaotic. He would see a slow interaction, try a random optimization, see that it didn't help, and keep trying other optimizations until he found the right one (or gave up).
Back then, Ivan didn’t know how to use performance devtools well. He would do a recording in Chrome DevTools or React Profiler, poke around it, try clicking random things, and then close it in frustration a few minutes later. Now, Ivan knows exactly where and what to look for. And in this workshop, Ivan will teach you that too.
Here’s how this is going to work. We’ll take a slow app → debug it (using tools like Chrome DevTools, React Profiler, and why-did-you-render) → pinpoint the bottleneck → and then repeat, several times more. We won’t talk about the solutions (in 90% of the cases, it’s just the ol’ regular useMemo() or memo()). But we’ll talk about everything that comes before – and learn how to analyze any React performance problem, step by step.
(Note: This workshop is best suited for engineers who are already familiar with how useMemo() and memo() work – but want to get better at using the performance tools around React. Also, we’ll be covering interaction performance, not load speed, so you won’t hear a word about Lighthouse 🤐)
Using CodeMirror to Build a JavaScript Editor with Linting and AutoComplete
React Day Berlin 2022React Day Berlin 2022
86 min
Using CodeMirror to Build a JavaScript Editor with Linting and AutoComplete
Top Content
Workshop
Hussien Khayoon
Kahvi Patel
2 authors
Using a library might seem easy at first glance, but how do you choose the right library? How do you upgrade an existing one? And how do you wade through the documentation to find what you want?
In this workshop, we’ll discuss all these finer points while going through a general example of building a code editor using CodeMirror in React. All while sharing some of the nuances our team learned about using this library and some problems we encountered.
Next.js 13: Data Fetching Strategies
React Day Berlin 2022React Day Berlin 2022
53 min
Next.js 13: Data Fetching Strategies
Top Content
Workshop
Alice De Mauro
Alice De Mauro
- Introduction- Prerequisites for the workshop- Fetching strategies: fundamentals- Fetching strategies – hands-on: fetch API, cache (static VS dynamic), revalidate, suspense (parallel data fetching)- Test your build and serve it on Vercel- Future: Server components VS Client components- Workshop easter egg (unrelated to the topic, calling out accessibility)- Wrapping up
React Performance Debugging
React Advanced 2023React Advanced 2023
148 min
React Performance Debugging
Workshop
Ivan Akulov
Ivan Akulov
Ivan’s first attempts at performance debugging were chaotic. He would see a slow interaction, try a random optimization, see that it didn't help, and keep trying other optimizations until he found the right one (or gave up).
Back then, Ivan didn’t know how to use performance devtools well. He would do a recording in Chrome DevTools or React Profiler, poke around it, try clicking random things, and then close it in frustration a few minutes later. Now, Ivan knows exactly where and what to look for. And in this workshop, Ivan will teach you that too.
Here’s how this is going to work. We’ll take a slow app → debug it (using tools like Chrome DevTools, React Profiler, and why-did-you-render) → pinpoint the bottleneck → and then repeat, several times more. We won’t talk about the solutions (in 90% of the cases, it’s just the ol’ regular useMemo() or memo()). But we’ll talk about everything that comes before – and learn how to analyze any React performance problem, step by step.
(Note: This workshop is best suited for engineers who are already familiar with how useMemo() and memo() work – but want to get better at using the performance tools around React. Also, we’ll be covering interaction performance, not load speed, so you won’t hear a word about Lighthouse 🤐)
Building WebApps That Light Up the Internet with QwikCity
JSNation 2023JSNation 2023
170 min
Building WebApps That Light Up the Internet with QwikCity
WorkshopFree
Miško Hevery
Miško Hevery
Building instant-on web applications at scale have been elusive. Real-world sites need tracking, analytics, and complex user interfaces and interactions. We always start with the best intentions but end up with a less-than-ideal site.
QwikCity is a new meta-framework that allows you to build large-scale applications with constant startup-up performance. We will look at how to build a QwikCity application and what makes it unique. The workshop will show you how to set up a QwikCitp project. How routing works with layout. The demo application will fetch data and present it to the user in an editable form. And finally, how one can use authentication. All of the basic parts for any large-scale applications.
Along the way, we will also look at what makes Qwik unique, and how resumability enables constant startup performance no matter the application complexity.
High-performance Next.js
React Summit 2022React Summit 2022
50 min
High-performance Next.js
Workshop
Michele Riva
Michele Riva
Next.js is a compelling framework that makes many tasks effortless by providing many out-of-the-box solutions. But as soon as our app needs to scale, it is essential to maintain high performance without compromising maintenance and server costs. In this workshop, we will see how to analyze Next.js performances, resources usage, how to scale it, and how to make the right decisions while writing the application architecture.