facebookexperimental / Recoil

Recoil is an experimental state management library for React apps. It provides several capabilities that are difficult to achieve with React alone, while being compatible with the newest features of React.
https://recoiljs.org/
MIT License
19.61k stars 1.18k forks source link

Is there a way to turn off HAMT? #959

Closed wojtekmaj closed 1 month ago

wojtekmaj commented 3 years ago

With 0.2.0, "HashArrayMappedTrieMap" was introduced. This caused the build to grow in size significantly without obvious benefits for an app the size I'm developing: I'm not concerned about performance of 10,000 atoms having, like, fifteen.

Is there a way to turn off this feature and tree shake HAMT thing?

RayLuxembourg commented 3 years ago

@wojtekmaj can you share please the size before and after?

wojtekmaj commented 3 years ago

You can see the growth here: https://bundlephobia.com/result?p=recoil@0.2.0

davidmccabe commented 3 years ago

It should be feasible to provide a build without this as it's already accessed via an abstract interface that can be switched between HAMT and built-in Map. More generally it's probably possible to shrink Recoil's bundle size a lot with some effort at eliminating cruft. I'd be a bit concerned about debugging and consistency issues by having two branches though.

Dorumin commented 3 years ago

While I don't think that the 15kb jump from 0.1.x to 0.2.0 is particularly massive, caring about bundle sizes is important, so if you're doing the fine-tuning necessary to drop it down even in an experimental state library I guess you could fiddle with some minifier settings

One thing that comes to mind would be exposing a tiny function that swaps the internal object used as the map, like

import { _replaceInternalMap } from 'recoil';

_replaceInternalMap(new Map());

and then, in the webpack config, use a custom resolve to make hamt_plus a noop module that doesn't export anything (or maybe exports a very minimal object for it not to crash when the library immediately loads)

That could break if any of your other dependencies are using hamt_plus though, so it seems like quite a brittle way to go about it

I still think 0.2 is a bit too early for a library to be putting tons of thought into bundle sizes and scaling performance seems like the right tradeoff for now, but this really makes me wish for some sort of build flag system like what Rust has for its dependencies. Particularly since JavaScript is often compiled by bundlers nowadays