Need help with mobx-jsx?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

ryansolid
156 Stars 8 Forks MIT License 72 Commits 3 Opened issues

Description

Raw MobX performance without being restrained by a Virtual DOM

Services available

!
?

Need anything else?

Contributors list

# 16,303
TypeScr...
Svelte
Shell
PureScr...
63 commits
# 45,173
Python
C++
Android
Sublime...
3 commits
# 123,887
preact
repl
React
HTML
1 commit

MobX JSX

This library is a demonstration of how MobX fine grain control can be leveraged directly in JSX for considerably better performance than pairing it with a Virtual DOM library. Even the fastest Virtual DOM library will have overhead when reconciling many small discreet changes into a scheduled render and patch.

Check out MobX JSX performance near the top of the charts on the JS Frameworks Benchmark.

It accomplishes this with using Babel Plugin JSX DOM Expressions. It compiles JSX to DOM statements and wraps expressions in functions that can be called by the library of choice. In this case

autorun
wraps these expressions ensuring the view stays up to date. Unlike Virtual DOM only the changed nodes are affected and the whole tree is not re-rendered over and over.

Usage

To use call render as follow

import { render } from 'mobx-jsx';

render(App, document.getElementById('main'));

And include 'babel-plugin-jsx-dom-expressions' in your babelrc, webpack babel loader, or rollup babel plugin.

"plugins": [["babel-plugin-jsx-dom-expressions", {moduleName: 'mobx-jsx'}]]

See plugin options

Installation

> npm install mobx-jsx babel-plugin-jsx-dom-expressions

Examples

API

MobX JSX works both with function and Class components (extend Component from this library).

Map For Observable Arrays

Ships a specialize map function for optimal list rendering that takes an observable array as it's first argument. To avoid re-rendering the complete list on changes.

import { map } from "mobx-jsx";

const list = observable(["Alpha", "Beta", "Gamma"]);

    { map(list, item =>
  • {item}
  • ) }

Lifecycles

Unlike React

render
only runs once, so you may not need to split in functions or methods your Lifecycles, all the initialization code could be set on
render
. See the issue Lifecycles for furter information

However, you may emulate

componentDidMount
and
componentWillUnmount
. The microtak
Promise
resolution will be after mount and
cleanup
runs at the beginning of re-evaluation so the elements aren't removed yet.

Example

import { render, cleanup, Component as _Component } from 'mobx-jsx'

class Component extends _Component { constructor(props) { super(props) if (this.componentDidMount) { Promise.resolve().then(() => this.componentDidMount()) } if (this.componentWillUnmount) { cleanup(() => this.componentWillUnmount()) } } }

class App extends Component { componentDidMount(){ console.log('componentDidMount')}
componentWillUnmount(){ console.log('componentWillUnmount') } }

Lazily Loading a Component

import { render, lazy } from "mobx-jsx";

// use lazy to allow code splitting const SomeComponent = lazy(() => import("./SomeComponent"));

function App() { return ( <> > ); }

render(App, document.body);

MobX JSX also supports a Context API.

Non-precompiled environments

Alternatively supports Tagged Template Literals or HyperScript for non-precompiled environments by installing the companion library and including variants:

js
import { html } from 'mobx-jsx/html'; // or
import { h } from 'mobx-jsx/h';
There is a small performance overhead of using these runtimes but the performance is still very impressive. Tagged Template solution is much more performant that the HyperScript version, but HyperScript opens up compatibility with some companion tooling like:

Further documentation available at: Lit DOM Expressions and Hyper DOM Expressions.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.