How we deal with icons on BestPrice.gr

The part that involves making the initial, fundamental decisions for a project, is the most important one in a project’s life-cycle.

High-level decisions and thus the level of abstraction that is to be followed defines what, what-not and how to build your project. I always emphasize on the “what not” part, by the way.

In other words, this stage involves both risk assessment and figuring out the trade-offs that will come into play when establishing the building blocks of the project.


One of those decisions we made when we started building the new BestPrice.gr was that we should not support legacy browsers, i.e IE < 10.

In a nutshell, we wanted BestPrice.gr to gaze at the future, not at the past. We wanted the development team to work with cutting-edge APIs and technologies and not to be limited by the past, because that’s both draining and definitely not pleasing.

There’s a lot more to be said on how we reached this decision, however this post is about icon generation so let’s get right on it.


Dropping support for legacy browsers, (also) enabled us going for “svg-only” (mobile-first was a no brainer).

What that means is:

We shall not use bitmap images or icon fonts to cover our icon needs. Period.

Thing is, working with SVGs can be tricky for a great deal of reasons, be they about browser incompatibilities or the icon generation itself.

However, working with icons — as with anything else — had to be simple.

And simple it got.


Here’s how we deal with icons on BestPrice.gr:

  • We have 2 sketch files: one that includes the icons used in filters and one for all the rest.
  • Each file is broken down into pages, based on context. Each page contains icons as art boards with icons in various, predefined, sizes.
  • Icons are either added or altered in these files on demand.

When changes are pushed to those files and are detected:

  1. A gulp script generates svg icon files from these sketch files, based on the artboard names and naming policies we have defined.
  2. Another gulp task combines all the icons into a single svg file having all icons as symbols.
  3. The svg file is then optimised using svgo (remove fills, cleanup tags, normalize paths etc), again based on rules (for example we preserve the fills in some cases)
  4. A commit and a push makes sure the files are on Github.
The gulp task

Finally, when the build process kicks in to initiate bundling and build processes:

At this stage, the symbol files are named using the content hash and pushed to our live servers (CDN).

This whole generation process takes around 1.5 seconds and is triggered whenever new icons are added or an existing one is updated.

Now, when it comes to front end, there are a couple more challenges.

One of those is the fact that not all browsers support referencing symbols from an “external” file. That said we had to identify those cases server-side and load the svg master file(s) in page.

Of course symbol referencing is the ideal scenario and most modern browsers support this case.

Unfortunately, a long-standing bug, forced us to avoid using our CDN for hosting the file, but the overhead was small enough not to care.

Now, time to deal with rendering.

We had three environments to deal with

  • React
  • Server-side (php)
  • Vanilla JS

For each of those cases we came up with an implementation (signature) that uses the same semantics and provide an easy way to render those lovely icons.

Here are some examples:

JSX (React)
PHP
Vanilla JS (ES6)

Conclusion

Being able to separate concerns and eliminate worries and (traditional) bottlenecks is critical for big projects.

Introducing a little bit of magic let’s you worry about actual, creativity-demanding issues and challenges and forget about tasks that should have minimal impact in your experience as a developer.

ps: we are following a rather similar, yet more complicated process, for image handling and optimizations. More on this in a later post.


Join us! We are hiring!

Show your support

Clapping shows how much you appreciated George Papadakis’s story.