#Improving Web Vitals in Remix

1 messages Β· Page 1 of 1 (latest)

lethal fiber
exotic jackal
#

the example code for preconnect links is doing a preload of the CSS like the previous section

lethal fiber
#

Ops

#

Fixed.

lethal fiber
#

@exotic jackal incidentally, I was able to spend some time going through @capisizecss and @fontaine code base, and figure out how the font overrides work.

#

You use @capsize to calculate a font's metric, then make adjustments based off it.

#

https://github.com/unjs/fontaine/blob/main/src/css.ts#L51

  const declaration = {
    'font-family': JSON.stringify(name),
    src: fallbacks.map(f => `local(${JSON.stringify(f)})`),
    // 'size-adjust': toPercentage(sizeAdjust),
    'ascent-override': toPercentage(
      metrics.ascent / (metrics.unitsPerEm * sizeAdjust)
    ),
    'descent-override': toPercentage(
      Math.abs(metrics.descent / (metrics.unitsPerEm * sizeAdjust))
    ),
    'line-gap-override': toPercentage(
      metrics.lineGap / (metrics.unitsPerEm * sizeAdjust)
    ),
    ...properties,
  }
#

to come up with:

@font-face {
  font-family: "NunitoSans Override";
  src: local("BlinkMacSystemFont"), local("Segoe UI"), local("Helvetica Neue"), local("Arial"), local("Noto Sans");
  ascent-override: 101.1%;
  descent-override: 35.3%;
  line-gap-override: 0%;
}
lethal fiber
winged fiber
#

Do you preload / preconnect a 3rd party css-file?

  return [
    { rel: 'preconnect', href: 'https://rsms.me/inter/inter.css', as: 'style' },
    //Preload CSS to makes it nonblocking
    { rel: 'stylesheet', href: 'https://rsms.me/inter/inter.css' },

  ];
lethal fiber
#

preconnect is reserved for domains.

#

I think you don't need to preconnect, if you don't have another file that you need from that domain.

#

This demonstrates the behaviorial difference when you preconnect the domain first

winged fiber
#

Ah, I understand. How do you preload fonts in a good way?

I can see that the css-file is preloaded but the font-file is that is linked (I guess) is doing something after 800ms.

Is it better to host the font-file by your self and preload it directly?

lethal fiber
#

In my testing, preloading fonts aren't worth it.

#

Self-hosting is a good idea though.

#

I have a follow-up article going over fonts in the works. It's a complicated subject.

winged fiber
#

Ah, cool. Looking forward to it πŸ™‚

lethal fiber
#
  1. Use font-swap
  2. font metric override
  3. optimizing font sizes
  4. self-hosting fonts with cache control
exotic jackal
#

and then you can use a link with rel preload

{ rel: "preload", as: "font", href: "path/of/the/font", crossOrigin: "anonymous" }
#

I also recommend you to self host the font

#

modern browsers don't re-use the cached for a URL across sites anymore

winged fiber
#

aha

exotic jackal
#

so there's no real benefit of loading the font from a CDN

#

which means it's better to self-host them

#

and you can then preload them better

winged fiber
#

can I remove crossOrigin if I self host?

#

{ rel: "preload", as: "font", href: "path/of/the/font" }

exotic jackal
#

I think yes, but I just leave it there, I don't remember why

#

I copied that line from my own root loader

winged fiber
#

do you have the font in the public folder?

exotic jackal
#

I do yes

lethal fiber
#

My concern with preloading fonts is that it shuffles something else to the back of the line, causing some other metrics to increase.

exotic jackal
#

yeah preloading is cool but if you preload too much it will make everything slower again

winged fiber
#

is it a good idea to preload the font or should I just self host it?

exotic jackal
#

I recommend you to self-host and preload it

#

fonts are not found by the browser until it parses the CSS

#

so preloading them means when the user parses the CSS it should have already loaded them or at least started to load them

#

and fonts are large files sometimes

winged fiber
#

Cool, I tried to preload it now but I get this message in the console. Did I miss something?

{
      rel: 'preload',
      as: 'font',
      href: 'inter/Inter.var.woff2',
      crossOrigin: 'anonymous',
},
exotic jackal
#

thats because what was supposed to trigger the same request didn't do it immediately

#

it means the browser will try to request it again if needed later AFAIK, but if you put a cache-control header to the file it should be ok

#

also use /inter/Inter.var.woff2 not inter/Inter.var.woff2, otherwise if the user is on /something the browser may try to preload the font from /something/inter/Inter.var.woff2

winged fiber
#

ah, do I put the cache-control header on the link?

exotic jackal
#

the cache-control is on the response

#

you need to configure your server to add that to the response with the font

#

Remix defaults to configure all files in the public folder to be cached for 1 hour and files in public/build for 1 year

winged fiber
#

Ah, didn't know that. I guess that 1h is too short to make lighthouse happy
πŸ™‚

lethal fiber
#

There's a trick to it, a bit involved.

exotic jackal
#

you will have to customize it

#

so for your fonts it uses a larger cache

lethal fiber
#

Did you have an article on that already?

exotic jackal
#

good thing is that fonts don't change often so you can cache them for a year

#

even if they eventually change you can just use a different name

exotic jackal
#

in express you can do:

server.use("/fonts", express.static("public/fonts", { immutable: true, maxAge: "1y" }));
winged fiber
#

yeah, I use express. I will go for that approach. Thanks for the help!

rocky wraith
#

btw, since Remix 1.7.3 you can let Remix handle your fonts

lethal fiber
#

Ohh that'll make things much easier!

rocky wraith
#

And it's satisfying πŸ˜„

stuck warren
#

Oh man this made my site load a pinch quicker. Awesome. U 🫡 da best

lethal fiber
#

Glad to hear!