Skip to content

Build/Test Tools: Enable text compression in the local Docker environment - #12529

Closed
westonruter wants to merge 6 commits into
WordPress:trunkfrom
westonruter:add/local-env-text-compression
Closed

Build/Test Tools: Enable text compression in the local Docker environment#12529
westonruter wants to merge 6 commits into
WordPress:trunkfrom
westonruter:add/local-env-text-compression

Conversation

@westonruter

@westonruter westonruter commented Jul 15, 2026

Copy link
Copy Markdown
Member

Enables gzip compression in the nginx config template used by the local Docker environment, so that HTML, JavaScript, CSS, JSON, XML, and SVG responses are served compressed.

Without this, front-end performance analysis against the local environment is not representative of a real user's experience: on JavaScript-heavy screens like the Site Editor, several megabytes of uncompressed editor JavaScript are transferred on every load, and any performance improvement under test is drowned out by that transfer. Serving compressed responses matches the behavior of virtually all production WordPress hosts.

Compression is Accept-Encoding-gated, so any request that does not advertise gzip support (e.g. curl without --compressed) continues to receive uncompressed responses as before. gzip_vary on ensures caches key on the encoding, and the gzip_types list deliberately omits already-compressed assets (images, woff2 fonts) so nothing is wastefully re-compressed.

Configuration

Compression is enabled by default and controlled by a new LOCAL_NGINX_COMPRESSION option in .env (valid values on/off, defaulting to on). The value is substituted into the nginx template the same way as LOCAL_DIR. Setting it to off reproduces the previous uncompressed behavior, which is useful for measuring the uncompressed baseline when comparing performance:

LOCAL_NGINX_COMPRESSION=off

Notes

  • nginx:alpine (the image used by the local environment) ships the gzip module but not brotli, so this uses gzip.
  • Because this changes docker-compose.yml (the web server's environment and command) in addition to the nginx template, existing checkouts need to recreate the web server container to pick up the change, e.g. docker compose up -d wordpress-develop or npm run env:start.

Verification

Verified locally under Fast 4G throttling: the Site Editor's major bundles compress to roughly 30% of their transfer size (e.g. editor.min.js 1.55 MB → 498 KB), which brought this screen's LCP down from ~25.4 s to ~15.4 s and made data-loading differences measurable rather than being swamped by asset transfer. Toggling LOCAL_NGINX_COMPRESSION between on and off was confirmed to add/remove the Content-Encoding: gzip response header as expected.

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

Use of AI Tools

AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 4.8
Used for: Authoring the nginx gzip configuration and the LOCAL_NGINX_COMPRESSION toggle, drafting this PR description, and running the performance measurements that motivated the change. All changes were directed, reviewed, and verified by me.

…ment.

Add gzip directives to the nginx config template used by the local Docker
environment so that HTML, JavaScript, CSS, JSON, XML, and SVG responses are
served compressed. This matches the behavior of virtually all production
WordPress hosts and makes front-end performance analysis against the local
environment representative: without it, the site editor's ~8 MB of editor
JavaScript is served uncompressed, so page-load metrics like LCP are dominated
by transfer of dev assets that would be compressed in production.

Compression only applies when the client sends `Accept-Encoding: gzip`, so
existing uncompressed workflows are unaffected. `gzip_vary on` ensures caches
key on the encoding.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 15, 2026

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props westonruter, jblz.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

westonruter and others added 2 commits July 14, 2026 18:52
Add a `LOCAL_NGINX_COMPRESSION` option (valid values `on`/`off`, defaulting to
`on`) that controls whether the web server serves compressed responses. The
value is substituted into the nginx template the same way as `LOCAL_DIR`, so it
can be set to `off` to reproduce uncompressed behavior for comparison.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enables gzip text compression in the local Docker nginx configuration so the local environment better reflects typical production hosting behavior and yields more representative front-end performance measurements.

Changes:

  • Adds gzip configuration (vary/proxied/level/min length + content types) to the nginx config template used by the local environment.
  • Introduces LOCAL_NGINX_COMPRESSION (default on) as a .env/Compose-controlled toggle for enabling/disabling compression.
  • Updates the container startup command to substitute the new variable into the nginx config via envsubst.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
tools/local-env/default.template Enables gzip compression in the nginx server config template with a variable-driven on/off toggle.
docker-compose.yml Adds LOCAL_NGINX_COMPRESSION to the web container environment and includes it in envsubst substitution.
.env.example Documents the new LOCAL_NGINX_COMPRESSION option and its valid values.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@jblz jblz left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should consider having LOCAL_NGINX_COMPRESSION default to off.

While negligible, compression and decompression in a local env will add overhead that is likely only useful when developing features that depend on that behavior.

Comment thread docker-compose.yml Outdated
Co-authored-by: Jeff Bowen <jblz@users.noreply.github.com>
Comment thread .env.example Outdated
Comment thread docker-compose.yml Outdated
westonruter and others added 2 commits August 16, 2026 11:33
Co-authored-by: Jeff Bowen <jblz@users.noreply.github.com>
Switch `LOCAL_NGINX_COMPRESSION` to the `:-` form of parameter expansion, so
the default applies when the variable is set but empty as well as when it is
unset entirely.

The value is substituted straight into the nginx template as
`gzip ${LOCAL_NGINX_COMPRESSION};`, so an empty value rendered `gzip ;` and
nginx refused to start with "invalid number of arguments in gzip directive".
Clearing the value in `.env` is an intuitive way to turn compression off, and
it now yields `off` rather than a crash-looping web container.

Co-authored-by: Jeff Bowen <jblz@users.noreply.github.com>
pento pushed a commit that referenced this pull request Aug 16, 2026
Add gzip directives to the nginx config template used by the local Docker environment so that HTML, JavaScript, CSS, JSON, XML, and SVG responses can be served compressed, matching normal production behavior. Without compression, frontend performance analysis against the local environment is not representative of a real user's experience.

Compression is controlled by a new `LOCAL_NGINX_COMPRESSION` option, and it defaults to `off` so that it is opt-in.

Since this changes `docker-compose.yml` in addition to the nginx template, existing checkouts need to recreate the web server container to pick up the change.

Developed in #12529.
Follow-up to r45745, r45783.

Props westonruter, jblz.
Fixes #65634.


git-svn-id: https://develop.svn.wordpress.org/trunk@63308 602fd350-edb4-49c9-b593-d223f7449a82
@github-actions

Copy link
Copy Markdown

A commit was made that fixes the Trac ticket referenced in the description of this pull request.

SVN changeset: 63308
GitHub commit: 1fcc5c0

This PR will be closed, but please confirm the accuracy of this and reopen if there is more work to be done.

@github-actions github-actions Bot closed this Aug 16, 2026
@jblz

jblz commented Aug 16, 2026

Copy link
Copy Markdown

This is testing well :)

$ curl -sI -H 'Accept-Encoding: gzip' http://localhost:8889/wp-includes/css/dashicons.css | grep -iE 'content-type|content-encoding|vary'
  Content-Type: text/css
  Vary: Accept-Encoding
  Content-Encoding: gzip


$ curl -sI -H 'Accept-Encoding: gzip' http://localhost:8889/wp-includes/images/w-logo-blue.png | grep -iE 'content-type|content-encoding'
  Content-Type: image/png

$ curl -sI -H 'Accept-Encoding: gzip' 'http://localhost:8889/?feed=rss2'
  | grep -iE 'content-type|content-encoding'
  Content-Type: application/rss+xml; charset=UTF-8
  Content-Encoding: gzip

Not a blocker, but noting that specifying a value other than on or off for LOCAL_NGINX_COMPRESSION "silently" breaks nginx in the container. Logs say something like:

wordpress-develop-1 | nginx: [emerg] invalid value "o" in "gzip" directive, it must be "on" or "off" in /etc/nginx/conf.d/default.conf:18

markjaquith pushed a commit to markjaquith/WordPress that referenced this pull request Aug 16, 2026
Add gzip directives to the nginx config template used by the local Docker environment so that HTML, JavaScript, CSS, JSON, XML, and SVG responses can be served compressed, matching normal production behavior. Without compression, frontend performance analysis against the local environment is not representative of a real user's experience.

Compression is controlled by a new `LOCAL_NGINX_COMPRESSION` option, and it defaults to `off` so that it is opt-in.

Since this changes `docker-compose.yml` in addition to the nginx template, existing checkouts need to recreate the web server container to pick up the change.

Developed in WordPress/wordpress-develop#12529.
Follow-up to r45745, r45783.

Props westonruter, jblz.
Fixes #65634.

Built from https://develop.svn.wordpress.org/trunk@63308


git-svn-id: http://core.svn.wordpress.org/trunk@62501 1a063a9b-81f0-0310-95a4-ce76da25c4cd
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

Successfully merging this pull request may close these issues.

3 participants