Skip to content
Merged
Changes from 10 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 94 additions & 1 deletion contributingGuides/PERFORMANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -361,4 +361,97 @@ Examples:
- [Remove shouldAdjustScrollView to avoid heavy rerender](https://github.com/Expensify/App/pull/66849) - removes hooks that were called only for Safari logic slowing down the `ReportScreen.tsx`
- [PopoverWithMeasuredContent optimization for mobile](https://github.com/Expensify/App/pull/68223) - returns early to avoid unnecessary calculations
- [Reduce confirm modal initial render count](https://github.com/Expensify/App/pull/67518) - returns early to reduce first load cost
- [Do not render PopoverMenu until it gets opened](https://github.com/Expensify/App/pull/67877) - adds a wrapper to control if `PopoverMenu` should be rendered
- [Do not render PopoverMenu until it gets opened](https://github.com/Expensify/App/pull/67877) - adds a wrapper to control if `PopoverMenu` should be rendered

# Proposing Performance Improvements

We are actively looking for contributions that improve the performance of the App, specifically regarding unnecessary re-renders, slow method executions, and user perceived latency.

___

If you haven't already, check out our [Contributing Guidelines](https://github.com/Expensify/App/blob/main/contributingGuides/CONTRIBUTING.md) and email [email protected] to request access to our Slack channel!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and email [email protected] to request access to our Slack channel!

We handle this via a google form now. Easiest to just delete this text cuz it's already in CONTRIBUTING.md . If you want to keep, update to

If you would like to join our #expensify-open-source Slack channel, fill out this form with your email and Upwork profile link. If you haven't been added in 2 weeks, email [email protected].

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ooh ok well maybe I can just keep the first part (check out our contributing guidelines) but remove the part about requesting slack channel access? I think it's always a good reminder & good practice to link to our main CONTRIBUTING docs - but we don't have to explain any processes here that are found there, as you said!


👉 **Before posting the proposal, please read through this whole process for important context and instructions.** Proposals that do not follow these guidelines cannot be accepted.

___

### Instructions for Submission
1. Copy the template below.
2. Fill out the details strictly following the guide.
3. Post it in `#expensify-open-source` with the title `[Performance Proposal] <Component_Name>`.

___

```
## 1. Component and Flow Description

**Component/Flow:** Describe the specific UI component or user flow being optimized.
- [Add details here]

**Preconditions:** List any specific setup required before reproducing the steps (e.g., "Workspace must have chat history").
- [Add details here]

**Reproduction Steps:** Provide a numbered list of steps to reproduce the performance issue (similar to a QA test case).
- [Add details here]

## 2. Required Tools
*I have verified these metrics using (check all that apply):*
- [ ] React DevTools Profiler
- [ ] Chrome Performance Tab
- [ ] JS Flamecharts
- [ ] Hermes / Release Profiler traces
- [ ] Sentry (If you have access)

## 3. Before/After Metrics
*Please fill out the table below. If a metric is not applicable, write N/A.*

| Metric | Before | After | Improvement |
| :--- | :--- | :--- | :--- |
| **Render Count** | | | |
| **Execution Time** | | | |
| **Perceived Latency** | | | |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe instead of a table we could use some tool and upload a JSON in the comment? Just to make sure that contributors don't choose only "the best numbers".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's totally fair, what tool would you suggest?

Copy link
Contributor

@staszekscp staszekscp Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general in this case I think the current version can stay as it is to not cause much delay, but I think it's worth to consider the options that we may have!

Internally we're using a tool that our colleague @sumo-slonik has built to compare the commit number and render times from the gathered profile traces. I think the contributors could simply add a screenshot from the tool and the profile traces that were used to generate it. It works great for the component performance, although with a single function execution time it might be a bit more tricky 😄

I usually rely on SpeedScope for analyzing web performance traces, but I’m curious whether others have a faster or more reliable way to measure function execution time—for example, across 100 runs—without significantly modifying the code? 😄 cc: @adhorodyski

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made a few adjustments - but yeah i think we can improve this as we go, for now let's keep it as is with the new format, unless y'all feel strongly for now!


* **Device Used:** (e.g. iPhone 13, Pixel 6, Chrome on M1 Mac)
* **Evidence:** *(Attach screenshots of the profiler or logs for both Before and After below this section)*

## 4. Prerequisites & Eligibility
*To ensure proposals are measurable and based on realistic scenarios, you must meet the following criteria:*

- [ ] **Experience:** I have at least **1 merged PR** in the App repository.
- [ ] **Test Environment:** I tested on a high-traffic account (instructions to create this [here](https://github.com/Expensify/App/blob/main/contributingGuides/CONTRIBUTING.md#high-traffic-accounts)).
- [ ] **Thresholds:** My proposal meets **at least one** of the following:
- [ ] > 20% reduction in Render Count
- [ ] > 20% reduction in Execution Time
- [ ] > 100ms reduction in Perceived Latency

## 5. Pattern Detection & Prevention
*Can we prevent this from happening again?*
- [ ] **App-wide Audit:** I have checked for other places in the app that have this same performance problem and fixed them.
- [ ] **Shared Refactor:** This fixes a shared utility/component (e.g., `Avatar.ts`) used across the app.
- [ ] **Localized Fix:** This only affects this specific view.

## 6. Automated Tests & QA
*Tests are required by default. If you cannot add them, explain why.*
- [ ] **Unit Tests:** Added to prevent regression.
- [ ] **Reassure Tests:** Added (Required for execution time improvements).
- [ ] **Exception:** I cannot add automated tests because: _________________
- [ ] **Manual Verification:** I have included manual verification steps (Required).

## 7. Other Considerations & UX Risks
*Performance improvements should not change user experience and product design.*
- [ ] This change preserves existing UX (No visual/behavioral changes).
- [ ] This change alters UX (Description: _________________).
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly an stylish suggestion, but I think the template was designed with a format more compatible to GitHub (markdown) rather than Slack, see how it looks like in Slack.

Screenshot 2026-01-16 at 15 06 34 Screenshot 2026-01-16 at 15 06 42

The ## headings don't work for example, maybe we should replace with something else that gives similar highlighting.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I def agree, but how about we release the current version, get feedback, and then update? 🙏 I just want to not wait too too long - we'll start with some internal-ish folks (C+) i believe so it's fine if it's not perfect to start, but at least let's get started 🙏

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good


---

### Compensation
* **Bounty:** Accepted and merged performance improvements are eligible for a flat **$250 bounty**.
* **Scope:** We prefer smaller, atomic PRs. However, if multiple proposals are submitted for closely related logic that could have been one PR, we reserve the right to consolidate them.

___

### Review Process
1. **Peer Review:** Wait for **2 Expert Contributors** to approve your proposal.
2. **Internal Review:** Once approved by experts, tag `@Expensify/performance-reviewers`.
3. **Approval:** **2 Internal Engineers** must approve before a GH issue is created.
Loading