Bud compiling really slow

Hi there,

I have previously successfully setup a bud multi compiler for a separate app & editor bud config following this topic.

I havent’t touched this setup since, but I wanted to upgrade bud so I ran yarn run bud upgrade from my theme folder (I was on v6.5.3) and am now on v6.6.10.

Whenever I try to run yarn bud dev or yarn bud build, it takes almost 5 mins to compile!
Any idea what might be causing this slowness after upgrading?

This is my final config:

import path from 'path';
import glob from 'glob';

String.prototype.toKebabCase = function () {
	return this.match(
		/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g
	).join('-');
};

/**
 * Get list of entrypoints for blocks
 */
const blockFiles = {};

glob.sync('app/Blocks/**/*.php').map(block => {
	const name  = path.basename(block, '.php').toKebabCase().toLowerCase();
	const files = glob.sync(`resources/views/blocks/${name}/*.{js,css}`);

	if (files?.length > 0) {
		const filesResult = files.map(file => file.replace(/resources\/views\/blocks/g, '@blocks'));

		blockFiles[name] = filesResult;
	}
});

/**
 * Build configuration
 *
 * @see {@link https://bud.js.org/guides/configure}
 * @param {import('@roots/bud').Bud}
 */
export default async bud => {
	/**
	 * Server
	 */
	bud
		.watch([`resources/views/**/*`, `app/**/*`])
		.proxy(`https://example.test`)
		.serve(`http://0.0.0.0:3000`);

	/**
	 * Tailwind
	 */
	bud.tailwind.generateImports([`screens`]);

	/**
	 * Frontend css/js
	 *
	 * @param {bud} app
	 */
	await bud.make('app', async app =>
		app
			.setPath('@dist', 'public/app')
			.alias('@blocks', bud.path('@src/views/blocks'))
			.entry({
				app: ['@scripts/app', '@styles/app'],
				admin: ['@styles/admin'],
				login: ['@styles/login'],
				...blockFiles
			})
			.assets(['images'])
			.provide({
				jquery: ['jQuery', '$']
			})
			.setPublicPath('/app/themes/sage/public/app/')
	)

	/**
	 * Editor css/js
	 *
	 * @param {bud} editor
	 */
	await bud.make('editor', async editor =>
		editor
			.setPath('@dist', 'public/editor')
			.alias('@blocks', bud.path('@src/views/blocks'))
			.entry({
				editor: ['@scripts/editor', '@styles/editor']
			})
			.tap(async bud => (
				bud.postcss.setPlugin('postcss-editor-styles', [
					await bud.module.resolve('postcss-editor-styles'), {
						scopeTo: '.editor-styles-wrapper :not(.acf-block-fields *)',
						tagSuffix: ':not([class^="components-"]):not([class^="editor-"]):not([class^="block-"]):not([aria-owns]):not([class^="acf-"]):not([id^="acf-"])'
					}
				])
			))
			.setPublicPath('/app/themes/sage/public/editor/')
	)
}

Thanks!

Are you using Linux or Windows or Windows with WSL?

When you are using WSL or a VM, Container, are the source files on a different file system?

Nope, just running on a MacBook M1 on a ssd disk. Nothing has changed, it used to compile in seconds, now in minutes?

My software hasn’t changed since last time I run a bud build.
I’m meeting all the required software versions:

MacOs Monterey 12.6.2
Chip Apple M1 Max
Node lts/gallium (16.19.0)
NPM 8.19.3
Yarn 1.22.19

Running yarn bud doctor returns:

yarn run v1.22.19
$ /path/to/project/site/web/app/themes/sage/node_modules/.bin/bud doctor
βœ… bud.js generated configuration

βœ… webpack validated configuration

Registered configurations
- bud.config.mjs ./bud.config.mjs

✨  Done in 1.10s.

Running a yarn build outputs:

yarn run v1.22.19
$ bud clean && bud build
βœ” emptied /path/to/project/site/web/app/themes/sage/.budfiles

βœ” emptied /path/to/project/site/web/app/themes/sage/.budfiles

βœ” emptied /path/to/project/site/web/app/themes/sage/public/app

βœ” emptied /path/to/project/site/web/app/themes/sage/public/editor



β—‰  app ./public/app [551d295fc6e0ce7c6685]
β”‚
β”œβ”€ entrypoints
β”‚ β”œβ”€ app
β”‚ β”‚ β”œβ”€ js/runtime.951d06.js             1.05 kB
β”‚ β”‚ β”œβ”€ js/221.a5f092.js                 1.21 MB
β”‚ β”‚ β”œβ”€ css/app.09a2c8.css             124.78 kB
β”‚ β”‚ └─ js/app.3f980f.js                 8.55 kB
β”‚ β”œβ”€ admin
β”‚ β”‚ β”œβ”€ js/runtime.951d06.js             1.05 kB
β”‚ β”‚ └─ css/admin.d592a3.css            15.68 kB
β”‚ β”œβ”€ login
β”‚ β”‚ β”œβ”€ js/runtime.951d06.js             1.05 kB
β”‚ β”‚ └─ css/login.cd6a48.css             1.28 kB
β”‚ β”œβ”€ front-header
β”‚ β”‚ β”œβ”€ js/runtime.951d06.js             1.05 kB
β”‚ β”‚ └─ css/front-header.645f0c.css    623 bytes
β”‚ β”œβ”€ jobs-list
β”‚ β”‚ β”œβ”€ js/runtime.951d06.js             1.05 kB
β”‚ β”‚ └─ js/jobs-list.ed31af.js           1.12 kB
β”‚ └─ process-steps
β”‚   β”œβ”€ js/runtime.951d06.js             1.05 kB
β”‚   β”œβ”€ js/916.14e9d8.js                20.23 kB
β”‚   β”œβ”€ css/process-steps.ac9255.css   451 bytes
β”‚   └─ js/process-steps.1df900.js       2.49 kB
β”‚
β”œβ”€ assets
β”‚ β”œβ”€ images/tmnl_logo.805a34.svg                 23.3 kB
β”‚ β”œβ”€ images/tmnl_logo_white.940b78.svg           23.3 kB
β”‚ β”œβ”€ images/numbers/number-0-dark.21aa16.png     9.01 kB
β”‚ β”œβ”€ images/numbers/number-5-dark.db74d2.png      7.5 kB
β”‚ └─ images/numbers/number-6-dark.db14a7.png     7.44 kB
β”‚
β”‚ … 7 additional asset(s) not shown
β”‚
└─ compiled 82 modules in 194s 99ms


β—‰  editor ./public/editor [b6be7ef6c7a78fd91d61]
β”‚
β”œβ”€ entrypoints
β”‚ └─ editor
β”‚   β”œβ”€ js/runtime.ad7e3b.js      1.13 kB
β”‚   β”œβ”€ js/478.551fa8.js         280.2 kB
β”‚   β”œβ”€ css/editor.45e211.css   136.61 kB
β”‚   └─ js/editor.c1a213.js        1.4 kB
β”‚
β”‚
└─ compiled 18 modules in 189ms


✨  Done in 197.05s.

The compiling of the modules itself, seem to go pretty fast (99ms & 189ms), but the total time 197.05s is exceptionally high?

Even when I remove the ...blockFiles entries and the postcss-editor-styles parts, it still compiles in sometimes even 470.86s.

Also downgrading to versions 6.6.5 results in the same compiling time.

The fastest and most reliable way for finding out the cause (bottleneck) is profiling.

Example using the native node profiler and flamebearer for processing the profiling logs:

npm install -g flamebearer

# (in the sage theme folder)
node --prof ./node_modules/.bin/bud build
node --prof-process --preprocess -j isolate*.log | flamebearer

# open the HTML
chrome flamegraph.html

What stands out in the graph, especially when comparing the last known version that wasn’t slow with the one that after the update?

1 Like

Thanks @strarsis!
I uploaded a screenshot of the profile, but I am not sure what I’m looking at t.b.h. :slight_smile:

node_modules/postcss/lib/lazy-result.js seems to take up a big portion?

Interestingly, there is a similar issue in the build script of another library, also with underlying PostCSS:

What postcss dependency version is currently used in your project? Is it the most recent one? Can you update it (peer dependency) and see whether this fixes the issue?

What node version are you using? Most recent LTS? Using a more recent node version may also improve performance and can fix β€œstrange issues”.

With the latest bud version 6.6.10, the installed postcss version is 8.4.20 which is from a month ago.

I was using the latest lts/gallium but I just updated to the latest lts/* which is v18.13.0.
Unfortunately, this doesn’t have any effect on the building time…

Interestingly, I just tried to revert to my last working code base (with bud 6.5.3) and that now also results in building times of minutes instead of seconds?
:thinking:

It must be some change on my laptop since the last time I run a bud build on this project, but I don’t know what…

Then profiling is indeed the best approach here.

Can you further expand the large part in the flamebearer chart (node_modules/postcss/lib/lazy-result.js)? Does this lead to I/O?

Hmm, this time I’ve got a different result, and multiple isolate*.log files (biggest file was 100 Mb)

I uploaded my flamegraph.html file since I’ve got no clue where I should look in this profile :roll_eyes:

Pff I feel stupid…
:face_with_peeking_eye:
Turns out, I have an icons folder within my resources folder for generating an icon fonts with grunt-webfont, which installs it’s own node_modules.

While compiling my tailwind css, it also looks in this node_modules folders for tailwind classes…
When I exclude this folder in my tailwind.config.js:

module.exports = {
	content: [
		"./index.php",
		"./app/**/*.php",
		"./resources/**/*.{php,vue,js}",
		"./resources/!(icons)/**/*.{php,vue,js}",
		"./node_modules/tw-elements/dist/js/**/*.js"
	],
	...
};

Boom, compiling time is back to:
compiled 47 modules in 3s 806ms

Thanks for your time @strarsis, the profiler did point me in the right direction, since the css compiling took the longest.

1 Like