Skip to content

Parallelize menu network requests#22562

Merged
nbradbury merged 21 commits intotrunkfrom
issue/menus-parallel-requests
Feb 9, 2026
Merged

Parallelize menu network requests#22562
nbradbury merged 21 commits intotrunkfrom
issue/menus-parallel-requests

Conversation

@nbradbury
Copy link
Contributor

@nbradbury nbradbury commented Feb 5, 2026

Description

As part of CMM-1166, the fetchMenus and fetchMenuLocations requests now run in parallel using async/await. This should reduce initial load time since both requests happen simultaneously instead of sequentially.

Testing instructions

  • Go to My Site > Menus and verify the menu list loads as expected

nbradbury and others added 15 commits February 5, 2026 06:12
Implements infinite scroll pagination for menu list, menu item list, and
linkable items dropdown with page size of 20. Shows loading spinner when
fetching more items.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix pagination not triggering after second page by properly tracking
  state changes in LaunchedEffect keys
- Remove inaccurate menu item count from menu list
- Remove unused fetchAllMenuItems function
- Move Edit Items button to end of menu card, centered vertically
- Fix detekt warnings: swallowed exceptions, unused imports, complexity
- Extract MenuItemListContent and sibling helper functions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The ExposedDropdownMenu doesn't support LazyColumn (SubcomposeLayout
intrinsic measurement issue), causing crashes when opening the dropdown.
This replaces it with a ModalBottomSheet which properly supports
pagination with LazyColumn.

Also restores PAGE_SIZE to 20 (was 5 for testing).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This resource was left over after removing the menu item count feature.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Extract duplicate type selection label logic to helper function
- Simplify parseErrorMessage by consolidating redundant cases
- Consolidate findPreviousSiblingIndex/findNextSiblingIndex into single function

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Prevents race conditions when multiple pagination requests occur in
rapid succession. Each pagination function now uses a mutex to ensure
atomic read-check-update operations, preventing duplicate items or
incorrect pagination state.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Ensure canLoadMore remains true when pagination fails, allowing users
to retry after transient errors (network issues, timeouts, etc.).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Prevents stale data from overwriting state when user rapidly switches
between menu item types.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Support all 22 protocols from wp_allowed_protocols(): http, https, ftp,
ftps, mailto, news, irc, irc6, ircs, gopher, nntp, feed, telnet, mms,
rtsp, sms, svn, tel, fax, xmpp, webcal, urn. Also adds support for
anchor links (#section) and protocol-relative URLs (//).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Derive offset from UI state instead of cache variables to avoid race
  conditions between initial load and pagination
- Set canLoadMore=true on initial load errors to allow retry

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Pre-compute parent-to-children mapping to reduce child lookup from O(n)
to O(1) per item, improving overall complexity from O(n²) to O(n log n).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use when expression to reduce return statements from 4 to 2.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use async/await to fetch menus and locations concurrently, reducing
initial load time.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@dangermattic
Copy link
Collaborator

dangermattic commented Feb 5, 2026

1 Warning
⚠️ PR is not assigned to a milestone.

Generated by 🚫 Danger

@nbradbury nbradbury added the Menus label Feb 5, 2026
@nbradbury nbradbury changed the title Add pagination and improvements to navigation menus Parallelize menu network requests Feb 5, 2026
@wpmobilebot
Copy link
Contributor

wpmobilebot commented Feb 5, 2026

App Icon📲 You can test the changes from this Pull Request in Jetpack Android by scanning the QR code below to install the corresponding build.

App NameJetpack Android
FlavorJalapeno
Build TypeDebug
Versionpr22562-d342f01
Build Number1484
Application IDcom.jetpack.android.prealpha
Commitd342f01
Installation URL4iuaecq01ds3g
Note: Google Login is not supported on these builds.

@wpmobilebot
Copy link
Contributor

wpmobilebot commented Feb 5, 2026

App Icon📲 You can test the changes from this Pull Request in WordPress Android by scanning the QR code below to install the corresponding build.

App NameWordPress Android
FlavorJalapeno
Build TypeDebug
Versionpr22562-d342f01
Build Number1484
Application IDorg.wordpress.android.prealpha
Commitd342f01
Installation URL0kk7qfi9kljsg
Note: Google Login is not supported on these builds.

@codecov
Copy link

codecov bot commented Feb 5, 2026

Codecov Report

❌ Patch coverage is 0% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 38.28%. Comparing base (77b0da1) to head (d342f01).
⚠️ Report is 2 commits behind head on trunk.

Files with missing lines Patch % Lines
...wordpress/android/ui/navmenus/NavMenusViewModel.kt 0.00% 6 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##            trunk   #22562      +/-   ##
==========================================
- Coverage   38.28%   38.28%   -0.01%     
==========================================
  Files        2237     2237              
  Lines      111473   111476       +3     
  Branches    15579    15579              
==========================================
  Hits        42680    42680              
- Misses      65252    65255       +3     
  Partials     3541     3541              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@nbradbury
Copy link
Contributor Author

@claude

@claude
Copy link
Contributor

claude bot commented Feb 6, 2026

Claude finished @nbradbury's task in 49s —— View job


Code Review Complete ✓

  • Read the changed file (NavMenusViewModel.kt)
  • Analyze the parallel request implementation
  • Review for correctness, error handling, and potential issues
  • Provide comprehensive feedback

Summary

The change successfully parallelizes the fetchMenus and fetchMenuLocations requests using Kotlin coroutines async/await, which should improve initial load time. The implementation is correct and follows good coroutine practices.

Review Feedback

✅ What's Good

  1. Correct Use of coroutineScope: The function properly uses coroutineScope which ensures structured concurrency - if either request fails or is cancelled, both will be cleaned up properly.

  2. Proper Async/Await Pattern: The implementation correctly:

    • Creates two async coroutines to start both requests immediately
    • Awaits both results sequentially
    • This allows both network calls to run in parallel
  3. No Breaking Changes: The function signature and return type remain the same, so this is a safe refactor with no downstream impact.

  4. Error Handling Preserved: The existing error handling in the caller (loadMenusInternal) remains effective - exceptions will still propagate correctly through the coroutineScope.

📝 Observations

  1. Performance Impact: This change should reduce load time from T(fetchMenus) + T(fetchMenuLocations) to max(T(fetchMenus), T(fetchMenuLocations)), which is a solid improvement.

  2. Return Statement: The change from return when to just when (line 179) is correct since the coroutineScope lambda returns the last expression.

  3. Import Additions: The two new imports (async, coroutineScope) are minimal and appropriate.

🎯 Verification

The change is focused and minimal (+8/-4 lines), which is ideal for this type of optimization. The implementation correctly handles:

  • Structured concurrency (both operations bound to same scope)
  • Cancellation (if parent scope cancels, both requests cancel)
  • Exception propagation (failure in either request surfaces properly)

Conclusion

This is a clean, well-implemented performance optimization. The parallel request pattern is used correctly, and the change achieves its stated goal without introducing any issues. ✅


@nbradbury nbradbury requested a review from adalpari February 6, 2026 20:22
@nbradbury nbradbury marked this pull request as ready for review February 6, 2026 20:22
@sonarqubecloud
Copy link

sonarqubecloud bot commented Feb 7, 2026

Copy link
Contributor

@adalpari adalpari left a comment

Choose a reason for hiding this comment

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

Nice improvement!

@nbradbury nbradbury merged commit bcdb13d into trunk Feb 9, 2026
24 checks passed
@nbradbury nbradbury deleted the issue/menus-parallel-requests branch February 9, 2026 12:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants