Illustration by Johan Gunnarsson

Election time: Do Swedish political parties’ websites keep their User Experience promise?

Read on about how parties fail to deliver good technical user experiences to their users, which is alarming in terms of bad performance (increasing data costs), security and accessibility.

The “right thing” is to be fast, accessible and secure. Even more so if you run the website of a political party in a democracy where almost everyone is online.

The parties examined

Factors examined

  • Performance
  • Accessibility
  • SEO
  • Security
  • Images

Want to see the data?

Notes on testing

Analysis

What systems do the parties use?

Performance

Load times using “Applied Fast 3G” setting on an emulated Nexus 5X mobile via Lighthouse
Request counts, captured with Chrome’s Network panel

Accessibility

SEO

Security

Images

No one except Socialdemokraterna (read below) seem to use modern image services like Cloudinary which makes it possible to query a specific size rendition of a given image, together with a specific compression quality. This is absolutely brilliant, as it removes the hassle of exporting various size images as content editors have been forced to do for a long time. With that in place, images can be requested with relevant size and quality parameters directly from code. Doing it from code also makes dynamic fetching of just the right size image possible in real-time, rather than providing one image which is either way too big or goes the middle-way of being at best acceptable on most screens.

Suggestions

What is the “sweet spot” to aim for?

  1. The fastest bytes to deliver are the ones that never need to be delivered: Remove unused parts (and dev-specific code), the rest should be heavily minified and delivered with HTTP2 using gzip or brotli/zopfli compression. Page weight is directly related to the user’s data plan cost, and you are therefore responsible for doing your part in keeping costs down.
  2. If something is loaded once, it should never be a “tax to be paid” again. Cache everything — reloads and revisits should be immediate and carry as close to a zero-byte cost as possible.
  3. If the user doesn’t see it, they don’t want it (nor need it) loaded. Use patterns like route splitting and lazy-loading to avoid loading unnecessary bytes.
  1. Distrust -everything- both internal and external to your domain and only make exceptions for the very exact things that should be allowed (a so-called “whitelist policy”).
  2. Security is not just for you, it’s for the user too. Misusing this trust is therefore a violation you inflict on your user as well.
  3. Reduce the number of moving and exposed parts. Sensitive information behind logins, such as FTP, and well-known targets like WordPress are extremely vulnerable and should be replaced with other alternatives. Private or small-scale servers are also ripe for attacks and suffer from not having big backbones that can defend them.

What specifically could the parties do?

  • Use static hosting to minimize your attack surface. Services include Netlify, Firebase Hosting, Amazon S3, or Zeit Now. With these you can do atomic rollbacks so if you are ever hacked, you can just go back to your last set of files. A static host entirely sidesteps the problem of someone destroying or tampering with your files.
  • Run frequent tests, especially during development, to audit performance, security and accessibility. Running them often makes problems visible quicker and helps resolve issues faster. Good tools include Lighthouse, Mozilla Observatory, Security Headers, GT Metrix, Sitespeed.io, and pa11y.
  • Consult the Infosec subsite at Mozilla which has details on both technical and human-to-human aspects of security.
  • Use a serverless backend like Amazon Lambda functions or Google Cloud Functions to make it harder to attack key functionality and harder to pinpoint where the server is and what it does. Also, you get the upside of avoiding to handle your own server security.
  • Use a headless CMS (such as Contentful, Prismic, or Sanity) together with automated content backup in order to let the service provider cover security concerns.
  • Use Cloudflare or another service that does good DDOS deflection.
  • Use a Content Delivery Network (CDN) to deliver content faster, and consider sharding out to CDNs that may pose less risk of attack. CDNs are often provided as part of a static hosting service.
  • Conduct normal production code hygiene: minify and bundle (consider Webpack) all code to make page loads much faster; strip all console logging (etc.) from your public code.
  • Use Snyk or some other vulnerability detector to find dependencies that may pose security risks.
  • Stop using harmful third-party code for things like undue tracking, analytics, and beacons—at the very least minimize and make sure it’s GDPR compliant so zero tracking happens without explicit user consent. “Vanity packages” with unnecessarily heavy features (common with calendars, carousels, and the like) should be removed and replaced with modern, small alternatives, then bundle and serve code from your own domain. If you DO use external scripts, for example from a CDN, give it a Subresource Integrity hash.
  • Use a rigid Content Security Policy and set long-expiry caching headers. Take a look at Hisec for a starter that provides an A+ level boilerplate.
  • Use a modern image service like Cloudinary, or a CMS like Contentful that provides parameterized images (so you can fetch compressed, correct-sized images in your code with no work from a Content Editor).
  • Avoid jQuery which is bloated and a major security risk. Use a fast, modern rendering library like React, Vue or Angular 5 instead. If you’re not using a rendering library, switch jQuery for plain vanilla Javascript.
  • Don’t keep data, if at all possible. Avoid FTP and any other file management systems that are basically open holes into your private files. Consider sharing files via cloud services with serious credential management, or send encrypted short-lived links for regular file transactions with WeTransfer.
  • Use service workers together with pre-caching to dramatically improve reload speed.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Mikael Vesavuori

Cloud Software Architect (and Technical Standards Lead) at Polestar