Skip to main content

Frontend Architecture

The frontend of the Tracker GraphQL application is built using vanilla JavaScript with a focus on performance, modularity, and real-time capabilities. This document outlines the key architectural decisions and implementation details.

Project Structure

The frontend codebase is organized into logical modules and components:

app/static/
├── js/
│ ├── components/ # UI Components
│ ├── services/ # Data services
│ ├── state/ # State management
│ ├── utils/ # Utility functions
│ └── graphql/ # GraphQL queries/mutations
├── css/ # Stylesheets
└── index.html # Entry point

Design Principles

  1. Vanilla JavaScript: The application uses pure JavaScript without frameworks, reducing bundle size and improving performance.
  2. Modular Architecture: Code is organized into reusable components and services.
  3. Event-Driven: Components communicate through a custom event system for loose coupling.
  4. Performance First: Implements various optimization techniques to ensure fast loading and smooth user experience.

Performance Optimization

Resource Loading

The application implements several strategies to optimize resource loading:

<!-- Resource hints for faster connections -->
<link rel="preconnect" href="https://cdn.jsdelivr.net" />
<link rel="preconnect" href="https://unpkg.com" />

<!-- Critical CSS inlined for above-the-fold content -->
<style>
/* Critical styles here */
</style>

<!-- Optimized CSS loading -->
<link rel="preload" href="./index.css" as="style" />

Web Vitals Monitoring

Performance is monitored using Web Vitals metrics:

// Track Core Web Vitals
webVitals.getCLS(console.log); // Cumulative Layout Shift
webVitals.getFID(console.log); // First Input Delay
webVitals.getLCP(console.log); // Largest Contentful Paint

Virtual Scrolling

Instead of traditional pagination, the application implements an advanced virtual scrolling system for handling large datasets efficiently. This approach significantly improves performance and user experience.

Key benefits:

  • Only renders visible rows in the viewport
  • Dynamically manages data loading
  • Maintains smooth performance with large datasets
  • Optimizes memory usage and DOM performance

For detailed implementation and technical specifications, see Virtual Scrolling Implementation.

Data Management

GraphQL Integration

The frontend minimizes GraphQL API calls through several strategies:

  1. Batched Queries: Combines multiple data requirements into single queries
  2. Selective Field Selection: Only requests needed fields
  3. Caching: Implements client-side caching to reduce redundant requests

Caching Strategy

The application implements a sophisticated caching system that optimizes data access and improves performance.

Key features:

  • In-memory caching of API responses
  • TTL (Time-To-Live) support
  • Cache invalidation on updates
  • Selective cache updates
  • Memory usage optimization

For detailed implementation and technical specifications, see Frontend Caching System.

Real-time Updates

Socket.IO integration enables real-time data updates:

  1. Connection Management: Handles reconnection and session management
  2. Event Handling: Processes real-time events and updates UI
  3. State Synchronization: Maintains consistency between server and client

UI Components

Asset Table Component

The asset table component demonstrates the application's architecture:

  1. Virtual Scrolling:
class VirtualScroll {
constructor(container, itemHeight) {
this.container = container;
this.itemHeight = itemHeight;
this.visibleItems = Math.ceil(container.clientHeight / itemHeight);
this.buffer = this.visibleItems * 2;
}

render(scrollTop) {
const startIndex = Math.floor(scrollTop / this.itemHeight);
const endIndex = startIndex + this.visibleItems + this.buffer;
// Render only visible items plus buffer
}
}
  1. Data Management:
  • Implements caching for filtered/sorted data
  • Maintains scroll position during updates
  • Handles real-time updates efficiently

Map Component

The map component showcases real-time location tracking:

  1. Lazy Loading: Map resources loaded only when needed
  2. Clustering: Efficiently handles multiple markers
  3. Real-time Updates: Smooth animation for location changes

Activity Panel

The activity panel demonstrates real-time event handling:

  1. Event Queue: Manages incoming real-time updates
  2. Smart Updates: Batches multiple updates for efficiency
  3. State Management: Maintains consistent UI state

Stats Display Component

The stats display component visualizes key metrics including duration tracking data (see Duration Tracking Guide for implementation details):

  1. Duration Visualization:
// Update progress bar
updateProgressBar(element, value) {
if (element) {
const percentage = Math.min((value / 30) * 100, 100);
element.style.width = `${percentage}%`;
}
}
  1. Data Transformation:
  • Converts duration hours to days for user-friendly display
  • Implements progress bars with a 30-day maximum (100%)
  • Formats numerical data for readability
  1. Store Integration:
  • Subscribes to status counts and duration statistics
  • Updates UI elements when data changes
  • Maintains consistency with filtering applied to tracker list
  1. Animation:
  • Implements smooth transitions for stats updates
  • Uses CSS transforms and opacity for visual feedback
  • Provides subtle visual cues for data changes

Filter Manager Component

The filter manager component provides advanced filtering capabilities for the tracker list:

  1. Typeahead Implementation:
// Typeahead creation with custom rendering and event handling
createTypeahead(input, {
getItems: (searchTerm) => {
const brandsData = store.getBrandsData();
// Filter and return matching items based on search term
return items.filter((item) =>
item.name.toLowerCase().includes(searchTerm.toLowerCase()),
);
},
renderItem: (item) => `${item.name} (${item.client.name})`,
onSelect: (item) => {
// Update store and UI when item is selected
store.updateFilters({ brandId: item.id });
},
});
  1. Filter State Management:
  • Integrates with application store for persistent filter state
  • Handles complex filter dependencies (e.g., campaigns depend on selected brand)
  • Provides methods for adding, removing, and clearing filters
  • Maintains filter state across page refreshes
  1. Visual Filter Representation:
  • Creates interactive filter chips for active filters
  • Implements consistent styling with status-specific colors
  • Provides clear visual feedback for filter actions
  • Supports keyboard navigation and accessibility
  1. Multi-filter Coordination:
  • Synchronizes multiple filter inputs (e.g., dropdown and typeahead)
  • Handles filter conflicts and dependencies
  • Updates related filters when primary filter changes
  • Maintains consistent filter state across all UI components
  1. Event Handling:
  • Uses custom event manager for clean event binding
  • Implements proper cleanup to prevent memory leaks
  • Handles outside clicks for dropdown dismissal
  • Provides debounced input handling for performance

Conclusion

The frontend architecture prioritizes:

  • Performance through virtual scrolling and efficient resource loading
  • Real-time capabilities with Socket.IO integration
  • Scalability through modular component design
  • User experience with responsive updates and smooth interactions
  • Data visualization for key metrics including duration tracking
  • Advanced filtering with typeahead search and visual filter representation