Wolstenhol.me as a Vue application

Some notes for the Manchester FRED show and tell session:

  • https://wolstenhol.me is a Vue application, replacing a Drupal site that was a pain to keep updated.
  • Free SSL and optimisations from Cloudflare, free hosting and deployments from Netlify, free private Git from Bitbucket, free image CDN and processing from Cloudinary.
  • Netlify is amazing — connected to my Bitbucket account so pushes to my master branch automatically run a deployment. My build scripts (npm and Python scripts) all run on Netlify and it does versioned deployments so I can roll back at any time. It has cool little extra features like webhooks so I get a Facebook Messenger message if a build fails.
  • Built using Chris Fritz’s vue-enterprise-boilerplate which is a great starting point for a Vue app. It helps you get your structure right, and adds some examples of nice ways to do things. Also comes with lots of nice linting tools and IDE config for VS Code.
  • It starts as a single page Vue application and ends as a static HTML page. I use Vue to build the page’s components, listings etc, but as part of the Webpack configuration prerender-spa-plugin prerenders it to static HTML (this post gives a really good guide to getting it set up.)
  • This makes it super fast as the browser doesn’t need to run the Vue code, construct a virtual DOM, and then create the actual DOM. The markup for the application is already in the index.html and Vue ‘rehydrates’ on load
  • The site has dynamic content (Medium, Instagram, Spotify, Foursquare, Twitter feeds), but this is refreshed with an hourly Netlify build, triggered by IFTTT, so there is no server side or client side API calls involved with serving a request. The content looks dynamic but it’s really static.
  • Having a static HTML output and no dynamic content that changes between builds means I can do some cool stuff for performance:
  • PurgeCSS is used to remove unused CSS classes. This is useful as I’m using Tachyons, a library of utility-first classes. At some point I’ll probably switch to Tailwind CSS as I like how easy it is to configure in JS.
  • Subfont is used to build custom versions of the Google Fonts in use on the page, subsetted to only contain the characters that my content actually uses. Saves around 54kb of font weight, and allows me to use font-display: swap which is hard to do with CDN loaded Google Fonts otherwise.
  • A lot of the social feed content is shown in a custom slider component that I made in Vue. It uses native scrolling so should be pretty smooth, and it uses CSS scroll-snap properties to make the slider scroll to the edges of slider items without any custom JS for this (in supported browsers). Chrome 69 will bring scroll-snap to Chrome which will be great.
  • The music feed is based on what I’ve been listening to on Spotify for the last week or so. Uses Last.fm to get the data, and the Spotify API to get the artist photos and a 30 second preview of their top track on Spotify. The track is playable using Howler.js (a web audio API library). The Spotify API can provide the BPM of a track, and this is used to animate the track component as it is playing. Faster tracks will animate faster than more chill tracks.
  • Tweets are shown in a custom Vue component that I made rather than as embedded tweets. This gives me more control over styling and media playback.
  • It’s a PWA, powered by the Vue CLI PWA plugin. I tried to cache the media items offline but had trouble doing it, especially the videos.