
How to make your React App 70% faster with Million.js
19 June, 2023
3
3
0
Contributors
Reac.js is undoubtedly the most popular front-end framework today. With its component driver architecture, virtual DOM, broad community support, and recent partnerships with Vercel, React is becoming an increasingly popular choice.
React is not perfect
However, there is one issue with React that restricts it from becoming the perfect framework to use. I am talking about performance issues. React tends to impact performance as you scale your app. There are two main reasons behind this:
- React ships two libraries to the browser:
react
andreact-dom
. Both of these are large. With React 18, the bundle size of these two libraries alone takes up 44.5kb of space, which is not suitable for a client-side app. - The Virtual DOM becomes slow and takes up more time as more data needs to be displayed. The Virtual DOM changes based on the change and updates the original DOM in real time. This makes it slow, performance-intensive, and lag.
Some JavaScript frameworks like Svelte, Quick, and Solid overcome React's performance issues by eliminating the need for Virtual DOM. However, React still holds the crown for the most dominant front-end framework.
Introducing: Million.js
Million.js is a JavaScript library that claims to make React 70% faster by replacing the virtual DOM in React.
Million provides a slim and fast virtual DOM approach. It allows a faster React-like experience while opening doors to build new frameworks or extend existing ones (like Vue or Angular) on top of it. Unlike React's virtual DOM, which diffs the entire DOM tree on every render, Million.js's block virtual DOM only diffs the changed data blocks. This makes it significantly faster, especially for large applications.
In addition to being faster, Million.js is also more lightweight than React. It is only 4kb. This makes it a great choice for mobile applications, where every byte counts.
On the JS framework benchmark, Million.js ranks 1.08, which is better than React and Solid, which ranks 1.74 and 1.11, respectively.
To start with Million.js, you don't need to learn anything new. It works with all of the existing React components, libraries, and frameworks.
The "Block Virtual DOM"
Million.js introduces a novel "block" virtual DOM. It's significantly faster than React's virtual DOM, as it diffs data instead of the DOM. The magic of Million.js is hidden inside a function called block()
. It is a special higher-order component used as React component but is hyper-optimized for rendering speed.
In simple terms, Blocks are components wrapped by block()
. Here's a basic example of the same:
import { block } from "million/react";
const SayMyName = block(function Lion() {
return <h1>Heisenberg</h1>
})
Blocks can be used just like normal React components. Like this:
export default function App() {
return (
<p>Say my name 😤</p>
<SayMyName />
<p>You are god damn right</p>
)
}
Use cases with Million.js
Million is not supposed to replace React for every single use case. In certain use cases, using Million would increase your app's performance.
Lots of static content but little dynamic content
Million's Block Virtual DOM is best suited for apps that consist of more static content than dynamic. This includes status sites like blogs, portfolios, admin dashboards, etc.
For example, here is when you should and should not consider using Million.js
// ✅ Good
<div>
<div>{dynamic}</div>
Lots and lots of static content...
</div>
// ❌ Bad
<div>
<div>{dynamic}</div>
<div>{dynamic}</div>
<div>{dynamic}</div>
<div>{dynamic}</div>
<div>{dynamic}</div>
</div>
Stable UI Trees
Another factor that determines whether you should consider Million over React is Stable UI. If the component returns non-deterministic or unstable elements, Million will struggle to perform well. It is best suited when the component returns in a stable and deterministic way.
Here are two code snippets that explain it:
function Component() {
// ✅ Good, because deterministic/stable return
return <div>{dynamic}</div>;
}
function Component() {
// ❌ Bad, because non-deterministic/unstable return
return Math.random() > 0.5 ? <div>{dynamic}</div> : <p>sad</p>;
}
However, Million provides different functionality for indeterministic or unstable returns if it follows a list-like structure. The `<For /> component allows you to render unstable returns.
function Component() {
return <For each={items}>{(item) => <div>{item}</div>}</For>;
Getting started with Million.js
Million.js works with React.js and other libraries and frameworks based on top of it.
Initialize your project
Million.js works on top of React. Hence initialize the project before you install Million in the directory.
Install million
Once you have initialized the React app, install million as a dependency:
# NPM
npm i million
## Yarn
yarn add million
# PNPM
pnpm install million
Add the Million compiler to your build tool
Build tool would vary based on the library or framework that you are using. The official Million documentation has detailed instructions on adding compilers on various builds.
Hence, we will only see how to do it in Next.js. Make the following changes in your Next.js config file:
import million from 'million/compiler';
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
};
export default million.next(nextConfig);
Customize the configuration
Here are some of the options you can pass to the compiler:
interface Options {
mode: 'react' | 'preact' | 'vdom' // default: 'react'
optimize: boolean // default: false
server: boolean // default: false
}
Frequently asked questions
How does Million.js work?
Million.js uses a compiler that performs static analysis to where the dynamic data is in advance. When the user interacts and React component re-renders, the compiler analyzes the React component and generates the block tree. The block tree is diffed from the previous block tree. Any blocks that have changed are updated in the DOM.
This process is much faster than React's virtual DOM because it only needs to diff the changed data blocks. This can lead to significant performance improvements, especially for large applications.
Which libraries or frameworks can I use with Million.js?
You can use any React or Preact-based library or framework. The official docs have support for the following:
- React (Create React App)
- Next.js
- Astro
- Gatsby
- Vite
- Webpack (plain build)
What are the limitations of using Million.js?
Though Million.js improves React's performance by 70%, it does have some limitations.
- Blocks need to be defined as a variable declaration
- You can only pass a reference to a component, not the JSX components.
- Unstable or non-deterministic outputs can not be rendered with Blocks
- You cannot use UI component libraries as components may introduce non-deterministic returns
- You can't use spread attributes in Million.js, as they can introduce non-deterministic returns.
The official docs have the list of all of the rules of blocks that need to be taken care of while using Million.js.
Is Million.js just a memo?
React.js provides an in-built hook that enables memoization in React apps. However, Million.js takes a different approach. Unlike memo, which reduces and avoids rendering, Million.js makes the rendering process faster.
react
frontend
millionjs
virtualdom