[wp-trac] [WordPress Trac] #64906: Media: Remove client-side media processing from 7.0
WordPress Trac
noreply at wordpress.org
Thu Mar 19 17:48:52 UTC 2026
#64906: Media: Remove client-side media processing from 7.0
-----------------------------+---------------------
Reporter: adamsilverstein | Owner: (none)
Type: defect (bug) | Status: new
Priority: normal | Milestone: 7.0
Component: Media | Version: trunk
Severity: normal | Resolution:
Keywords: has-patch | Focuses:
-----------------------------+---------------------
Description changed by adamsilverstein:
Old description:
> == Description
>
> The client-side media processing feature (wasm-vips) should be removed
> from WordPress 7.0 and punted to 7.1. The feature adds approximately 16MB
> of inlined WASM to the build output (the `vips/worker.min.js` file alone
> accounts for ~36% of the `script-modules/` directory), which is too much
> build size overhead relative to the value the feature currently provides.
>
> This ticket tracks the complete removal of all backported client-side
> media processing code from core.
>
> === Background
>
> Client-side media processing was backported from Gutenberg to allow
> browsers to handle image resizing, format conversion, and thumbnail
> generation using a WebAssembly build of the libvips image processing
> library. The feature requires cross-origin isolation (via Document-
> Isolation-Policy on Chromium 137+) and SharedArrayBuffer, limiting it to
> secure contexts on modern Chromium browsers.
>
> While the feature shows promise, the build size cost is significant and
> the browser support is limited. The decision is to remove it from 7.0 and
> revisit for 7.1 once the build size and browser compatibility concerns
> are addressed.
>
> == What Is Being Removed
>
> === PHP functions (`wp-includes/media.php`)
> - `wp_is_client_side_media_processing_enabled()` — feature gate
> - `wp_set_client_side_media_processing_flag()` — sets JS flags and VIPS
> module dependency
> - `wp_get_chromium_major_version()` — browser detection for DIP support
> - `wp_set_up_cross_origin_isolation()` — enables isolation in block
> editor
> - `wp_start_cross_origin_isolation_output_buffer()` — sends DIP header
> - `wp_add_crossorigin_attributes()` — adds `crossorigin="anonymous"` to
> HTML tags
>
> === Hook registrations (`wp-includes/default-filters.php`)
> - `admin_init` → `wp_set_client_side_media_processing_flag`
> - `load-post.php` / `load-post-new.php` / `load-site-editor.php` / `load-
> widgets.php` → `wp_set_up_cross_origin_isolation`
>
> === REST API (`wp-includes/rest-api/`)
> - `POST /wp/v2/media/{id}/sideload` endpoint — uploads client-processed
> image sub-sizes
> - `POST /wp/v2/media/{id}/finalize` endpoint — triggers
> `wp_generate_attachment_metadata` filter after client processing
> - `generate_sub_sizes` and `convert_format` request parameters on `POST
> /wp/v2/media`
> - `get_endpoint_args_for_item_schema()` override in attachments
> controller
> - `remove_client_side_media_processing_filters()`, `sideload_item()`,
> `filter_wp_unique_filename()`, `finalize_item()`,
> `sideload_item_permissions_check()` methods
> - REST index additions: `image_sizes`, `image_size_threshold`,
> `image_output_formats`, `jpeg_interlaced`, `png_interlaced`,
> `gif_interlaced`
>
> === Media templates (`wp-includes/media-template.php`)
> - Cross-origin isolation output buffer in `wp_print_media_templates()`
> - `crossorigin="anonymous"` attribute injection for media template tags
>
> === Script modules (`wp-includes/script-modules.php`)
> - VIPS minified filename forcing logic
>
> === Build assets
> - VIPS module entries in `script-modules-packages.min.php`
> - `@wordpress/vips/worker` dependency in `script-loader-packages.min.php`
> - VIPS exclusion rules in `Gruntfile.js` and `tools/gutenberg/copy.js`
>
> === Test files
> - `tests/phpunit/tests/media/wpCrossOriginIsolation.php` (deleted)
> - Sideload/finalize/generate_sub_sizes tests in `rest-attachments-
> controller.php`
> - Client-side media processing setup in `rest-schema-setup.php`
> - Sideload/finalize route fixtures in `wp-api-generated.js`
>
> == What Is Preserved
>
> The following independent features are **not** removed:
>
> - `wp_prevent_unsupported_mime_type_uploads` filter (Trac ticket 64836,
> added in 6.8.0)
> - `X-WP-Upload-Attachment-ID` response header (useful for error recovery)
> - Pre-existing `post-process` endpoint (since 5.3.0) and `edit` endpoint
> (since 5.5.0)
> - `exif_orientation`, `filename`, `filesize`, `missing_image_sizes`
> schema properties
> - The `client-side-media-experiments/` plugin directory (not part of
> core)
>
> == Proposed Fix
>
> PR: https://github.com/WordPress/wordpress-develop/pull/11309
>
> 12 files changed, 1,507 lines deleted. All changes are deletions with no
> new code added.
>
> == Testing
>
> 1. Run `phpunit tests/phpunit/tests/media/` — no failures.
> 2. Run `phpunit tests/phpunit/tests/rest-api/rest-attachments-
> controller.php` — no failures.
> 3. Run `phpunit tests/phpunit/tests/rest-api/rest-schema-setup.php` —
> route list correct.
> 4. Upload images via the block editor and media library — standard
> server-side sub-size generation works.
> 5. Run `npx grunt build --dev` — build succeeds without VIPS.
> 6. Confirm `build/wp-includes/js/dist/script-modules/vips/` no longer
> exists.
New description:
== Description
The client-side media processing feature is removed for 7.0, reducing
build size overhead relative to the value the feature currently provides.
This ticket tracks the complete removal of all backported client-side
media processing code from core.
=== Background
Client-side media processing was backported from Gutenberg to allow
browsers to handle image resizing, format conversion, and thumbnail
generation using a WebAssembly build of the libvips image processing
library. The feature requires cross-origin isolation (via Document-
Isolation-Policy on Chromium 137+) and SharedArrayBuffer, limiting it to
secure contexts on modern Chromium browsers.
While the feature shows promise, the build size cost is significant and
the browser support is limited. The decision is to remove it from 7.0 and
revisit for 7.1 once the build size and browser compatibility concerns are
addressed.
== What Is Being Removed
=== PHP functions (`wp-includes/media.php`)
- `wp_is_client_side_media_processing_enabled()` — feature gate
- `wp_set_client_side_media_processing_flag()` — sets JS flags and VIPS
module dependency
- `wp_get_chromium_major_version()` — browser detection for DIP support
- `wp_set_up_cross_origin_isolation()` — enables isolation in block editor
- `wp_start_cross_origin_isolation_output_buffer()` — sends DIP header
- `wp_add_crossorigin_attributes()` — adds `crossorigin="anonymous"` to
HTML tags
=== Hook registrations (`wp-includes/default-filters.php`)
- `admin_init` → `wp_set_client_side_media_processing_flag`
- `load-post.php` / `load-post-new.php` / `load-site-editor.php` / `load-
widgets.php` → `wp_set_up_cross_origin_isolation`
=== REST API (`wp-includes/rest-api/`)
- `POST /wp/v2/media/{id}/sideload` endpoint — uploads client-processed
image sub-sizes
- `POST /wp/v2/media/{id}/finalize` endpoint — triggers
`wp_generate_attachment_metadata` filter after client processing
- `generate_sub_sizes` and `convert_format` request parameters on `POST
/wp/v2/media`
- `get_endpoint_args_for_item_schema()` override in attachments controller
- `remove_client_side_media_processing_filters()`, `sideload_item()`,
`filter_wp_unique_filename()`, `finalize_item()`,
`sideload_item_permissions_check()` methods
- REST index additions: `image_sizes`, `image_size_threshold`,
`image_output_formats`, `jpeg_interlaced`, `png_interlaced`,
`gif_interlaced`
=== Media templates (`wp-includes/media-template.php`)
- Cross-origin isolation output buffer in `wp_print_media_templates()`
- `crossorigin="anonymous"` attribute injection for media template tags
=== Script modules (`wp-includes/script-modules.php`)
- VIPS minified filename forcing logic
=== Build assets
- VIPS module entries in `script-modules-packages.min.php`
- `@wordpress/vips/worker` dependency in `script-loader-packages.min.php`
- VIPS exclusion rules in `Gruntfile.js` and `tools/gutenberg/copy.js`
=== Test files
- `tests/phpunit/tests/media/wpCrossOriginIsolation.php` (deleted)
- Sideload/finalize/generate_sub_sizes tests in `rest-attachments-
controller.php`
- Client-side media processing setup in `rest-schema-setup.php`
- Sideload/finalize route fixtures in `wp-api-generated.js`
== What Is Preserved
The following independent features are **not** removed:
- `wp_prevent_unsupported_mime_type_uploads` filter (Trac ticket 64836,
added in 6.8.0)
- `X-WP-Upload-Attachment-ID` response header (useful for error recovery)
- Pre-existing `post-process` endpoint (since 5.3.0) and `edit` endpoint
(since 5.5.0)
- `exif_orientation`, `filename`, `filesize`, `missing_image_sizes` schema
properties
- The `client-side-media-experiments/` plugin directory (not part of core)
== Proposed Fix
PR: https://github.com/WordPress/wordpress-develop/pull/11309
12 files changed, 1,507 lines deleted. All changes are deletions with no
new code added.
== Testing
1. Run `phpunit tests/phpunit/tests/media/` — no failures.
2. Run `phpunit tests/phpunit/tests/rest-api/rest-attachments-
controller.php` — no failures.
3. Run `phpunit tests/phpunit/tests/rest-api/rest-schema-setup.php` —
route list correct.
4. Upload images via the block editor and media library — standard server-
side sub-size generation works.
5. Run `npx grunt build --dev` — build succeeds without VIPS.
6. Confirm `build/wp-includes/js/dist/script-modules/vips/` no longer
exists.
--
--
Ticket URL: <https://core.trac.wordpress.org/ticket/64906#comment:2>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list