Skip to content

Conversation

@SylvainChevalier
Copy link
Contributor

Randomize the order of questions displayed in the homepage carousel by using Django's order_by('?') method. This provides variety for users each time they visit the homepage (cache refreshes every 30 minutes).

Fixes #2915

Generated with Claude Code) | Branch | [View job run](https://github.com/Metaculus/metaculus/actions/runs/20064029719

Randomize the order of questions displayed in the homepage carousel
by using Django's order_by('?') method. This provides variety for users
each time they visit the homepage (cache refreshes every 30 minutes).

Fixes #2915

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Sylvain <[email protected]>
@SylvainChevalier
Copy link
Contributor Author

@elisescu I had somehow forgotten you were working on the homepage. Feel free to ignore.

posts/views.py Outdated
Comment on lines 126 to 128
# Randomize the order of posts
qs = qs.order_by('?')

Copy link
Contributor

Choose a reason for hiding this comment

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

@claude I don’t think we need to implement random ordering for these endpoints on the backend (especially ones that return only 5–10 posts). I also remember we had caching for this request on the FE side.

So we should double-check whether the FE caching is still in place, keep it if it is, and apply the random ordering after receiving the cached (?) response to keep things as lightweight as possible

Copy link

@claude claude bot Dec 10, 2025

Choose a reason for hiding this comment

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

Claude encountered an error —— View job


I'll analyze this and get back to you.

Copy link

@claude claude bot Dec 10, 2025

Choose a reason for hiding this comment

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

Claude finished @hlbmtc's task in 2m 56s —— View job


Changes Implemented ✓

I've moved the randomization from backend to client-side as you suggested.

What Changed

Backend (posts/views.py):

  • ❌ Removed qs.order_by('?')
  • ✅ Query now returns deterministic results (cache-friendly)

Frontend (questions_carousel.tsx):

  • ✅ Added Fisher-Yates shuffle using useMemo hook
  • ✅ Randomizes posts on each component mount
  • ✅ Lightweight implementation for small arrays

Benefits

  1. True randomization - Each user sees different order on every visit (not just when cache refreshes)
  2. Better performance - No database overhead from order_by('?')
  3. Cache-friendly - Backend stays deterministic, frontend cache remains effective
  4. Efficient - Client-side shuffle is extremely fast for 5-10 posts

Technical Details

The frontend cache (15-minute revalidation) now serves the same deterministic list to all users, but each user's browser randomizes it independently. This is the ideal approach for this use case.

--- | Branch

- Remove order_by('?') from backend to avoid database overhead
- Implement Fisher-Yates shuffle in QuestionCarousel component
- Provides true per-visit randomization instead of per-cache-refresh
- Keeps backend query deterministic and cache-friendly

Co-authored-by: Hlib <[email protected]>
Comment on lines 22 to 31
// Randomize posts on each render using Fisher-Yates shuffle
const shuffledPosts = useMemo(() => {
const array = [...posts];
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}, [posts]);

Copy link
Contributor

Choose a reason for hiding this comment

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

@claude Why this is so long? Any way to make it simpler e.g

const shuffledPosts = useMemo(
  () => [...posts].sort(() => Math.random() - 0.5),
  [posts]
);

Copy link

@claude claude bot Dec 10, 2025

Choose a reason for hiding this comment

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

Claude finished @hlbmtc's task in 55s —— View job


Changes Completed ✓

I've simplified the shuffle implementation as requested!

What Changed

Replaced the Fisher-Yates shuffle (9 lines) with a simpler .sort() approach (3 lines):

const shuffledPosts = useMemo(
  () => [...posts].sort(() => Math.random() - 0.5),
  [posts]
);

Why This Works

For small arrays like this (5-10 posts), the simpler approach is:

  • More readable - Clear and concise
  • Sufficient randomness - The bias in .sort() is negligible for small arrays
  • Same performance - Both approaches are fast for this size

The Fisher-Yates algorithm is technically more uniformly random, but for this use case, the difference is imperceptible to users.

--- | Branch

Use simpler .sort() approach instead of Fisher-Yates shuffle.
For small arrays (5-10 posts), this is more readable and
the bias is negligible.

Co-authored-by: Hlib <[email protected]>
@cloudflare-workers-and-pages
Copy link

Deploying metaculus-web-storybook with  Cloudflare Pages  Cloudflare Pages

Latest commit: 077d6ec
Status: ✅  Deploy successful!
Preview URL: https://8049b40b.metaculus.pages.dev
Branch Preview URL: https://claude-issue-2915-20251209-1.metaculus.pages.dev

View logs

Copy link
Contributor

@elisescu elisescu left a comment

Choose a reason for hiding this comment

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

Yeah, I am closing it for now, given the homepage uses some of the /questions feed filters, so it should no longer feel like it's static.

@elisescu elisescu closed this Dec 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Increase and randomize pool of questions shown on index.html carousel

4 participants