How I reduced Raveberry's transferred frontend code by 90%

This page summarizes the projects mentioned and recommended in the original post on /r/Raveberry

Our great sponsors
  • SurveyJS - Open-Source JSON Form Builder to Create Dynamic Forms Right in Your App
  • InfluxDB - Power Real-Time Data Analytics at Scale
  • WorkOS - The modern identity platform for B2B SaaS
  • raveberry

    A multi-user music server with a focus on participation

  • For those that don't know, my side project Raveberry is a multi user music server that allows democratic selection of songs. People can download it from PyPi and setup their own instance.

  • npm

  • In this post I want to share with you the journey of how I significantly reduced the size of the frontend code used in Raveberry. For a long time, I tried to avoid the frontend ecosystem as much as possible. Stories like a transitive dependencies breaking thousands of projects or npm rendering your system unusable by changing a bunch of permissions don't really help. That's why, for a long time, Raveberry's frontend was structured pretty straightforward.

  • SurveyJS

    Open-Source JSON Form Builder to Create Dynamic Forms Right in Your App. With SurveyJS form UI libraries, you can build and style forms in a fully-integrated drag & drop form builder, render them in your JS app, and store form submission data in any backend, inc. PHP, ASP.NET Core, and Node.js.

    SurveyJS logo
  • django-compressor

    Compresses linked and inline javascript or CSS into a single cached file.

  • The external dependencies were downloaded into the static/ folder containing all frontend assets using yarn and a package.json. Other than that, yarn was not used. Next I ran a bash script that removed all files I did not need, keeping the javascript, css and font files that should be served. In html, these files where directly included. I knew that loading many files is bad, so I used django-compressor to combine them into one big file. Conveniently, this tool also provided me with a way to compile scss.

  • snarkdown

    :smirk_cat: A snarky 1kb Markdown parser written in JavaScript

  • Analyzing these dependencies, I found that some of them could be reduced or replaced. For example, jquery-ui is used for autocompletion and reordering. All additional widgets provided by jquery-ui (e.g. sliders, datepickers) are dead weight and can be excluded from the final bundle. Another example is marked, which was used to render the changelog. However, the changelog has a very simple structure and does not require a ~300KB library to be parsed. So instead, I use snarkdown, a lightweight alternative which is fully sufficient for this application.

  • berry

    📦🐈 Active development trunk for Yarn ⚒

  • The external dependencies were downloaded into the static/ folder containing all frontend assets using yarn and a package.json. Other than that, yarn was not used. Next I ran a bash script that removed all files I did not need, keeping the javascript, css and font files that should be served. In html, these files where directly included. I knew that loading many files is bad, so I used django-compressor to combine them into one big file. Conveniently, this tool also provided me with a way to compile scss.

  • fonttools

    A library to manipulate font files from Python.

  • Similar to the approach used for the css code, the fonts were also modified to only contain used symbols. A script parses html and javascript files to find used identifiers. Then, fonttools is used to create a subtyped font file with only these symbols. Since Raveberry only uses a small set of icons and Font Awesome provides a lot of them, this approach eliminates the vast majority. The resulting font files are 6.7KB and 2.3KB, much smaller than the original ones.

  • webpack

    A bundler for javascript and friends. Packs many modules into a few bundled assets. Code Splitting allows for loading parts of the application on demand. Through "loaders", modules can be CommonJs, AMD, ES6 modules, CSS, Images, JSON, Coffeescript, LESS, ... and your custom stuff.

  • To bring everything together, I use webpack to create the final bundle. It takes care of including the necessary libraries and minifies the output. I tried to use rollup but there were issues when importing only parts of jquery-ui. The final bundle.js has a size of 272KB. This is still not ideal, but since the functionality is basically identical, I consider it quite an achievement. The next step would probably be to replace jquery and jquery-ui with more lightweight alternatives.

  • InfluxDB

    Power Real-Time Data Analytics at Scale. Get real-time insights from all types of time series data with InfluxDB. Ingest, query, and analyze billions of data points in real-time with unbounded cardinality.

    InfluxDB logo
  • purgecss

    Remove unused CSS

  • Bootstrap provides css rules for a lot of html elements. Instead of serving all of it, purgecss is used to only include the necessary rules. The tool sifts through every html template and all javascript files to detect used identifiers. Everything else is removed from the resulting file, drastically reducing its size. I only had to manually prevent a few dynamically created identifiers from being removed.

  • PostCSS

    Transforming styles with JS plugins

  • Afterwards, a postcss pass minifies the css code, resulting in 21,8KB per light/dark style. In comparison to the naive approach, this amounts to almost 90% reduction.

  • marked

    A markdown parser and compiler. Built for speed.

  • Analyzing these dependencies, I found that some of them could be reduced or replaced. For example, jquery-ui is used for autocompletion and reordering. All additional widgets provided by jquery-ui (e.g. sliders, datepickers) are dead weight and can be excluded from the final bundle. Another example is marked, which was used to render the changelog. However, the changelog has a very simple structure and does not require a ~300KB library to be parsed. So instead, I use snarkdown, a lightweight alternative which is fully sufficient for this application.

NOTE: The number of mentions on this list indicates mentions on common posts plus user suggested alternatives. Hence, a higher number means a more popular project.

Suggest a related project

Related posts