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

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

Our great sponsors
  • Appwrite - The Open Source Firebase alternative introduces iOS support
  • Scout APM - Less time debugging, more time building
  • SonarQube - Static code analysis for 29 languages.
  • 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.

  • Appwrite

    Appwrite - The Open Source Firebase alternative introduces iOS support . Appwrite is an open source backend server that helps you build native iOS applications much faster with realtime APIs for authentication, databases, files storage, cloud functions and much more!

  • 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.

  • Scout APM

    Less time debugging, more time building. Scout APM allows you to find and fix performance issues with no hassle. Now with error monitoring and external services monitoring, Scout is a developer's best friend when it comes to application development.

  • 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