Make WordPress Core

Opened 7 months ago

Closed 7 months ago

Last modified 7 months ago

#64563 closed defect (bug) (fixed)

Grunt uglify:core and copy:files tasks hang when wp-content has many files

Reported by: westonruter Owned by: westonruter
Priority: normal Milestone: 7.0
Component: Build/Test Tools Version:
Severity: normal Keywords: has-patch
Cc: Focuses: javascript

Description

For a long time, I've struggled with npm run build:dev (see Slack thread). When I run the command, it would always seem to hang at:

Running "uglify:core" (uglify) task

I got so fed up with having to wait so long at that task, that I started resorting to using symlinks to avoid having to do a build altogether.

A note on my development environment setup: I clone the repos for the plugins and themes I work on into the wp-content of my wordpress-develop clone which I use for core development.

I got fed up and decided to put Gemini CLI on the problem and it came up with this fix:

  • Gruntfile.js

    a b module.exports = function(grunt) {  
    926926                                        'wp-includes/js/tinymce/plugins/wp*/plugin.js',
    927927
    928928                                        // Exceptions.
    929                                         '!**/*.min.js',
     929                                        '!{wp-admin,wp-includes}/**/*.min.js',
    930930                                        '!wp-admin/js/custom-header.js', // Why? We should minify this.
    931931                                        '!wp-admin/js/farbtastic.js',
    932932                                        '!wp-includes/js/wp-emoji-loader.js', // This is a module. See the emoji-loader task below.

The hang was caused by a broad exclusion pattern in the uglify:core task within Gruntfile.js. Its explanation makes perfect sense:

When you run npm run build:dev, the cwd (current working directory) for the build tasks is set to src/.

The original pattern !**/*.min.js told Grunt to exclude any minified files found anywhere inside the src/ directory. To fulfill this request, the globbing engine had to scan every single folder and file within src/ to see if they matched.

Because your src/wp-content/ directory contains several plugins (like the jetpack-monorepo) with massive node_modules folders containing hundreds of thousands of files, Grunt would hang for a long time just trying to find all those files to ensure they were excluded.

By changing the pattern to !{wp-admin,wp-includes}/**/*.min.js, I restricted that exclusion search to only the core wp-admin and wp-includes directories. This allows Grunt to completely skip scanning the wp-content directory, which resolves the hang.

Impact

When running npm run build:dev:

Before: 43.032s
After: 9.393s

This is now >4.5 times faster, a >78% reduction in execution time!

Change History (8)

This ticket was mentioned in PR #10809 on WordPress/wordpress-develop by @westonruter.


7 months ago
#1

  • Keywords has-patch added

The uglify:core task utilizes a negative glob pattern !**/*.min.js to prevent re-minifying already minified files. In development builds (npm run build:dev), this pattern operates relative to the src/ directory. Consequently, the glob expansion scans the entire src/ directory tree, including wp-content.

For environments where wp-content contains deep directory structures—such as plugins with node_modules dependencies—this traversal becomes prohibitively slow, causing the build process to hang.

This change scopes the exclusion pattern to !{wp-admin,wp-includes}/**/*.min.js, limiting the file scan to the relevant core directories and preventing unnecessary recursion into wp-content.

Trac ticket: https://core.trac.wordpress.org/ticket/64563

#2 @westonruter
7 months ago

  • Owner set to westonruter
  • Status newaccepted

This ticket was mentioned in Slack in #core by westonruter. View the logs.


7 months ago

#4 in reply to: ↑ description @mukesh27
7 months ago

Replying to westonruter:

Impact

When running npm run build:dev:

Before: 43.032s
After: 9.393s

This is now >4.5 times faster, a >78% reduction in execution time!

Go for it 🚀

@westonruter commented on PR #10809:


7 months ago
#5

I asked Gemini if there were any other opportunities to improve performance similarly in Gruntfile.js, and it identified another glob pattern in copy:files. Indeed, when I run npm run build I find it hangs for a long time at:

Running "copy:files" (copy) task

However, with c413206 the time to build is dramatically improved:

Before: 51.102s
After: 13.805s

This ticket was mentioned in Slack in #core by sirlouen. View the logs.


7 months ago

#7 @westonruter
7 months ago

  • Resolutionfixed
  • Status acceptedclosed

In 61545:

Build/Test Tools: Optimize uglify:core and copy:files glob patterns in Grunt tasks.

The uglify:core and copy:files tasks utilized broad negative glob patterns (!**/*.min.js and !**/*.map) to exclude files from processing. The glob expansion scans the entire src/ directory tree, including wp-content. For environments where wp-content contains deep directory structures (such as plugins with node_modules dependencies) this traversal becomes prohibitively slow, causing the build process to hang.

This change scopes the exclusion patterns to specific directories (e.g. wp-admin, wp-includes, default themes, and Akismet), limiting the file scan to relevant core paths and preventing unnecessary recursion into wp-content.

In one dev environment, this reduces npm run build:dev from 43s to 9s, and npm run build from 51s to 13s.

Developed in https://github.com/WordPress/wordpress-develop/pull/10809

Follow up to [61475].

Props westonruter, jonsurrell.
See #63606.
Fixes #64563.

#8 @westonruter
7 months ago

  • Summary Grunt uglify:core task hangs when wp-content has many filesGrunt uglify:core and copy:files tasks hang when wp-content has many files
Note: See TracTickets for help on using tickets.