Skip to content

mcost45/tune

Repository files navigation

Tune - The Spotify Recommendations Web App

An Angular Ionic PWA

NOTE: To test out this app, your Spotify email must be added to the list of authorised users beforehand. Contact me if you would like to try.

preview.mp4

Key Features and Components

  • 'Tinder-swiper' card-based music recommendation, determined by the users' favourite artists and tracks
  • 'OAuth PKCE flow' used for Spotify account authorisation
  • recommended track music previews played, via AudioContext
  • recommended track visualisations, utilising metadata for:
  • reliance on reactive programming via RxJS for asynchronous event handling
  • 'IndexedDB' and 'localStorage' are utilised for maintaining some basic data across sessions
  • basic error handling on failed networking or authentication
  • basic PWA capabilities (i.e. Service Worker)
  • logging and dynamic env configuration
  • 'ii8n' via ngx-translate
  • integrated with (deployed via) Firebase
  • supports Chrome (+Edge), Firefox and Safari
  • reactive design, suitable for desktop and mobile devices
  • 'lint-staged', 'ESLint' and 'Prettier' utilised for linting setup
  • codebase complies with strict Typescript and Angular rules

Performance Considerations

UI Thread:

  • if the browser supports Web Worker OffscreenCanvas, the calculations to fetch, convert and determine an album art's average colour are processed on a separate thread
  • after a new card is loaded (and painted), only fast GPU compositor rendering events will occur on card interaction (avoiding Paint and Layout on interactions such as drag and hover), with CSS transforms and conservative 'will-change' usage
  • utilise CSS 'contain' to help to improve rendering time

Networking:

  • multiple network requests are executed in parallel where possible (when they have no sequential dependencies) with 'Promise.All'
  • where possible, all networking requests are batched to maintain low rates (i.e. when a track is 'liked' no call is fired until the current batch of liked ids gets flushed - either triggered by timeouts or exiting the page)
  • assets are compressed where possible
  • utilise preloading/prefetching for essential domains such as 'https://api.spotify.com'
  • utilise fetch priority hints
  • abort no-longer necessary fetch requests

Angular:

  • always use 'onPush' change detection
  • run code outside of Angular's zone if it would trigger unnecessary change detections (i.e. for handling events such as card hovering)
  • rely on pure pipes for template transformations
  • modules are split and utilise lazy-loading to avoid excessive payloads
  • ensure all observables are completed to prevent leaks

Event handling:

  • ensure all event listeners are removed to prevent leaks
  • for handling all card events, listeners are added on a single wrapper element - relying on bubbled events - rather than listening to each card