Experimenting with replacing the haste-map in Metro #992
afoxman
started this conversation in
Bundle Working Group
Replies: 1 comment 1 reply
-
I wrote up a feature proposal in |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Expo: Evan Bacon
Meta: Moti Silberman
Microsoft: Adam Foxman, Andrew Coates
Recording: Link
Metro uses
jest-haste-map
to crawl the monorepo file-system. It gathers metadata on each file and watches for changes so it can keep the metadata up-to-date. The metadata includes things like a file hash and info about haste annotations within the file (e.g.@providesModule
). The haste annotations allow a module to depend on another without using an explicitimport
orrequire
statement.Metro crawls the file-system synchronously when it is launched, before it bundles or starts a bundle server. In large monorepos, crawling takes a long time and uses a lot of CPU, memory and disk resources.
jest-haste-map
uses caching to alleviate this. Even still, the cached data can take several gigabytes of memory. At this size, the haste map is too large and causeswatchman
to become unresponsive or crash.Haste, as a module loading system, is not widely used by the react-native developer community. It is mostly used by Meta (Facebook). Yet, every developer pays the cost to run it on their machines and in CI loops.
Metro recently landed a PR which lets developers replace the default haste map implementation with their own code. We can use this to create a "lazy" crawler which doesn't eagerly collect file metadata. Instead, it reads metadata on demand.
The working theory is that the file graph needed for bundling will be much smaller than the monorepo file graph, and will therefore use fewer resources.
To validate this, we need a prototype implementation and a set of measurable experiments which look at CPU time, memory usage, disk reads/writes, time to create a bundle, and time to start a bundle server and deliver a bundle to a waiting app.
If this approach proves to be worthwhile, it should land in
jest-haste-map
as a third crawler implementation namedlazy
, next tonode
andwatchman
. Inmetro
,lazy
should be used by default, and only revert tonode
orwatchman
when expliclty configured to do so.The metadata found by
lazy
should be cached, just aswatchman
andnode
data is cached.lazy
must continue to support file-watching for those files which are queried by Metro.Metro assumes it will have synchronous access to an in-memory map of all files and their metadata. This will need to be replaced with synchronous calls to the
lazy
crawler to fill in missing pieces of the map.Beta Was this translation helpful? Give feedback.
All reactions