Skip to content

(SP: 1) [Frontend] Improve Lighthouse Performance and SEO scores for quiz pages#272

Merged
ViktorSvertoka merged 31 commits into
developfrom
sl/feat/quiz
Feb 5, 2026
Merged

(SP: 1) [Frontend] Improve Lighthouse Performance and SEO scores for quiz pages#272
ViktorSvertoka merged 31 commits into
developfrom
sl/feat/quiz

Conversation

@LesiaUKR
Copy link
Copy Markdown
Collaborator

@LesiaUKR LesiaUKR commented Feb 4, 2026

Closes #271
Closes #273

Goal

Improve Lighthouse Performance (85->90+) and SEO (82->100) scores for quiz pages, fix timer UX issues, and resolve mobile anti-cheat false positives.

Scope

  • Remove unused Font Awesome CSS import (render-blocking, ~780ms)
  • Add .browserslistrc to target modern browsers (reduce polyfills ~14 KiB)
  • Add generateMetadata() for /quizzes and /quiz/[slug] pages with i18n
  • Add meta translations to en.json, uk.json, pl.json
  • Replace emoji with lucide-react icon in CountdownTimer
  • Fix timer progress bar animation glitches on session restore and tab switch
  • Fix mobile anti-cheat false positives by distinguishing touch vs mouse events
  • Add --force flag to JS Fundamentals quiz seed for reseeding
  • Expand JS Fundamentals quiz from 10 to 40 questions

Expected impact

Metric Before After
Render blocking CSS ~780ms 0ms
Legacy JS polyfills ~14 KiB ~0 KiB
SEO score 82 100
Performance score 85 90+
Timer UX animation jumps smooth sync
Mobile quiz blocked by anti-cheat works correctly
JS Fundamentals quiz 10 questions 40 questions

Out of scope

  • LCP optimization via server components refactoring
  • Lato font removal (used in BlogHeaderSearch)

Summary by CodeRabbit

  • New Features

    • Dynamic metadata generation for individual quiz pages and the quizzes list for improved SEO.
  • Improvements

    • Countdown timer: smoother, more accurate timing and better handling when switching tabs.
    • Anti-cheat: touch vs mouse interactions distinguished to reduce false violations.
  • Style

    • Replaced emoji with icon in the countdown hurry-up message; removed legacy Font Awesome import.
  • Chores

    • Added browser list config; extended translations for EN/PL/UK.

LesiaUKR and others added 30 commits January 24, 2026 16:26
…(issues #181, #193, #194)

- Refactor QaTabButton to shared CategoryTabButton component
- Add category accent colors to QuizCard, buttons, progress indicators
- Standardize colors with CSS variables, traffic light timer
- Add DynamicGridBackground to quizzes list page
- Border-only answer feedback, semi-transparent progress styles
Changed violationsCount > 3 to >= 3 in QuizResult points block
to match the warning banner threshold at line 124.
- Configure Vitest for quiz module
- Add test factories and setup utilities
- Add quiz-crypto tests (13 tests)
- Add quiz-session tests (12 tests)
…eat hook (#199)

- verify-answer.test.ts: 8 tests for API endpoint
  - Correct/wrong answer verification
  - Validation errors (missing fields, tampered data)
  - Security: rejects modified encrypted answers

- quiz-anticheat.test.ts: 10 tests for useAntiCheat hook
  - Detects copy, paste, context-menu, tab-switch events
  - Respects isActive flag
  - Reset and cleanup functionality

Total quiz tests: 52 (9 setup + 25 unit + 18 integration)
…UI flow

Add 28 new tests covering:
- useQuizSession hook (6 tests)
- useQuizGuards hook (8 tests)
- guest-quiz storage (5 tests)
- guest-result API route (5 tests)
- quiz-slug API route (3 tests)
- QuizContainer UI flow (1 test)

Coverage: 35% -> 90.94% (quiz scope)
Tests: 52 -> 80
Closes #260, #261, #262

- Add quiz-answers-redis.ts with getOrCreateQuizAnswersCache()
- Cache correct answers per quiz (12h TTL)
- Replace AES-256-GCM decryption with O(1) Redis lookup
- Add initializeQuizCache server action
- Update verify-answer route to use Redis

- Allow restoring 'completed' sessions (not just 'in_progress')
- Only clear session for authenticated users after submit
- Guest result screen now survives language switch

- Delete PendingResultHandler.tsx (never executes)
- Delete start-session/route.ts (broken import, unused)
- Delete quiz-crypto.ts (AES replaced by Redis)
- Delete quiz-crypto.test.ts (tests dead code)
- Rewrite verify-answer.test.ts for Redis API (8 tests)
- Fix quiz-session.test.ts for completed session restore
Part of #262 cleanup - route had broken import after Redis migration.
- Validate seed param to prevent NaN breaking question shuffle
- Add cache recovery in verify-answer when Redis cache expires
- Add DB fallback in getCorrectAnswer when Redis unavailable
Add isQuizzesPath to MainSwitcher to exclude /quiz and /quizzes routes
from extra px-6 padding, matching Q&A page behavior.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove unused Font Awesome CSS import (render-blocking, ~780ms savings)
- Add generateMetadata for /quizzes page with i18n support
- Add generateMetadata for /quiz/[slug] page with dynamic title/description
- Add meta translations to en.json, uk.json, pl.json
- Replace emoji with lucide-react Clock icon in CountdownTimer
- Add .browserslistrc to target modern browsers (reduce polyfills ~14 KiB)
- Add touch detection to anti-cheat to prevent false contextmenu violations on mobile
- Add select-none and webkit-touch-callout CSS to prevent text selection
- Fix timer progress bar jump on navigation using isSynced state
- Fix TypeScript error in quiz metadata description
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Feb 4, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
devlovers-net Ready Ready Preview, Comment Feb 5, 2026 0:14am

@netlify
Copy link
Copy Markdown

netlify Bot commented Feb 4, 2026

Deploy Preview for develop-devlovers ready!

Name Link
🔨 Latest commit 56f76e5
🔍 Latest deploy log https://app.netlify.com/projects/develop-devlovers/deploys/6983e0876968440008ecd93c
😎 Deploy Preview https://deploy-preview-272--develop-devlovers.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 4, 2026

📝 Walkthrough

Walkthrough

Adds browserslist config, dynamic metadata generation for quizzes, removes Font Awesome import, refactors the quiz countdown timer (icon and sync logic), extends i18n keys for quiz metadata, enhances anti-cheat touch detection, and adds a force-delete option to the quiz seeding script.

Changes

Cohort / File(s) Summary
Browser & Global Styles
frontend/.browserslistrc, frontend/app/globals.css
Add browserslist targeting modern/ES6-module-capable browsers; remove Font Awesome CSS import; extend .no-select to descendants and add -webkit-touch-callout.
Quiz Page Metadata
frontend/app/[locale]/quiz/[slug]/page.tsx, frontend/app/[locale]/quizzes/page.tsx
Add exported generateMetadata functions that load translations and (for detail) fetch quiz data to return typed Metadata (title, description) and handle not-found.
Countdown Timer UI
frontend/components/quiz/CountdownTimer.tsx
Replace emoji with Clock from lucide-react; increase tick rate to 100ms; add isSynced/prevEndTime sync logic, visibility handling, and conditional progress-bar transitions.
Anti-Cheat Hook
frontend/hooks/useAntiCheat.ts
Track last interaction type (touch vs mouse); add touchstart (passive) and mousedown handlers; only record contextmenu violations when last interaction was not touch.
Translations
frontend/messages/en.json, frontend/messages/pl.json, frontend/messages/uk.json
Add quiz metadata and not-found keys: quiz.page.notFoundTitle, quiz.page.metaSuffix, quiz.page.metaDescriptionFallback, quiz.list.metaTitle, quiz.list.metaDescription.
DB Seed Script
frontend/db/seed-quiz-javascript.ts
Add --force flag and forceDelete parameter to allow deleting existing quiz attempts; update CLI parsing, help text, and function signature; import dotenv/config.
Misc
frontend/app/globals.css (import removal), frontend/.browserslistrc
Minor CSS rule changes and browserslist addition to reduce legacy polyfills and remove render-blocking CSS.

Sequence Diagram(s)

sequenceDiagram
    participant Req as Request (locale, slug)
    participant GM as generateMetadata
    participant I18n as i18n loader
    participant API as Quiz API
    participant Next as Next.js

    Note over Req,Next: Page request triggers metadata generation
    Req->>GM: invoke generateMetadata(params)
    GM->>I18n: loadTranslations(locale, namespace)
    GM->>API: fetchQuiz(slug) (detail page only)
    API-->>GM: quiz | null
    I18n-->>GM: translation strings
    GM->>Next: return Metadata { title, description } or notFound metadata
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

UI, refactor

Suggested reviewers

  • AM1007
  • ViktorSvertoka

Poem

🐰 I hopped through code with tiny paws,
swapped an emoji for a Clock’s bright jaws.
Metadata sung in three tongues true,
modern browsers joined the crew,
seeds can force a fresh restart—hip paws, hooray!

🚥 Pre-merge checks | ✅ 3 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR includes out-of-scope changes to seed-quiz-javascript.ts (--force flag, quiz attempt handling) and CountdownTimer.tsx synchronization logic that exceed the stated objectives. Move seed-quiz-javascript.ts changes and timer synchronization enhancements to a separate PR, keeping only the Clock icon replacement for CountdownTimer as specified in issue #271.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately summarizes the main objective of improving Lighthouse Performance and SEO scores for quiz pages, which is clearly reflected in all changes.
Linked Issues check ✅ Passed All coding requirements from issue #271 are met: Font Awesome CSS removed, .browserslistrc added, generateMetadata() implemented for both quiz pages with i18n, translations added, and Clock icon replaces emoji in CountdownTimer.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch sl/feat/quiz

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

- Reset isSynced state when endTime changes to prevent transition jump
- Reset isSynced on tab visibility change for instant sync
- Add --force flag to JS quiz seed for reseeding with existing attempts
- Expand JS Fundamentals quiz from 10 to 40 questions
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@frontend/components/quiz/CountdownTimer.tsx`:
- Around line 24-41: Add a new useEffect in the CountdownTimer component that
runs when endTime changes and immediately resets isSynced to false and updates
remainingSeconds to the current computed value (e.g., Math.max(0,
Math.floor((endTime - Date.now())/1000))). This ensures the progress bar
transition is disabled until the next sync interval; reference the setIsSynced
and setRemainingSeconds setters and endTime in the effect dependency array.

Comment thread frontend/components/quiz/CountdownTimer.tsx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants