DEV Community

Cover image for How I reduced Tailwind CSS Home Page's HTML size by 28.5%, CSS by 23.7% and JS by 8.4%
Gleb Gorokhov
Gleb Gorokhov

Posted on

How I reduced Tailwind CSS Home Page's HTML size by 28.5%, CSS by 23.7% and JS by 8.4%

I really love Tailwind CSS! It's impressive to see how easily Tailwind has made it possible to integrate any project's design system into the code while optimizing the CSS simultaneously.

Tailwind's approach to styling has resulted in very small CSS files. However, as a consequence, the HTML and JS files have become larger.

Breezify is my attempt to address this issue.

How It Works

Breezify is a Node.js library that post-processes your CSS, HTML, and JS files in your build folder, updating them through AST (Abstract Syntax Tree) transformations in a few steps:

  1. It identifies class names in your CSS files and <style> tags in your HTML files.

  2. Breezify then generates a list of ultra-short class names, such as .a, .b, .ab, etc., and creates a mapping that links your existing class names to these new ones. Did you know that you only need 2 symbols to generate 3328 unique class names?

  3. Afterwards, it updates the class names found in your CSS, HTML, and JS files to these new ones.

Breezify offers a simple mode that replaces everything using regex, but its default mode employs AST transformations, which are smarter and offer more control over what gets updated and what doesn't.

So, in essence, Breezify converts this:

<div class="w-full max-w-content px-6 md:px-9 grid mx-auto z-[1] relative gap-x-6 md:gap-x-10 gap-y-6 md:gap-y-10 grid-cols-1 md:grid-cols-2 justify-items-start items-start">
  <a
    href="#"
    class="gap-2 items-center mb-10 transition-all text-theme-text-interactive dark:text-dark-text-interactive group-hover:text-theme-text-interactive-hover hover:text-theme-text-interactive-hover dark:hover:text-dark-text-interactive-hover dark:group-hover:text-dark-text-interactive-hover"
  >
    Carts
  </a>
</div>
Enter fullscreen mode Exit fullscreen mode

into this:

<div class="a b c d e f g h i j k l m n o p">
  <a href="#" class="q r s t u v y z A B">
    Carts
  </a>
</div>
Enter fullscreen mode Exit fullscreen mode

And this:

const mySpecialClass = "primary-color";
const decorated = "decorated";

const header = document.querySelector(
  `.header[role='decorated']:not(.decorated) .aside, ${decorated}, aside > .aside, ${mySpecialClass}`,
);
Enter fullscreen mode Exit fullscreen mode

into this:

const mySpecialClass = "a";
const decorated = "b";

const header = document.querySelector(
  `.c[role='decorated']:not(.b) .d, ${decorated}, aside > .d, ${mySpecialClass}`,
);
Enter fullscreen mode Exit fullscreen mode

Note how the word "decorated" is updated when it appears as a string, but remains unchanged when it is used as the name of a constant or as a value of the "role" attribute.

How to Use Breezify

  1. npm i breezify to install the module.
  2. breezify init to create a configuration file.
  3. npm run build (or your preferred build command) to build your project.
  4. breezify do to run Breezify.

For more information, visit the project's README.

Testing Breezify with the Tailwind CSS Homepage

The testing process is straightforward.

1. Clone Breezify

Clone the repository and install dependencies with pnpm install.

2. Add Files for Testing

Create a folder in breezify/tests/data/build-files for your build files and place your files there.

I will create a folder named tailwind-complete and save the Tailwind homepage by simply saving the page from the browser:

Tailwind CSS Homepage

To check how it looks after such a straightforward saving, I can serve this folder using npx serve tailwind-complete:

That's not bad

Some pictures are missing

Some pictures are missing.

As you can see, it works; however, some pictures are missing, but that's not an issue for testing purposes.

3. Run the Test

Then, I run pnpm test, which creates a copy of this folder in tests/data/output-files/%BUILD_FOLDER_NAME% and logs all the file size reductions in your terminal:

My terminal

Breezify reduced the size of HTML files by 28.55%, CSS files by 23.70%, and JS files by 8.44%. Not bad for already minified and obfuscated files, isn't it?

4. Preview the Results

Finally, we can preview the results by using npx serve tailwind-complete in the tests/data/output-files folder:

Preview Screenshot 1

Preview Screenshot 2

Interestingly, all images in the "breezified" version are functioning! Aside from the HTML, everything else appears the same:

New HTML

Conclusion

Breezify appears to be a valuable addition to the suite of post-processing libraries designed to minimize project file sizes as much as possible.

However, it does have a few drawbacks:

  1. It is written in JavaScript, meaning it may not be as fast as if it were developed in, for example, Rust.

  2. There is a risk of inadvertently replacing the wrong value, but this is preventable.

  3. There is a possibility of AST (Abstract Syntax Tree) parsing errors.

  4. Not all frameworks solely output CSS, JS, and HTML files. I am currently experiencing some difficulties making it work with Next.js, as it produces gzipped files that are challenging to process. However, I am confident this issue can be resolved. Feel free to contribute if you have a solution!

Thank you for reading! I can't wait to hear your thoughts on Breezify. Please feel free to share your experiences and results:

Top comments (0)