Firefox/SVG Asset Optimization

From MozillaWiki
Jump to: navigation, search

This page is about the production and optimization of SVG assets for use in Firefox UI.

Background

The SVG output from most drawing applications requires optimization before it can be committed to mozilla-central. As SVG is a text format, SVG files are subject to code review, and need to be readable and file-size kept to a reasonable minimum.

Film-strip Animations

Many of the new UI animations added in Firefox 57 ("Quantum") used a "film strip" technique to get pre-rendered, 60fps animation that could run entirely on the compositor and off the main thread. These SVG files were typically a horizontal strip of frames, each frame offset on the x-axis by frame index * frame width. To play the animation, the CSS transform property is updated to translateX to a value that places the current frame at 0,0 in a cropped element. This technique is explained and illustrated here.

There are many ways to create and optimize the output assets for these animations. The toolchain we used was a mix of existing tools and custom scripts and processes:

Asset preparation process

The framing and motion design was done in After Effects, and exported using the BodyMovin plugin to a SVG-as-json format.

This JSON-SVG tool imports the data exported by BodyMovin, creates a SVG document and plays the animation in order to generate the static frames. The output can be saved from the browser.

SVGO was used to optimize these rather bloaty documents down to a more appropriate size. SVGO uses a plugin architecture to string together a series of optimization steps, based on a config file. The goal is to:

  • Eliminate any proprietary markup, vendor metadata, comments
  • Simplify DOM - eliminating unnecessary and hidden elements and flattening out nested structures
  • Convert shapes and pre-apply and consolidate transforms to paths

SVGO is a generic optimization tool. Which plugins to use and the order to apply them depends on the specific input given and desired output. What works for one image may not for another - this is not a push-button-get-result kind of operation. Each image or animation will likely need config tweaks, possible manual post-processing and careful preview to ensure detail isn't lost in the optimization. For the filmstrip images and this workflow there are specific considerations:

  • Remove moz-select attributes that are added when saving from the browser
  • Replace specific color values with context-fill and context-stroke. See this tool for help picking colors to substitute and previewing the result
  • Add the mozilla license
  • De-duplicate repeated paths. These animations frequently involve many frames which move a entire shape, or transform the color of a shape and we can use a path and use href to define and reference these paths once rather than inlining these long paths in every frame.

Some of these steps are trivial to perform manually (like adding the license), or search/replace to swap out designated colors for context-fill/context-stroke. The path de-duplication is amenable to scripting if the need arises. There are a couple of possibly-useful plugins in a fork of the SVGO repo. The repo includes asample config file. Usage like so:

 ./bin/svgo --config=your.config --input=/path/to/file.svg --output=/path/to/optimizes/file.svg