-
Notifications
You must be signed in to change notification settings - Fork 164
Improve metadata performance #1080
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
storywithoutend
wants to merge
15
commits into
main
Choose a base branch
from
feature/fet-2595-improve-metadata-performance
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Improve metadata performance #1080
storywithoutend
wants to merge
15
commits into
main
from
feature/fet-2595-improve-metadata-performance
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Added console logging to investigate query context parameters passed to checkImageExists. Temporarily removed timestamp parameter to test cache behavior. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Deploying ens-app-v3 with
|
| Latest commit: |
89d2b7a
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://3a720d6c.ens-app-v3.pages.dev |
| Branch Preview URL: | https://feature-fet-2595-improve-met.ens-app-v3.pages.dev |
Add cache-busting mechanism to ensure fresh avatar and header images after updates. Timestamps are only added when queries are explicitly invalidated, not on initial fetch. Key changes: - Create metadataCache.ts with LRU cache (100-entry limit) to prevent memory leaks - Implement invalidateMetaDataQuery utility for centralized cache-bust logic - Update useEnsAvatar to append timestamps to metadata URLs - Fix URL query parameter handling (use & when params exist) - Remove debug console.log statements - Break circular dependency by extracting cache to separate module 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
LeonmanRolls
approved these changes
Nov 5, 2025
Simplified bustMetadataCache.ts to avoid code duplication by: - Creating getChainNameForClient utility that follows the same pattern as getChainName - Removing inline chain ID mapping that caused eslint errors - Centralizing chain name logic for better maintainability Also simplified invalidateMetaDataQuery bulk path to only trigger React Query refetches without setting expiries for all URLs, fixing the performance issue where unrelated images were unnecessarily cache-busted. Co-Authored-By: Claude <[email protected]>
e29b5ac to
cf4b60a
Compare
Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
…te file - Created src/utils/metadataUrl.ts with createMetaDataUrl and META_DATA_BASE_URL - Updated imports in useEnsAvatar.ts, metadataCache.ts, and invalidateMetaDataQuery.ts - Resolves ESLint import/no-cycle errors - All tests passing (19/19 metadataCache tests) - Build now succeeds without ESLint blocking errors
The tests were using the old appspot.com URL while the production code was updated to use metadata.ens.domains. This caused test failures. All 19 tests now passing.
Changed META_DATA_BASE_URL from appspot.com staging URL to production metadata.ens.domains domain for consistency.
- Add cache busting to updateResolver transaction for avatar/header records - Extend React Query invalidation to all profile-modifying transactions - Colocate metadataCache test file with source file - Add comprehensive PR documentation explaining cache architecture When a user changes their resolver, the new resolver may have different avatar/header records. This ensures stale images are properly invalidated. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Fixed incorrect import path from '../metadataCache' to './metadataCache' since both files are in the src/utils/ directory. This resolves test failures caused by file relocations. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.



PR Summary: Metadata Cache Improvements
Overview
This PR enhances the metadata cache busting system to ensure avatar and header images are properly invalidated when profile records are updated. It adds cache busting to the
updateResolvertransaction and ensures all profile-modifying transactions properly invalidate React Query caches.Architecture Flow
1. How Avatar/Header Images Are Loaded
Step 1.1: Creating Metadata URLs
When a component needs to display an avatar or header, it starts by creating a metadata service URL:
src/utils/metadataUrl.ts:17-28This generates URLs like:
https://metadata.ens.domains/mainnet/avatar/vitalik.ethhttps://metadata.ens.domains/mainnet/header/vitalik.ethStep 1.2: Fetching Images with Cache Busting
The
useEnsAvatarhook fetches images and applies cache-busting when needed:src/hooks/useEnsAvatar.ts:35-44src/hooks/useEnsAvatar.ts:12-28When a cache-bust expiry exists, the URL becomes:
https://metadata.ens.domains/mainnet/avatar/vitalik.eth?expiry=1699564800000Step 1.3: Usage in Components
Components use the
useEnsAvatarhook to display images:src/components/AvatarWithZorb.tsx:78-822. How Cache Busting Works When Records Change
Step 2.1: Transaction Execution with Cache Busting
When a user updates their profile (avatar, header, or other records), the transaction file busts the metadata cache:
Example:
src/transaction-flow/transaction/updateProfile.ts:62-78Step 2.2: Setting Cache-Bust Expiry
The
bustMediaCachefunction stores an expiry timestamp:src/utils/metadataCache.ts:140-156src/utils/metadataCache.ts:104-122The cache-bust expiry is:
Step 2.3: React Query Cache Invalidation
After a transaction completes,
TransactionNotificationsinvalidates React Query caches:src/components/TransactionNotifications.tsx:61-71This triggers React Query to refetch the image with the new cache-bust parameter.
3. Cache-Bust Expiry and Automatic Cleanup
Step 3.1: Checking for Expiry
When
getCacheBustExpiryis called, it checks if the expiry time has passed:src/utils/metadataCache.ts:74-94Step 3.2: LRU Eviction
The cache implements Least Recently Used (LRU) eviction with a max size of 100 entries:
src/utils/metadataCache.ts:16-18When the cache reaches capacity, the oldest entry is removed before adding a new one.
Step 3.3: localStorage Persistence
Cache expiries are persisted to survive page refreshes:
src/utils/metadataCache.ts:37-53Expired entries are automatically filtered out when loading from localStorage.
Changes in This PR
1. Added Cache Busting to
updateResolverTransactionFile:
src/transaction-flow/transaction/updateResolver.tsProblem: When a user changes their resolver, the new resolver may have different avatar/header records. Without cache busting, stale images could be displayed.
Solution: Added cache busting for both avatar and header when the resolver is updated.
Changes:
bustMediaCacheclientparameter to transaction functionbustMediaCacheto bust both avatar and header caches2. Extended React Query Invalidation Coverage
File:
src/components/TransactionNotifications.tsxProblem: Several profile-modifying transactions were not invalidating React Query caches, potentially causing stale data to persist in memory.
Solution: Added all profile-modifying transactions to the switch statement that invalidates React Query caches.
Changes:
resetProfileresetProfileWithRecordsmigrateProfilemigrateProfileWithResetupdateResolver3. Test File Colocation
File Move:
src/utils/__tests__/metadataCache.test.ts→src/utils/metadataCache.test.tsReason: Colocate test file with source file following modern testing best practices.
Transaction Coverage
All transactions that modify avatar or header records now properly implement dual-cache invalidation:
updateProfileupdateProfileRecordsresetProfileresetProfileWithRecordsmigrateProfilemigrateProfileWithResetupdateResolverTwo-Level Cache Architecture
The system maintains two separate caches that must both be invalidated:
1. Metadata Service Cache (External)
?expiry={timestamp}query parameter to URLsbustMediaCache()2. React Query Cache (In-Memory)
queryClient.invalidateQueries()TransactionNotifications.tsxBoth caches must be invalidated to ensure users see updated images immediately.
Testing
The metadata cache system has comprehensive test coverage:
Test File:
src/utils/metadataCache.test.tsTest coverage includes:
bustMediaCachefunction for avatar/headerBenefits