Skip to content

Commit 531e9c2

Browse files
committed
Implement progressive batch loading for faster recent edits
PERFORMANCE IMPROVEMENTS: - Reduce API fetch limits from 20x to 8x (400→160 pages) for balanced performance - Add progressive batch sizing: start with 15 items, increase to 20+5*batch for subsequent loads - Fix Firebase admin initialization in subscription portal route (build-time issue) PROGRESSIVE LOADING LOGIC: - Initial load: 15 items for fast first paint - Batch 2: 25 items (20 + 5*1) - Batch 3: 30 items (20 + 5*2) - Max batch: 50 items (capped) BENEFITS: - Much faster initial page load - Smooth infinite scroll with increasing batch sizes - Maintains data continuity while improving perceived performance - Fixes build errors from module-level Firebase initialization
1 parent 1c01ace commit 531e9c2

File tree

4 files changed

+65
-10
lines changed

4 files changed

+65
-10
lines changed

app/api/recent-edits/route.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,12 @@ export async function GET(request: NextRequest) {
8787
.where('deleted', '!=', true) // Filter out deleted pages (includes pages without deleted field)
8888
.orderBy('deleted') // Required for != queries
8989
.orderBy('lastModified', 'desc')
90-
.limit(limit * 10); // Increased multiplier to account for heavy filtering
90+
.limit(limit * 5); // Moderate multiplier for user-specific queries
9191
} else {
92-
// For general recent edits, fetch much more data to account for filtering
92+
// Progressive batch loading: Start with reasonable fetch size, let client request more
9393
pagesQuery = db.collection(getCollectionName('pages'))
9494
.orderBy('lastModified', 'desc')
95-
.limit(limit * 20); // Dramatically increased to ensure continuous data after filtering
95+
.limit(limit * 8); // Balanced: enough data after filtering, but fast initial load
9696
}
9797

9898
// Add cursor for pagination

app/api/subscription/portal/route.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ import { NextRequest, NextResponse } from 'next/server';
88
import { getUserIdFromRequest } from '../../auth-helper';
99
import { initAdmin } from '../../../firebase/admin';
1010

11-
// Initialize Firebase Admin
12-
const admin = initAdmin();
13-
const adminDb = admin.firestore();
14-
1511
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
1612

1713
export async function POST(request: NextRequest) {
1814
try {
15+
// Initialize Firebase Admin inside function to avoid build-time issues
16+
const admin = initAdmin();
17+
const adminDb = admin.firestore();
18+
1919
// Get authenticated user
2020
const userId = await getUserIdFromRequest(request);
2121
if (!userId) {

app/components/features/SimpleRecentEdits.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,18 +63,24 @@ export default function SimpleRecentEdits() {
6363
});
6464
const [isFollowingAnyone, setIsFollowingAnyone] = useState<boolean | null>(null);
6565
const [followCardDismissed, setFollowCardDismissed] = useState(false);
66+
const [batchNumber, setBatchNumber] = useState(1); // Track batch number for progressive loading
6667

6768
const fetchRecentEdits = useCallback(async (cursor?: string, append = false) => {
6869
try {
6970
if (!append) {
7071
setLoading(true);
7172
setError(null);
73+
setBatchNumber(1); // Reset batch number for fresh loads
7274
} else {
7375
setLoadingMore(true);
76+
setBatchNumber(prev => prev + 1); // Increment batch number
7477
}
7578

79+
// Progressive batch sizing: Start small for fast initial load, increase for subsequent batches
80+
const currentBatchSize = append ? Math.min(20 + (batchNumber * 5), 50) : 15;
81+
7682
const params = new URLSearchParams({
77-
limit: '50',
83+
limit: currentBatchSize.toString(),
7884
includeOwn: filters.includeOwn.toString(),
7985
followingOnly: filters.followingOnly.toString()
8086
});
@@ -114,7 +120,7 @@ export default function SimpleRecentEdits() {
114120
setLoading(false);
115121
setLoadingMore(false);
116122
}
117-
}, [user?.uid, filters]);
123+
}, [user?.uid, filters, batchNumber]);
118124

119125
// Load more items when scrolling near bottom
120126
const loadMore = useCallback(() => {

docs/SIMPLIFIED_ACTIVITY_SYSTEM.md

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,15 @@
22

33
## Overview
44

5-
WeWrite's activity system has been completely refactored from a complex multi-collection approach to a simple, reliable system based on recent pages with diff data stored directly on page documents.
5+
WeWrite's activity system has been completely refactored from a complex multi-collection approach to a simple, reliable system based on the unified version system with embedded token allocation controls.
6+
7+
## 🚀 Latest Updates (July 2025)
8+
9+
### Recent Edits System Overhaul
10+
- **✅ Fixed Data Gaps**: Increased fetch limits from 60 to 400 pages to eliminate massive timeline gaps
11+
- **✅ Smart Token Controls**: Added conditional token allocation bars (hidden on user's own pages)
12+
- **✅ Include Own Edits**: Changed default to show user's own recent edits for complete activity feed
13+
- **✅ Unified Version System**: All recent edits now pull from the consolidated version system
614

715
## Architecture
816

@@ -34,6 +42,47 @@ Activity Page → Query recent pages → Show pages with diff data
3442
- Automatic consistency (diff data lives with page)
3543
- Easier to maintain and debug
3644

45+
## Recent Edits API Architecture (2025)
46+
47+
### Critical Performance Fixes
48+
49+
The recent edits system underwent major performance and data integrity improvements:
50+
51+
#### 1. Increased Fetch Limits
52+
```typescript
53+
// OLD: Insufficient data causing gaps
54+
.limit(limit * 3); // Only 60 pages total
55+
56+
// NEW: Adequate data for continuous timeline
57+
.limit(limit * 20); // 400 pages for general recent edits
58+
.limit(limit * 10); // 200 pages for user-specific edits
59+
```
60+
61+
**Problem Solved**: The API was only fetching 60 pages before applying heavy filtering (visibility, ownership, deleted status), leaving massive 4-month gaps in the timeline.
62+
63+
#### 2. Smart Token Allocation Controls
64+
```typescript
65+
// Only show token allocation for other users' pages
66+
{activity.userId && activity.pageId && user?.uid !== activity.userId && (
67+
<EmbeddedTokenAllocation
68+
pageId={activity.pageId}
69+
authorId={activity.userId}
70+
pageTitle={currentPageName}
71+
source="HomePage"
72+
/>
73+
)}
74+
```
75+
76+
**Benefit**: Users no longer see confusing token allocation controls on their own pages where allocation isn't possible.
77+
78+
#### 3. Include Own Edits by Default
79+
```typescript
80+
// NEW: Show complete activity feed including user's own edits
81+
includeOwn: true, // Users want to see all recent activity including their own
82+
```
83+
84+
**Rationale**: Most recent activity comes from the logged-in user, so excluding their own edits created artificially sparse feeds.
85+
3786
## Implementation Details
3887

3988
### 1. Diff Data Storage on Pages

0 commit comments

Comments
 (0)