This project contains a contacts table application that displays and updates contact information in real-time. The table receives frequent updates from a service that mimics server-sent events (SSE) behavior. Currently, the high frequency of update events causes browser memory overload and performance degradation when updates are processed directly in the main thread.
The application includes a ContactsMemoryUsage.vue component that monitors browser memory in real-time and displays warnings when memory usage exceeds 80MB.
The contacts-updates.service.ts generates frequent update events for table cells (identified by rowId, colId, and new value). When the application subscribes to these events directly in the Contacts.vue component (see commented code), the browser's memory usage spikes and performance degrades significantly due to:
- High frequency of DOM updates (each event triggers a separate reactive update)
- Main thread blocking
- Memory pressure from rapid object allocations
Implement a Web Worker solution that:
- Moves the event listening logic off the main thread
- Maintains a queue of incoming updates
- Processes the queue every 500ms and sends a strict batch size to the main thread
- Maintains the existing data management architecture
- Create a Web Worker (
contacts.worker.ts) that handles update event subscriptions - The worker MUST import and use the existing
contactsUpdatesService.listenUpdates()method to subscribe to events - The worker should NOT reimplement the service's internal logic (e.g., don't directly call
getRandomCellUpdateor create your own update generation logic)
- The worker must maintain a queue that accumulates all incoming update events
- Every 500ms (strict interval), the worker must process the queue
- Batch Size: Define a strict batch size (e.g., 100 updates per batch)
- Sending Logic:
- If the queue has ≥ batch size items: send exactly batch size items, keep the rest in queue
- If the queue has < batch size items: send all available items
- If the queue is empty: don't send anything
- After sending a batch, remove only the sent items from the queue
- The remaining items stay in the queue for the next interval
- Implement a clear message protocol between main thread and worker:
- START: Begin listening to updates and batching
- STOP: Stop listening and clean up resources
- UPDATES: Message type for sending batched updates to main thread
- Use the existing
contactsStore.patchRow()method to apply each update - No modifications to store logic or data structures
- Memory Usage: Solution must keep memory consumption below 80MB threshold
- The
ContactsMemoryUsage.vuecomponent monitors memory usage and displays spikes above 80MB - A successful implementation should show NO memory spikes (memory stays under 80MB)
- The
- Responsiveness: Main thread should remain responsive during heavy update loads
- Worker must properly clean up all intervals and listeners on STOP
- No memory leaks from unclosed intervals or event listeners
- Worker must be properly terminated when component unmounts
- No modifications to existing services:
contacts-updates.service.tsmust remain unchangedcontacts.store.tslogic must remain unchangedcontacts-table.fixture.tsmust remain unchanged
- Clear separation of concerns between worker and main thread
- Well-defined message protocol
- Readable code
- Complete the task, commit it to your personal GitHub repository, and deploy it to any Vue.js sandbox of your choice for easier review and validation.
- DO NOT modify
contacts-updates.service.ts - DO NOT modify the store's data fetching or storage logic
- DO NOT modify the table rendering components
- DO use the existing
contactsUpdatesService.listenUpdates()andcontactsUpdatesService.stopListening()methods - DO maintain the existing update data structure:
{ rowId: string, colId: string, value: string }