popup/
├── index.js # 🎯 Main orchestrator (120 lines)
│
├── utils/ # 🔧 Utility functions
│ ├── dom.js # DOM caching & manipulation (105 lines)
│ ├── chrome-api.js # Chrome API wrappers (85 lines)
│ └── helpers.js # General utilities (40 lines)
│
├── services/ # 💼 Business logic
│ ├── tinder-detector.js # Tinder detection (40 lines)
│ ├── stats-service.js # Stats polling (85 lines)
│ └── settings-service.js # Settings management (60 lines)
│
├── components/ # 🎨 UI components
│ ├── status-badge.js # Status indicator (35 lines)
│ ├── stats-display.js # Stats display (30 lines)
│ ├── controls.js # Buttons & sliders (95 lines)
│ ├── mode-selector.js # Mode selection (50 lines)
│ └── navigation.js # Navigation buttons (35 lines)
│
└── state/ # 📊 State management
└── app-state.js # Centralized state (125 lines)
Total: ~905 lines across 13 focused files Old: 417 lines in 1 monolithic file
┌─────────────────────────────────────────────────────────────┐
│ index.js │
│ (Main Orchestrator) │
│ • Initializes all services, state, and components │
│ • Sets up callbacks and event listeners │
│ • Coordinates application lifecycle │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ app-state.js │
│ (State Management) │
│ • Centralized state (isActive, stats, settings) │
│ • Provides callbacks for state changes │
│ • Batches UI updates for performance │
└─────────────────────────────────────────────────────────────┘
│
┌─────────────┼─────────────┐
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Services │ │ Components │ │ Utils │
└──────────────┘ └──────────────┘ └──────────────┘
User Action (Click/Input)
│
▼
┌─────────────────┐
│ Component │ ◄─── Event Listener
│ (controls.js) │
└─────────────────┘
│
▼
┌─────────────────┐
│ Service │ ◄─── Business Logic
│ (settings.js) │
└─────────────────┘
│
▼
┌─────────────────┐
│ Chrome API │ ◄─── Send Message to Content Script
│ (chrome-api.js) │
└─────────────────┘
│
▼
┌─────────────────┐
│ App State │ ◄─── Update State
│ (app-state.js) │
└─────────────────┘
│
▼
┌─────────────────┐
│ Components │ ◄─── UI Update via Callbacks
│ (all UI files) │
└─────────────────┘
- dom.js: DOM element caching, manipulation helpers
- chrome-api.js: Chrome extension API wrappers
- helpers.js: Debounce, throttle, formatting utilities
- tinder-detector.js: Detects if user is on Tinder
- stats-service.js: Loads and polls statistics
- settings-service.js: Manages settings updates
- status-badge.js: Active/inactive status display
- stats-display.js: Statistics visualization
- controls.js: Toggle, speed slider, stealth checkbox
- mode-selector.js: Swipe mode selection
- navigation.js: Navigation buttons
- app-state.js: Centralized state management with callbacks
- index.js: Initializes and coordinates everything
Each file has ONE clear purpose. Easy to understand what each module does.
- Bug in stats display? → Check
stats-display.js - Issue with settings? → Check
settings-service.js - DOM performance problem? → Check
dom.js
Each module can be unit tested independently:
// Test stats-display.js
import { StatsDisplay } from './components/stats-display.js';
// Test in isolationUtils and services can be reused across different parts:
// Use debounce in multiple components
import { debounce } from './utils/helpers.js';Adding new features is straightforward:
- New UI element? → Add component
- New business logic? → Add service
- New utility? → Add to utils
- DOM elements cached once
- Updates batched using requestAnimationFrame
- Only changed values updated
- Smart polling with RAF
popup.js (417 lines)
├── DOM caching
├── Event listeners
├── Chrome API calls
├── Stats polling
├── Settings management
├── UI updates
├── State management
└── Everything mixed together ❌
popup/ (13 files, ~905 lines)
├── Clear separation of concerns ✅
├── Easy to find and fix bugs ✅
├── Testable modules ✅
├── Reusable components ✅
└── Scalable architecture ✅
Example: Add a "Pause Timer" feature
-
Add utility (if needed)
// utils/helpers.js export function formatTime(seconds) { ... }
-
Create service
// services/timer-service.js export class TimerService { ... }
-
Create component
// components/timer-display.js export class TimerDisplay { ... }
-
Update state
// state/app-state.js this.pauseTime = null;
-
Wire up in index.js
this.timerService = new TimerService(); this.timerDisplay = new TimerDisplay();
- ✅ ES6 Modules: Proper import/export
- ✅ JSDoc Comments: Every function documented
- ✅ Consistent Naming: Clear, descriptive names
- ✅ Error Handling: Proper try-catch blocks
- ✅ Performance: Optimized DOM operations
- ✅ Separation: Clear boundaries between layers
This refactor demonstrates:
- How to break down monolithic code
- Proper separation of concerns
- Service-oriented architecture
- Component-based UI design
- Centralized state management
- Performance optimization techniques
Old Code: 417 lines, everything mixed together New Code: 13 focused modules, clear architecture Result: Maintainable, scalable, professional codebase ✨