Skip to content

SVGO optimisation suggestions #2

@NedkoChulev

Description

@NedkoChulev

Taken from: https://www.reddit.com/r/webdev/comments/1mnz3o2/the_most_efficient_way_to_do_icons_in_web_apps/n897raw/

There are two further big optimisations you could perform:

1) Reducing SVG paths using SVGO

Currently the icons are made of multiple SVG elements.
Using the `a-arrow-down` icon as an example:

<svg \[ ...params... \] >  
  <path d="m14 12 4 4 4-4" />  
  <path d="M18 16V7" />  
  <path d="m2 16 4.039-9.69a.5.5 0 0 1 .923 0L11 16" />  
  <path d="M3.304 13h6.392" />  
</svg>

Using SVGO this could be reduced to:

<svg \[ ...params... \] > 
  <path d="M9.7 13H3.3M11 16 7 6.3a.5.5 0 00-1 0L2 16M18 7v9m4-4-4 4-4-4"/>
</svg>

2) Storing the single path for each icon in an array of strings

export const icons = {
  aArrowDown: "M9.7 13H3.3M11 16 7 6.3a.5.5 0 00-1 0L2 16M18 7v9m4-4-4 4-4-4",
  aArrowUp: "M9.7 13H3.3M11 16 7 6.3a.5.5 0 00-1 0L2 16M18 7v9m4-5-4-4-4 4"
} as Record<string, string>; 

Then in you just need a single React component that takes the name of the icon path as a reference. For example:

import { PATHS } from "./icon-paths.ts";

export function renderIcon(
  id: string,
  width: Dim,
  height: Dim,
  size: Dim,
  props: IconProps
) {
  return (
    <svg
      {...props}
      {...(size != null ? { width: size, height: size } : {})}
      {...(width != null ? { width } : {})}
      {...(height != null ? { height } : {})}
    >
      <path d={`${PATHS[id]}`} />
    </svg>
  );
}

Because the icons are stored as strings and only rendered when needed this will also be more efficient for the browser to render.

I wrote a long post about how to heavily optimise SVG icons for clarity and efficiency.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions