Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce 1.0.0 size (Remove, reduce CSS variables option) #3761

Open
kasperkamperman opened this issue Mar 30, 2024 · 18 comments
Open

Reduce 1.0.0 size (Remove, reduce CSS variables option) #3761

kasperkamperman opened this issue Mar 30, 2024 · 18 comments

Comments

@kasperkamperman
Copy link

This is a question.

Overview of the problem

This is about the Bulma CSS framework
I'm using Bulma version [1.0.0]
I am sure this issue is not a duplicate

Description

I love the new Bulma and the accessible color styles. What I love less is the new file size.
The default minified went from 207kb to 554kb.

This is mainly do addition from the css variables. This is nice of for color switching, but I feel it's not worth the trade-off for my current sites.

Is there away to compile without variables in Sass. I tried postprocessing with postcss, but that plugin hangs on the Bulma script.
I posted an issue on that here: MadLittleMods/postcss-css-variables#139

I'm curious to know if there are other ways.

I use other postcss plugins to prune unused variables and compress variables names (not nice for readibility, but regular site-users won't care. I also changed the prefix to one character (instead of bulma- in front of each variable).

Any suggestions or ideas are welcome.

@jgthms
Copy link
Owner

jgthms commented Mar 30, 2024

It's probably doable by not including any of the themes and creating your own.

It's a bit tricky because you'd need to know which CSS variables to include yourself.

Now that I think about it, creating a "lite" theme could be something of a solution.

@kasperkamperman
Copy link
Author

That would be interesting. I feel there is too much overhead. I would only like to have css variables for the parts that actually are variable and change (I assume mostly color).

For example the new "gradient" colorpalettes take a lot of variable space (I commented out the digits in the sass file to exclude them), maybe they could be in a separate sass file, which can be excluded.

Anyway, super nice job.

@kasperkamperman
Copy link
Author

I'm still figuring out how to remove css variables. I found a package to convert them to sass-variables (and then remove them).

However the order of variables gives a issue. For css you can refer to a variable that is declared later, but for sass not.

There are several cases where reference is made to "not declared" variables.

I don't know if that needs to be fixed (and it might be really difficult), just figuring out a way to make some major savings in file size.

@kasperkamperman kasperkamperman changed the title Remove CSS variables example Reduce 1.0.0 size (Remove, reduce CSS variables option) Apr 5, 2024
@kasperkamperman
Copy link
Author

Changed the title to better explain the context of my question.

@E021ntox
Copy link

E021ntox commented Apr 6, 2024

Yes, 1.0 is terrible, I have rolled back to 0.9.4.

@kasperkamperman
Copy link
Author

@E021ntox Well I could make major savings with postcss.

My postcss.config.js:

const purgecss = require('@fullhuman/postcss-purgecss')
const cssnano = require('cssnano')
const pruneVar = require('postcss-prune-var')
const varCompress = require('postcss-variable-compress')

module.exports = {
    plugins: [
        purgecss({
            // file paths to your contents to remove unused styles. 
            // content: ['js/my.js','*.php'],
            // other wise our aria-selected is removed (like with purgecss online)
            dynamicAttributes: ["aria-selected"]
        }),
        pruneVar(), // remove unused css variables
        varCompress(), // compress css variables
        cssnano({
            preset: 'default',
        }),
    ],
};

My final Bulma 1.0.0 CSS was 52kb, the 0.9.4 version was 46kb.
Good compressed CSS variables might be even more efficient size wise.

I think color contrast is a major improvement in 1.0.0, I don't know if the theme is backwards compatible.

@max-arnold
Copy link

@kasperkamperman Could you please elaborate a bit on what is needed to make a custom Bulma build with your config? So far I've followed these steps and got the basic my-bulma-project.css build. What I need to add to the package.json to reproduce your setup?

Unfortunately I'm not familiar with the Node.js tooling ecosystem

@kasperkamperman
Copy link
Author

kasperkamperman commented Apr 14, 2024

Yes. I'm also not super familiar either, but I could make it happen.

You have to install more package install --save-dev (although I think the --save-dev doesn't really matter (I'm not really into npm).

My package.json looks like this:

{
  "devDependencies": {
    "@fullhuman/postcss-purgecss": "^6.0.0",
    "cssnano": "^6.1.2",
    "dependencies": "^0.0.1",
    "postcss-cli": "^11.0.0",
    "postcss-prune-var": "^1.1.2",
    "postcss-variable-compress": "^3.0.0",
  },
  "dependencies": {
    "sass": "^1.72.0"
  },
  "scripts": {
     "build-my-bulma": "sass --style=expanded --source-map my-bulma.scss css/bulma.css",
    "build-bulma": "sass --style=expanded --source-map bulma/bulma.scss css/bulma.css",
    "purge-bulma": "postcss css/bulma.css --no-map --output css/bulma.min.css",
  }
}

You see I add purge-bulma, to run the postcss part. Although you could run it from the command-line to I think with the postcss cli. For example I now use cat css/bulma.css css/page.css | npx postcss > css/style.css to first merge bulma with some other css file with my modifications, this is piped | into postcss. NPX is npm but then without installing (so I think I could use the command npm too.

Everytime you run postcss it runs what's in the postcss.config.js (which I shared above). You can comment out parts you don't use.

I use below too customize bulma (no dark-mode, custom colors). I removed the bulma-- prefix from the css variables, although if you use postcss-variables-compress that is not needed (since they get compressed names anyway).

For completeness below, my custom version to build bulma (my-bulma.scss). I removed dark-mode and new things as grid/skeleton. However if you use purge-css and you don't use it, all those classes will be removed anyway.

@charset "utf-8";

$cyan: hsl(198, 100%, 70%);
$blue: hsl(229, 86%, 36%);
$red: hsl(348, 86%, 49%); // used for danger

/* no dark mode, only light-theme for now */
@use "bulma/sass" with (
  $cssvars-prefix: "",
  $primary: $cyan,
  $link: $blue,
  $danger: $red
);

@forward "bulma/sass/utilities";
//@forward "themes";
@forward "bulma/sass/base";
@forward "bulma/sass/elements";
@forward "bulma/sass/form";
@forward "bulma/sass/components";
//@forward "bulma/sass/grid";
@forward "bulma/sass/layout";
//@forward "bulma/sass/base/skeleton";
@forward "bulma/sass/helpers";

@use "bulma/sass/themes/light";
@use "bulma/sass/themes/setup";

:root {
  @include light.light-theme;
  //@include setup.setup-theme;
}

Hope this helps.

@nioc
Copy link

nioc commented May 7, 2024

Thanks @kasperkamperman.
As I don't master the subtleties of SCSS, I have 2 questions about your example:

  1. I was wondering why you import the bulma/sass file when you're also importing the bulma/sass/utilities and bulma/sass/base files?
  2. Why @use some files and @forward others? Is there a difference in your use?

@kasperkamperman
Copy link
Author

@nioc To be honest, I just worked from the Bulma examples and tried to make it work. I hardly get SCSS either (and I'm too "lazy" to dive into it) :-)

@nioc
Copy link

nioc commented May 8, 2024

My understanding is:

  • @use load the content,
  • @forward make it available for other rules in file.

As you @use "bulma/sass"(all lib), you should remove following @forward statements.

In bulma docs, it is said that we can load all lib (bulma/sass) or load only what we need.

But it does not matter, as you purge css 😄

@nioc
Copy link

nioc commented May 10, 2024

Thanks for your help again @kasperkamperman and obviously @jgthms for this incredible work.
In case anyone needs to reduce CSS in a Svelte app (Vite not Sveltekit), here is my postcss.config.cjs (just it and npm i -D @fullhuman/postcss-purgecss, no need for anything else, Vite does the magic):

/* eslint-disable @typescript-eslint/no-var-requires */
const purgecss = require('@fullhuman/postcss-purgecss')

module.exports = {
  plugins: [
    purgecss({
      content: [
        './index.html',
        './src/**/*.{svelte,js,ts}',
      ], // declaring source files
      safelist: {
        standard: [/$svelte-/], // required for inline component styles
      },
      variables: true, // remove unused CSS variables
    }),
  ],
}

I do not use postcss-prune-var because purgecss has an option that gives better results in my case:

Bulma version Bulma Themes Post CSS CSS assets size CSS variables count
0.9.4 No Nothing 214.41 kB
1.0.0 Dark & light 565.77 kB 987
1.0.0 Dark & light PurgeCSS + PruneVar 139.64 kB 561
1.0.0 Dark & light PurgeCSS with variables: true 107.30 kB 220

So 107 kB (60 kB gzipped), for such a rich CSS with 2 themes, that's impressive 🦸🏻

@jgthms
Copy link
Owner

jgthms commented May 20, 2024

Great find. Thanks @nioc. I'll see if I can include purgecss in the build process, without it impacting the final result and the customization options.

@rednaks
Copy link

rednaks commented May 24, 2024

Yes, 1.0 is terrible, I have rolled back to 0.9.4.

same, rolledback to 0.9.4 due to bundle size ...

@muellerj
Copy link

@nioc: How did you instruct purgecss to leave the themes alive? I have not managed to configure it in such a way, the theme-dark selectors seem to get purged regardless.

  system "purgecss",
    "--css", "_build/css/base.css",
    "--content", "_tmp/compiled.html.erb",
    "--safelist", "theme-dark",
    "--safelist", "fa-*",
    "--output", "_build/css"

@nioc
Copy link

nioc commented Jun 23, 2024

Hello @muellerj I'm not behind my pc but I think themes are also purged, but it's what I wanted (keep only used variables and classes, and in my case I use both light and dark in a svelte app).

@muellerj
Copy link

Understood - thanks. If I find a configuration that keeps the themes, I'll post it here. My feeling is that the CLI interface for purgecss doesn't off the full power of the patterns (https://purgecss.com/safelisting.html) as the Javascript API.

@muellerj
Copy link

If anyone stumbles across this - I ended up using the inline CSS comments to guard the themes from being purged. In ruby, it looks something like this:

def add_purgecss_protection(file)
  return if has_purgecss_protection?(file)

  puts "Adding protection to #{file}"
  File.write(file, [
    "/*! purgecss start ignore */",
    *File.readlines(file).map(&:chomp),
    "/*! purgecss end ignore */",
  ].join("\n"))
end

def has_purgecss_protection?(file)
  lines = File.readlines(file)
  return false unless lines.first.chomp == "/*! purgecss start ignore */"
  return false unless lines.last.chomp  == "/*! purgecss end ignore */"

  true
end

# ...

  add_purgecss_protection("_src/bulma/sass/themes/_index.scss")  # <= This guards themes/_index.scss from being purged
  system "sass", "sass/base.scss", "_build/css/base.css"
  system "purgecss",
    "--css", "_build/css/tc-base.css",
    "--content", "_tmp/compiled.html.erb",
    "--output", "_build/css"
  system "csso", "_build/css/base.css",
    "--output", "_build/css/base.css"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants