npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

mobx-jsx

v0.16.0

Published

Raw MobX performance without the restraints of a Virtual DOM

Downloads

36

Readme

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 discrete 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

For TS JSX types add to your tsconfig.json:

"jsx": "preserve",
"jsxImportSource": "mobx-jsx"

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"]);

<ul>
  {map(list, item => (
    <li>{item}</li>
  ))}
</ul>;

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 further information.

However, you may emulate componentDidMount and componentWillUnmount. The microtask 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");
  }
}

Mounting

Mounting can be done by functions and not class components. However you may use an arrow function as follows:

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

class App extends Component {
  render() {
    return <div>Mounted</div>
  }
}

render(() => <App />, document.body);

References

ref assigns to a variable.

let elRef;
Promise.resolve().then(() => elRef.clientWidth);
<div ref={elRef} />

Note: Promise.resolve().then is used as mount see the issue Lifecycles for further information.

Lazily Loading a Component

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

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

function App() {
  return (
    <>
      <SomeComponent name={"John"} />
    </>
  );
}

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:

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.