#Does non-static output ship full CSS bundle?

39 messages · Page 1 of 1 (latest)

dim isle
#

I've been trying to figure out why my app ships 130kb of css while a new App with almost the same tailwind plugins ship like 3 or 5kbs, and I think that when I switch to output: 'hybrid' // or server , Astro ships all bundled css, going from 3-5 to 20kb all at once. Is it expected behaviour? It is extremely apparent when using tailwind and blocks page load

ruby sorrel
#

I’m very interested in this topic, and so far, I’ve noticed the following, although I don’t fully understand how Astro, Tailwind, or CSS handle this in detail. My CSS file includes only the relevant Tailwind CSS and is around 5.1 KB for each page of the website (using SSR in server mode). It seems that Tailwind successfully purged unnecessary CSS. Additionally, the CSS is minified after the build process. It appears that the CSS is bundled once for the entire website, shipped only once, and then cached. A file size of 130 KB sounds excessive to me, especially considering that websites like Netflix’s Top 10, which also use Tailwind, have CSS sizes of around 8 KB.

dim isle
#

Maybe hybrid output can't figure out how to treeshake tailwind

#

So, static output:

#

Server:

#

Hybrid(same):

#

@ruby sorrel take a look please 🙂

ruby sorrel
#

I am not a member of the Astro team and do not wish to present myself as such—I'm simply interested in the topic.

Here’s what I observed:

Initially, the CSS file in server/hybrid is about 27.4kb.

  1. Removing the Tailwind plugin DaisyUI reduces the file size to ~17.4kb (a reduction of ~10kb).
  2. Removing the Tailwind class prose further reduces the CSS to ~5kb (a reduction of ~12.4kb).

This is really strange because I also use prose with the server configuration, and my total CSS across the entire site is only about 5kb.

However, when I check the CSS file in the dist directory after the build, it’s almost 29kb. Yet, on the client side, only 5kb actually get delivered (I'm using Vercel).

Are your data coming from the preview or the deployed site @dim isle ?

#

Tomorrow, I’ll also be deploying my site via Node.js (I need this for a thesis I’m working on about Astro). Maybe I’ll have more information then. In the meantime, I’ll tag the right support—they probably know more about this. <@&1129102257422610512>

I also worry I may have given the wrong impression, making it seem like you're already receiving professional help through this conversation that took place in the ticket.

#

I can imagine that with static rendering, the CSS is more thoroughly optimized since it won’t change anymore. However, with SSR rendering through server or hybrid modes, this optimization might not happen because, for example, components with lazy loading only receive their CSS later when needed? Could it be that the optimization is happening on the server side in this case?

dim isle
#

I would actually prefer optimisations being made always, I think that's the right thing, because otherwise its pretty stupid to have such a huge css bundle anywhere. What's the point of Astro then if there's more css than js

ruby sorrel
#

Did you deploy the site with Node.js, or are you taking the numbers/screenshots from npm run preview?

#

Alright, I just started your project locally on my machine with Node.js after the build, and I'm also getting the same 27kb of CSS. That's really strange. I'm curious to see what results you'll get with Vercel, and tomorrow I'll try deploying my Vercel instance on Node.js as well. Let's see what comes out of it.

foggy flower
#

Do either of you use the “universal defaults” setting in your tailwind config?

It removes a bunch of bloat

ruby sorrel
# foggy flower Do either of you use the “universal defaults” setting in your tailwind config? ...

Could you explain what you mean by "universal defaults"? I'm not entirely sure. From the repo we discussed, the Tailwind config looks like this:

import typography from "@tailwindcss/typography";
import daisyui from "daisyui";

/** @type {import('tailwindcss').Config} */
export default {
  content: ["./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}"],
  theme: {
    extend: {},
  },
  plugins: [
    require('@tailwindcss/typography'),
    require('daisyui'),
  ],
};
foggy flower
#

optimizeUniversalDefaults: true I think is what it’s called

Not at my desk ATM

#

Try adding this


experimental: {
    optimizeUniversalDefaults: true,
  },
ruby sorrel
#

This reduces the file size to 25.2 kB.

foggy flower
#

What was it before? Sorry haven’t fully read up

ruby sorrel
#

27.4kB

foggy flower
#

Nice, a crisp 2.2 kB saved 😅

ruby sorrel
#

Is there a reason why static only produces 5kb, while hybrid/server produces around 27kb?

foggy flower
#

I don’t know but your guess does seem reasonable

There may be less optimization if css is transformed during a build vs on request

dim isle
sturdy glacier
#

Your CSS has the same exact content in both bundles (case in point, it has the same hash), your static output preview is gzipped, your hybrid one isn't

#

if you put the 27kb CSS inside a gzip compressor, the output gets to what you'd expect (exact value depending on how much gzip effort you put, here it's low)

dim isle
#

So, how should I mitigate this? Use nginx or something for proxying?

#

I will try to deploy to vercel in few mins, it uses brotli, wanna try that

sturdy glacier
#

Yeah, your reverse proxy or hosting platform will typically be the one doing the compression

#

But typically yeah, the reverse proxy / cdn / host etc does it and doing it at the framework level ends up being wasted effort

dim isle
#

Okay thank you for pointing that out!!

#

@sturdy glacier Yeah, you were right! I wonder how I even came to the point of fooling myself here 🤓 Thank you!

foggy flower
#

Awesome! Thanks Erika! ❤️