million README

The project's README from github.com/aidenybai/million. As one markdown file: README.md.

Want to automatically find and fix performance issues? Check out Million Lint.

Million.js Banner
CI NPM Version NPM Downloads
📚 Read the docs 🎦 Watch video 💬 Join our Discord 🌐 Follow on Twitter

What is Million.js?

Million.js is an extremely fast and lightweight optimizing compiler that make components up to 70% faster.

Oh man... Another /virtual dom|javascript/gi framework? I'm fine with React already, why do I need this?

Million.js works with React and makes reconciliation faster. By using a fine-tuned, optimized virtual DOM, Million.js reduces the overhead of diffing (try it out here)

TL;DR: Imagine React components running at the speed of raw JavaScript.

👉 Setup Million.js in seconds! →

Installation

The Million.js CLI will automatically install the package and configure your project for you.

npx million@latest

Once your down, just run your project and information should show up in your command line!

Having issues installing? → View the installation guide

Why Million.js?

To understand why to use Million.js, we need to understand how React updates interfaces. When an application's state or props change, React undergoes an update in two parts: rendering and reconciliation.

To show this, let's say this is our App:

function App() {
  const [count, setCount] = useState(0);
  const increment = () => setCount(count + 1);
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
}

In this App, when I click on the button, the count state will update and the <p> tag will update to reflect the new value. Let's break this down.

Rendering

The first step is rendering. Rendering is the process of generating a snapshot of the current component. You can imagine it as simply "calling" the App function and storing the output in a variable. This is what the App snapshot would look like:

const snapshot = App();

// snapshot =
<div>
  <p>Count: 1</p>
  <button onClick={increment}>Increment</button>
</div>;

Reconciliation

In order to update the interface to reflect the new state, React needs to compare the previous snapshot to the new snapshot (called "diffing"). React's reconciler will go to each element in the previous snapshot and compare it to the new snapshot. If the element is the same, it will skip it. If the element is different, it will update it.

(total: 6 diff checks)

<div>
-  <p>Count: 0</p>
+  <p>Count: 1</p>
  <button onClick={increment}>Increment</button>
</div>

From here, we can see that the <p> tag needs to be updated. React will then update the <p> DOM node to reflect the new value.

<p>.innerHTML = `Count: ${count}`;

How Million.js makes this faster

React is slow.

The issue with React's reconciliation it becomes exponentially slower the more JSX elements you have. With this simple App, it only needs to diff a few elements. In a real world React app, you can easily have hundreds of elements, slowing down interface updates.

Million.js solves this by skipping the diffing step entirely and directly updating the DOM node.

Here is a conceptual example of how Million.js reconciler works:

function App() {
  const [count, setCount] = useState(0);
  const increment = () => setCount(count + 1);

  // generated by compiler
  if (count !== prevCount) {
    <p>.innerHTML = `Count: ${count}`;
  }

  <button>.onclick = increment;

  // ...
}

Notice how when the count is updated, Million.js will directly update the DOM node. Million.js turns React reconciliation from O(n) (linear time) to O(1) (constant time).

How fast is it? → View the benchmarks

Resources & Contributing Back

Looking for the docs? Check the documentation or the Contributing Guide out. We also recommend reading Virtual DOM: Back in Block to learn more about Million.js's internals.

Want to talk to the community? Hop in our Discord and share your ideas and what you've build with Million.js.

Find a bug? Head over to our issue tracker and we'll do our best to help. We love pull requests, too!

We expect all Million.js contributors to abide by the terms of our Code of Conduct.

→ Start contributing on GitHub

Alt

Codebase

This repo is a "mono-repo" with modules. Million.js ships as one NPM package, but has first class modules for more complex, but important extensions. Each module has its own folder in the /packages directory.

You can also track our progress through our Roadmap.

Module Description
million The main Virtual DOM with all of Million.js's core.
react / react-server React compatibility for Million.js.
compiler The compiler for Million.js in React.
jsx-runtime A simple JSX runtime for Million.js core.
types Shared types between packages

Sponsors

Acknowledgments

Million.js takes heavy inspiration from the following projects:

License

Million.js is MIT-licensed open-source software by Aiden Bai and contributors:

million (aidenybai/million)

Searching Database…

17.7K ·GitHub
这是什么?Million.js 是一个速度极快、非常轻量的 React 优化编译器,通过加快调和(reconciliation)过程,让组件的性能提升最高可达 70%。
它是用来替代 React 的,还是加到我现有应用里的东西?不是替代品 —— 它作为一个优化编译器与 React 一起工作。它以一个 NPM 包的形式发布,可以加快你现有组件的更新速度。
我怎么把它加到我的项目里?运行 Million.js CLI:它会自动安装依赖包并配置好你的项目。之后照常运行你的项目就可以了。
使用它需要特殊的 React 配置或打包器设置吗?你只需要一个能正常运行的 React 项目 —— 安装和配置都由 CLI 处理,运行应用时优化信息会直接显示在命令行里。
是不是每个 React 应用都会变快,还是只有部分会?收益主要体现在包含大量 JSX 元素的真实应用中。只对比少量元素的简单应用几乎不会变快,因为 React 只在元素数量增多时才会变慢。
React 本来为什么会慢,Million 是怎么解决的?React 的协调器会在新旧快照之间逐一对比每个元素(即 diffing),所以元素越多,更新就越慢。Million.js 完全跳过了 diffing 这一步,直接更新 DOM 节点,把调和过程从 O(n) 变成 O(1)。
我的组件实际能快多少?README 声称组件最高能快 70%,而且由于调和器是常数时间的,应用规模变大后效果依然成立。如果你想看具体数字,README 里附有性能基准测试的链接。
Million Lint 是什么?它是 README 开头提到的一个独立工具,能自动发现并修复 React 性能问题。Million.js 本身则是加快调和过程的优化编译器。
这项技术是从哪来的?这个仓库是一个 monorepo,其核心虚拟 DOM 深受 blockdom(开创了虚拟 DOM 中的 blocks 概念)和 voby(template() API)的启发,并致谢了 ivi 和 Preact。
Creator
aidenybai
Size
80.7 MB
Stars
17.7K
Age
5y
Commits · 90 Days