npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

unfont

v0.1.1

Published

Render Font Awesome to static HTML. No JS runtime, no webpack.

Downloads

10

Readme

unfont

Embed Font Awesome icons into HTML with inline SVG:

  • Zero runtime JS
  • No webpack required
  • Instantly displays icons during page load
  • Up to 10x (–12.5KB) smaller than the SVG + JS core
  • Every HTML page loads just the icons it needs
  • Streaming HTML support
  • Inline styles option for even smaller bundles
  • Works with any node-based templating.

Font awesome now has 1600+ icons in the free pack, pushing the bundle to ~200K — a lot of code to only use a couple of icons. It also takes a while to load, and the icons are not rendered while it's loading. Font awesome's SVG + JS core is a JS runtime that dynamically replaces <i> with inline SVG. Smart, but extra 40K (13K gzip) of JS is not always welcome, and still leaves your users with missing icons during script load.

As a lightweight alternative, I made this package that renders font awesome icons into inline SVG during HTML generation. It comes with the standard tradeoffs of inline SVG (no caching), but works well for static HTML websites, and is a perfect fit for critical content.

Table of Contents

Basic usage

Play around with unfont in the sandbox (but please don't use it client-side)

Install:

$ npm i --save unfont
$ yarn add unfont

Import CSS into your styles bundle (it's just copied over from @fortawesome/fontawesome-svg-core, no need to duplicate if you already run SVG + JS runtime):

@import 'unfont/css/fs.css';

You can also import it from JS or <link> to it as per your build setup.

Use in your template:

const { fa } = require('unfont');

// instead of <i class="fab fa-twitter"></i>
fa('fab fa-twitter'); // returns inline SVG to directly put into your HTML

Add custom classes:

fa('fas fa-camera fa-2x'); // <svg class="... fas fa-camera fa-2x">
fa('fas fa-camera block__icon'); // <svg class="... fas fa-camera block__icon">

Add attributes:

fa('fas fa-camera', {
  attributes: { 'id': 'camera-icon' }
});
// <svg id="camera-icon">

Add inline styles:

fa('fas fa-camera', {
  styles: { 'color': 'red' }
});
// <svg style="color: red">

Dynamic node SSR (express & co) should work out of the box, but make sure to run your own performance / load tesing and cache as needed, since it's not a primary use case and rendering may be expensive.

Client-side use makes no sense. If you really have to, try rendering icons for dynamic display into a hidden container and using their innerHTML. Never import unfont js into your client bundle.

Inline styles mode

If you only use a few fa- utility classes here and there, or rely on inline styles for critical content, you can opt into inline styles mode with inlineCss option:

fa('fas fa-camera fa-2x', { inlineCss: true })
// <svg style="display: inline-block;font-size: 2em;height: 1em;overflow: visible;vertical-align: -0.125em;width: 1em;">

This works by statically evaluating font-awesome styles for the given class and should support all fa-* utility classes and respect the styles option. The downside is that you can only override the styles with !important or more inline styles, so existing styling might break.

To use fa-spin or fa-pulse, include unfont/css/faSpin.css for the @keyframes. These styles can also be inlined into a <style> tag using a string exported from require('unfont').faSpinCss. It's a tiny CSS of 376 (120 gzip) bytes.

Comparison with standard FA runtimes

A benchmark with 10 icons produces the following bundles (all sizes in K):

| | unfont inlineCss | unfont | FA SVG + JS | FA font | |----------------|------------------|---------------|-----------------|----------------| | HTML (gz) | 9.3 (3.0) | 6.2 (2.9) | 0.5 (0.3) | 0.5 (0.3) | | CSS (gz) | | 7.8 (1.4) | | 60 (13) | | JS (gz) | | | 43.2 (15.1) | | | Woff2 | | | | 168 | | Total (gz) | 9.3 (3.0) | 14 (4.3) | 43.7 (15.3) | 228 (182) |

  • Default unfont bundle is 3.5 times smaller than SVG + JS core version. No matter how many icons you have, you get rid of the 12.5K gz JS runtime.
  • Comparison with the font version is not even fair (50x difference).
  • inlineCss version is another 1.5 times smaller than the default, or only 20% of SVG + JS core.
  • Unfont displays the icons instantly, while both fa versions have a gap when the icons are missing.
  • Both unfont setups generate 2.5K extra HTML, which is fine.

In a Slow 3G + 6x CPU Slowdown emulation without cache, icons are displayed @ 11s for font, 5s SVG + JS core, 4s unfont base, 2s unfont inlineCss. unfont only shows the page once the icons are ready, so no FOUC.

Why not...

  • <img src="..."> / background-image: url(...) generate a request per icon, have FOUC while loading, and are difficult to style.
  • CSS data-URI is difficult to style, which is a pity. Also, interpolating JS calls into CSS is tricky.
  • Directly imported FA SVG can not add attributes and classes. Also, importing SVG from dynamic path in node is tricky.
  • SVG sprite in HTML reduces raw HTML size, bu gzip already handles SVG duplication well. I have not seen a significant change in FCP / FMP when applying this technique. Also, harder to manage, and prevents streaming HTML in dynamic SSR.
  • Remote SVG sprite sounds like a decent option, but I need too investigate further regarding FOUC & actual performance.

License

Built by Vladimir Klepov @thoughtspile

MIT License