vips: ensure single instance#76780
Conversation
|
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 If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
Note that I'm not entirely sure what the positive impact of this fix might be. Performance-wise, I couldn't measure much of an uplift, but it may solve some of the existing issues around memory usage and resulting crashes. |
|
Size Change: 0 B Total Size: 7.66 MB ℹ️ View Unchanged
|
|
Flaky tests detected in fae657a. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/23489557643
|
andrewserong
left a comment
There was a problem hiding this comment.
This looks like a good improvement to me, too, and it's testing well for me manually 👍
|
Thank you for taking a look, @swissspidy and @andrewserong! 👍 |
Co-authored-by: sgomes <sergiomdgomes@git.wordpress.org> Co-authored-by: swissspidy <swissspidy@git.wordpress.org> Co-authored-by: andrewserong <andrewserong@git.wordpress.org>
Co-authored-by: sgomes <sergiomdgomes@git.wordpress.org> Co-authored-by: swissspidy <swissspidy@git.wordpress.org> Co-authored-by: andrewserong <andrewserong@git.wordpress.org>
|
Thanks for this @sgomes! |
Fix unintended revert of #76780 during rebase. The promise-based approach ensures only a single Vips instance is ever created, even when multiple callers race on initialization.
Co-authored-by: sgomes <sergiomdgomes@git.wordpress.org> Co-authored-by: swissspidy <swissspidy@git.wordpress.org> Co-authored-by: andrewserong <andrewserong@git.wordpress.org>
* Use image.copyMemory() for batch thumbnail generation Decode the source image once via copyMemory() and use thumbnailImage() for each sub-size, instead of re-decoding the source buffer for every thumbnail. This approach was suggested by the wasm-vips maintainer and avoids both re-decoding overhead and the need for intermediate format conversions. The new batchResizeImage() function in the vips package materializes the decoded image in WASM memory, then generates all thumbnails from that single in-memory copy. Results are written directly to the target output format, eliminating separate transcode steps. Falls back to per-thumbnail processing if the batch operation fails. * Restore vipsPromise singleton pattern in getVips() Fix unintended revert of #76780 during rebase. The promise-based approach ensures only a single Vips instance is ever created, even when multiple callers race on initialization. * Extract shared resize/crop logic into common helpers Add applyResizeAndCrop() to consolidate the duplicated dimension calculation and crop logic between resizeImage and batchResizeImage. Add buildSaveOptions() to unify save option construction, which also fixes the missing AVIF effort=2 setting in resizeImage. * Address review nits in applyResizeAndCrop and batchResizeImage Clone the resize config into a local target object rather than mutating the caller's ImageSizeCrop parameter, and drop an unused strOptions constant in batchResizeImage.
The feature shipping target moved from 7.0 to 7.1 (per #76756). Bring the architecture explanation and how-to guide up to date with the post-7.0-cycle state of the code: - Reposition introductions around 7.1 with 7.0 as the groundwork cycle. - HEIC/HEIF: document the canvas-based fallback path (createImageBitmap, HTMLImageElement+OffscreenCanvas, HEIC container parsing + WebCodecs VideoDecoder), JPEG companion file, and isHeicCanvasSupported() gate. - AVIF: note the wp_prevent_unsupported_mime_type_uploads bypass when generate_sub_sizes=false (#76371). - Batch thumbnail generation via image.copyMemory() / thumbnailImage() (#76979). - Sub-size deduplication via image_size: string|string[] on the sideload route (#77036). - Single VIPS instance via promise caching (#76780). - Build-output trimming: remove vips-jxl.wasm (#76639), skip non-min worker (#76615), skip WASM-inlined sourcemaps (#75993). - COI: <img> excluded from cross-origin attribute injection (#76618). - Loosened feature-detection thresholds: 2 cores, 3g (#76616). - Post-saving lock fix: Save Draft now respects the lock (#76973). - convert_format declared as boolean on sideload route (#77565). - Fix incorrect REST index settings list (only image_sizes and image_size_threshold are exposed). - Remove references to client_side_supported_mime_types filter (PR #76549 was closed unmerged); state the supported MIME set is fixed at CLIENT_SIDE_SUPPORTED_MIME_TYPES. Refs #75111.
What?
This PR ensures that a single instance of
vipsgets created, by caching a promise instead of a fully initialised instance.Why?
The existing code has a race condition where successive calls to
getVips()can end up creating multiple instances. SincegetVipsis async, if a new call is made before the instance initialisation is complete, it will create a new instance.How?
This PR changes the cache to a promise instead of an instance. This way, the promise is immediately set the first time
getVips()is called, and subsequent calls will wait for the same promise, instead of creating their own.Testing Instructions
npm run test:unit -- packages/upload-mediapassesnpm run test:unit -- packages/vipspassesUse of AI Tools
No AI tools were used.