MetaMask / MetaMask/metamask-extension
Reduce UI Dependency on background state to load UI quickly without delay
- Dominant language
- TypeScript
- Stars
- 13.2k
- Forks
- 5.6k
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 451
Description
## **Problem statement:**
Before the UI application can start, a connection to the background service is needed in order to get the state from the background. This problem has always existed, but manifest v3 has made the symptoms painfully obvious. In manifest v2 the problem was rarely felt because we were allowed to have a long running background process. It did restart, but infrequently. In manifest v3 we are forced to use a service worker for the background. The service worker frequently dies and there is a much greater chance of the user summoning the extension (via click or confirmation) while the service worker is not ready. When this happens the application stalls until the service worker is not only running but the background code has been initialized. This results in the user having a frustrating experience waiting for the UI to be able to be interacted with.
## **Short term solution**
The short term strategy to resolve the issue is a two part plan that not only helps to build the mental division between redux and background for our engineers, but also improves loading time and pushes us closer to a place where changing how background communication works is possible.
More to read [here](https://docs.google.com/document/d/101G7CwP1pKFGw_I9QLFoC9YNgqeGwbZQiDduOT_ZNZ4/edit#):
## Implementation part 1: Define deeper boundaries between background and redux state
### **Background:**
In UI actions, we are treating background state as a const to inject in redux store and selectors who interact with background state is mixed with those who deal with UI redux state. The task is aiming to separate the usage of background state in action file and isolate the methods, selectors as well as other background communication we rely on. Once these steps are complete we will have a much clearer understanding of which parts of the UI require state from which controllers because they will import the selectors file from the specific controllers they rely upon.
### **User Stories:**
1. https://github.com/MetaMask/metamask-extension/issues/18072
2. https://github.com/MetaMask/metamask-extension/issues/18073
3. https://github.com/MetaMask/metamask-extension/issues/18074
4. https://github.com/MetaMask/metamask-extension/issues/18075
## Implementation part 2: Allow the UI to read state from the storage system instead of from the service worker/background connection
### **Background:**
Similar to how Apollo keeps a local cache of state and then requests updates from the server, a minimal viable solution to this problem by routinely saving a snapshot of the state tree to browser storage and rehydrating the UI from that state instead of requiring the connection to be alive. Once the connection starts the updated state can be pushed to the UI and rerender the components. Once this is in place we have built into our system the sort of mechanism that Apollo relies upon as well, and instituted a gradual shift in the current paradigm so that we can think about adopting more of those paradigms and shifting to a GraphQL approach.
In the Metamask Controller we have two stores, a persisted `store`and a non persisted `memStore`. `memStore` contains *most* controller’s persisted store as well, with a couple of exceptions, and represents the data structure that the UI relies upon. We flatten the memStore and send it to the UI. The `store` is only used to write updates to the persisted chrome storage system.
### **User Stories:**
1. https://github.com/MetaMask/metamask-extension/issues/18092
2. https://github.com/MetaMask/metamask-extension/issues/18093
3. https://github.com/MetaMask/metamask-extension/issues/18104
4. https://github.com/MetaMask/metamask-extension/issues/18105
5. https://github.com/MetaMask/metamask-extension/issues/18108
Contributor guide
Research direction
Start with the linked design document and user-story issues 18072–18075 and 18092–18108. Read the UI Redux actions and selectors alongside the controller's persisted store and non-persisted memStore, then trace the service-worker and browser-storage boundaries. Done requires completing both implementation parts and their listed user stories, but this issue names no files, tests, or concrete acceptance criteria.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- graphql, redux, typescript
- Domain
- frontend, web-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100