In our first brainstorming sessions for our own website, we already had a pretty clear vision of what we would expect from it:

Concept:

  • Mobile-first design as most visitors use their phones or tablets to browse
  • High performance, low time-to-interact, small footprint
  • Accessibility
  • Dark theme because we like to work at night

Technology:

  • Component-based development do DRY up the code and easy maintenance
  • SEO
  • Static pages and dynamic content like our portfolio, blog posts etc.
  • CI/CD pipeline for automated deployment

And last but not least, we wanted something that is fun to work with. We are our own customer here, so we can do whatever we want!

We are very experienced in working with frameworks like Angular, making this a natural first choice as tech stack. But Angular is a framework primarily meant to build extensive and state-driven Single Page Applications and because we would not use much of the functionality coming with that, we decided to avoid additional overhead. Applications built with Angular are pretty large compared to other solutions and because payload size is important to us, we decided to try something else.

Prototyping

After discussing the general style and wording of the page, we immediately started building a prototype. We used a mixture of static HTML, JavaScript and CSS that we then split into "light components" using Nunjucks as template engine. We then put all the pieces together in custom gulp tasks and implemented a simple CI/CD pipeline in Gitlab to build and publish the artifacts to our FTP server after every commit.

Gitlab CI/CD jobs page showing four passed pipelines for the ShipBit Website

While this was working great at first, we kept adding content and had to realize that both the footprint of our pages and the complexity of our gulp tasks were growing linearly. We started to implement code-splitting, so that only required assets would be loaded depending on the page you were visiting. This further complicated our build pipelines and also the complexity of our "components".

One thing we really liked though, is the fact that this was now basically a DIY static site generator that needed no backend, APIs or overloaded admin interface to create content.

Moving to the final solution

All of these advantages are basically the ideas behind the Jamstack: Pre-render pages at build-time, move them to a CDN without any backend or special server requirements, let the client handle the rest.

Guess what, there are frameworks for that! Even though we already had some experience in working with the great GatsbyJS (and liked it), we decided to get our hands on something new in this non-critical environment where we are the customer. After hearing many good things about the core concepts and ideas behind it, we played around with Svelte & Sapper for a while and finally decided to migrate our page to that.

Svelte is just perfect for our usecase: Components are very simple and just consist of a script and style block and the HTML body of the component. Components are style-scoped by default and you can add global styles in a separate stylesheet or using a :global() selector. Transforming our Nunjucks templates and macros into Svelte components was easy and also created an opening for us to refactor some of the code we wrote before, reducing the overall complexity.

The Svelte API is extremely light-weight and all we really needed were a couple of lifecycle hooks and some syntax candy, allowing us to really learn it by doing. Also, built apps are really tiny because Svelte is just a compiler and adds very little overhead to your artifacts. To the contrary, it optimizes your code, for example by detecting and omitting unused styles inside of your components.

On top of Svelte, there is Sapper which is basically the "framework" part of Svelte. It utilizes RollupJS to bundle and minimize the code and brings features like routing, server-side-rendering and code-splitting into the mix. It also allows you to create static sites based on any input, just like GatsbyJS. The geeky developers we are, we immediately decided to go with Markdown for our blog posts and work examples.

With the help of Sapper's starter template, we were really quickly able to setup the page and instantly measured huge performance benefits compared to our prototype. Sapper is not as trivial to use as Svelte, so we will certainly explain some challenges we faced in other blog posts.

Google Lighthouse scores for https://shipbit.de/service: Performance 94/100, Accessibility 100/100, Best Practices: 92/100, SEO 100/100

Shipping early

It is worth mentioning that we published our page on Day 1. It was always "live", starting with the very first prototype that was nothing more than a rough sketch of the home page and navigation concept. It contained dummy texts and placeholder images, a lot of bugs and was clearly a "work in progress" for most of the time. Of course, we didn't register the page on search engines right away, nor did we promote it actively in social media or other channels.

Nevertheless, we were very motivated by the fact that we were building something real. Besides that, we could test on real devices any time during development, always feeling the immediate impacts of our work. We also showed the page to some people we know and asked them what they were thinking, gaining valuable user feedback in an early development stage.

This is exactly what ShipBit is all about: Putting products on the street as fast as possible and letting users experience both the progress and the results. We strive to use new technologies whenever we get the chance to do so because ultimately, we also want to have fun as developers.