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
Uh oh!
There was an error while loading. Please reload this page.
-
Expo: Evan Bacon
Meta: Moti Silberman
Microsoft: Adam Foxman, Andrew Coates
Recording: Link
Metro uses
jest-haste-mapto 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 explicitimportorrequirestatement.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-mapuses 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 causeswatchmanto 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-mapas a third crawler implementation namedlazy, next tonodeandwatchman. Inmetro,lazyshould be used by default, and only revert tonodeorwatchmanwhen expliclty configured to do so.The metadata found by
lazyshould be cached, just aswatchmanandnodedata is cached.lazymust 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
lazycrawler to fill in missing pieces of the map.Beta Was this translation helpful? Give feedback.
All reactions