Client Side Media: Add device/browser capability detection#75863
Client Side Media: Add device/browser capability detection#75863adamsilverstein merged 11 commits intotrunkfrom
Conversation
Document the upcoming capability detection areas including credentialless iframe support, device memory, network conditions, and Web Worker checks. Notes that browsers without credentialless support will have client-side media disabled by default, with a server-side filter opt-in.
Add four new checks to detectClientSideMediaSupport(): Web Worker support, credentialless iframe support, device memory (≤2 GB), and network conditions (data saver/2g). These gate client-side media processing on low-end devices and unsupported browsers before the expensive CSP check.
The saveData check already covers reduced data mode but the docblock only referenced "data saver". This makes it explicit.
|
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. |
|
Size Change: +258 B (0%) Total Size: 6.84 MB
ℹ️ View Unchanged
|
- Correct the JSDoc filter name from `client_side_media_processing_enabled` to `wp_client_side_media_processing_enabled` to match the canonical PHP filter. - Add null guard for `window.HTMLIFrameElement` before accessing `.prototype` to prevent TypeError in partial DOM environments. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
I wasn't sure if this is ready for review yet, so apologies if this is too early, but thought I'd take it for a quick spin!
This looks nearly ready to me, and is flagging in the console when it's disabled (e.g. in Safari and Firefox) 👍
The mains questions I left were just:
- Should we make 4g network the floor instead of 3g?
- Should we also check for number of cores?
Not a blocker, though, as we can keep tweaking these things in follow-ups of course!
Co-authored-by: Andrew Serong <14988353+andrewserong@users.noreply.github.com>
The WASM vips bundle is large and requires many sub-image uploads, so 3g connections are too slow for a good experience. Setting 4g as the effective floor for network speed.
WASM vips processing needs multiple cores for threading plus the main thread. Require at least 4 CPU cores to ensure a smooth experience.
Co-authored-by: Ramon <ramonjd@users.noreply.github.com>
Reduces repetition by restoring WebAssembly and SharedArrayBuffer in beforeEach instead of repeating the same two lines at the start of every test case.
|
Looking pretty good, thanks a lot @adamsilverstein 🙇🏻 I'll defer to @andrewserong for confidence check, but in my tests: ✅ Verify detectClientSideMediaSupport() returns supported: false with correct reason in Chrome DevTools when simulating: slow network (2g), low memory, data saver Chrome is a little annoying in that I found the detection takes place too early. So I emulate 3g, reload the page and I enabled Save Data (data saver) mode and it detected it:
|
There was a problem hiding this comment.
Looking good to me, Ramon beat me to it for a re-review!
Something I wondered about briefly on a second look is that these checks allow pass-through if properties aren't available. So for example, it seems that checking for connection is Chrome-only right now: https://caniuse.com/?search=navigator.connection
Given that a) we're already bailing early for Firefox + Safari and b) some of these properties might not be available, I think the pass-through approach (defaulting to opt-in if a check cannot be performed) is actually preferable. But if we run into any issues, we could always adjust the if statements to only allow the feature to be switched on if some of these properties are present. In any case, not a blocker for now, I'm mostly just thinking out loud.
As an aside, it's a shame we can only check the connection speed on Chrome!
Thanks again for all the follow-ups 🚀
|
Thanks for the reviews and feedback. I'm going to add the typing suggested in #75863 (comment) then merge this. |
Replace `as any` casts with proper typed interfaces for navigator.deviceMemory and navigator.connection properties.
* Update feature detection docblock for planned checks Document the upcoming capability detection areas including credentialless iframe support, device memory, network conditions, and Web Worker checks. Notes that browsers without credentialless support will have client-side media disabled by default, with a server-side filter opt-in. * Add device/browser capability detection checks Add four new checks to detectClientSideMediaSupport(): Web Worker support, credentialless iframe support, device memory (≤2 GB), and network conditions (data saver/2g). These gate client-side media processing on low-end devices and unsupported browsers before the expensive CSP check. * Mention reduced data mode in docblock The saveData check already covers reduced data mode but the docblock only referenced "data saver". This makes it explicit. * Fix filter name in docblock and add HTMLIFrameElement guard - Correct the JSDoc filter name from `client_side_media_processing_enabled` to `wp_client_side_media_processing_enabled` to match the canonical PHP filter. - Add null guard for `window.HTMLIFrameElement` before accessing `.prototype` to prevent TypeError in partial DOM environments. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update packages/upload-media/src/feature-detection.ts Co-authored-by: Andrew Serong <14988353+andrewserong@users.noreply.github.com> * Add 3g to network condition check The WASM vips bundle is large and requires many sub-image uploads, so 3g connections are too slow for a good experience. Setting 4g as the effective floor for network speed. * Add hardware concurrency check WASM vips processing needs multiple cores for threading plus the main thread. Require at least 4 CPU cores to ensure a smooth experience. * Update packages/upload-media/src/feature-detection.ts Co-authored-by: Ramon <ramonjd@users.noreply.github.com> * Move global restores to beforeEach in tests Reduces repetition by restoring WebAssembly and SharedArrayBuffer in beforeEach instead of repeating the same two lines at the start of every test case. * Fix missing period in WebAssembly test assertion * Add TypeScript interfaces for Navigator extensions Replace `as any` casts with proper typed interfaces for navigator.deviceMemory and navigator.connection properties. --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Co-authored-by: Ramon <ramonjd@users.noreply.github.com>
|
I just cherry-picked this PR to the wp/7.0 branch to get it included in the next release: c98993a |
|
I just cherry-picked this PR to the release/22.6 branch to get it included in the next release: b380d66 |
* Update feature detection docblock for planned checks Document the upcoming capability detection areas including credentialless iframe support, device memory, network conditions, and Web Worker checks. Notes that browsers without credentialless support will have client-side media disabled by default, with a server-side filter opt-in. * Add device/browser capability detection checks Add four new checks to detectClientSideMediaSupport(): Web Worker support, credentialless iframe support, device memory (≤2 GB), and network conditions (data saver/2g). These gate client-side media processing on low-end devices and unsupported browsers before the expensive CSP check. * Mention reduced data mode in docblock The saveData check already covers reduced data mode but the docblock only referenced "data saver". This makes it explicit. * Fix filter name in docblock and add HTMLIFrameElement guard - Correct the JSDoc filter name from `client_side_media_processing_enabled` to `wp_client_side_media_processing_enabled` to match the canonical PHP filter. - Add null guard for `window.HTMLIFrameElement` before accessing `.prototype` to prevent TypeError in partial DOM environments. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update packages/upload-media/src/feature-detection.ts Co-authored-by: Andrew Serong <14988353+andrewserong@users.noreply.github.com> * Add 3g to network condition check The WASM vips bundle is large and requires many sub-image uploads, so 3g connections are too slow for a good experience. Setting 4g as the effective floor for network speed. * Add hardware concurrency check WASM vips processing needs multiple cores for threading plus the main thread. Require at least 4 CPU cores to ensure a smooth experience. * Update packages/upload-media/src/feature-detection.ts Co-authored-by: Ramon <ramonjd@users.noreply.github.com> * Move global restores to beforeEach in tests Reduces repetition by restoring WebAssembly and SharedArrayBuffer in beforeEach instead of repeating the same two lines at the start of every test case. * Fix missing period in WebAssembly test assertion * Add TypeScript interfaces for Navigator extensions Replace `as any` casts with proper typed interfaces for navigator.deviceMemory and navigator.connection properties. --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Co-authored-by: Ramon <ramonjd@users.noreply.github.com>
CI run: #11059. See #64595. --- I've included a log of the Gutenberg changes with the following command: git log --reverse --format="- %s" 23b566c72e9c4a36219ef5d6e62890f05551f6cb..022d8dd3d461f91b15c1f0410649d3ebb027207f | sed 's|#\([0-9][0-9]*\)|https://github.com/WordPress/gutenberg/pull/\1|g; /github\.com\/WordPress\/gutenberg\/pull/!d' | pbcopy - Pattern Editing: Fix nested patterns/sections (WordPress/gutenberg#75772) - QuickEdit: rename status label and remove extra labels in popup (WordPress/gutenberg#75824) - Fix block editing modes not recomputing when isolated editor value changes (WordPress/gutenberg#75821) - Synced patterns: Fix block editing mode of synced pattern content when nested in an unsynced pattern (WordPress/gutenberg#75818) - Block Support: Fix custom CSS not saved when style schema is not defined (WordPress/gutenberg#75797) - Gallery: Fixes keyboard focus escaping the lightbox overlay when navigating a gallery with Tab/Shift+Tab. (WordPress/gutenberg#75852) - Navigation Overlay Close: Set Close as default text, rather than using a placeholder (WordPress/gutenberg#75692) - RTC: Fix entity save call / initial persistence. (WordPress/gutenberg#75841) - Real-time collaboration: Improve collaboration within the same rich text (WordPress/gutenberg#75703) - Client Side Media: Add device/browser capability detection (WordPress/gutenberg#75863) - Navigation editing: simplify edit/view buttons (WordPress/gutenberg#75819) - Add core/icon block to theme.json schema (WordPress/gutenberg#75813) - Fix error when undoing newly added pattern (WordPress/gutenberg#75850) - Page List Item: Replace RawHTML with dangerouslySetInnerHTML for label and title (WordPress/gutenberg#75890) - REST API: Make filter_wp_unique_filename() static to match core, plus avoid duplicate routes (WordPress/gutenberg#75782) - RichText: useAnchor: Fix TypeError in virtual element (WordPress/gutenberg#75900) - DataViews: Remove menu divider again. (WordPress/gutenberg#75908) - Theme: Add build plugins to inject design token fallbacks (WordPress/gutenberg#75901) - Theme: Remove global stylesheet (WordPress/gutenberg#75879) - Real-time collaboration: Remove ghost awareness state explicitly when refreshing (WordPress/gutenberg#75883) - Real-time collaboration: Expand mergeCrdtBlocks() automated testing (WordPress/gutenberg#75923) - Fix client-side media file naming (WordPress/gutenberg#75817) - Add: Connectors screen (WordPress/gutenberg#75833) - Merge document meta into state map (WordPress/gutenberg#75830) - Move WordPress meta key from sync package to core-data (WordPress/gutenberg#75846) - Bugfix: Fix casing of getPersistedCRDTDoc (WordPress/gutenberg#75922) - Add debug logging to SyncManager (WordPress/gutenberg#75924) - DataForm: fix label colors (WordPress/gutenberg#75730) - DataViews: minimize padding for primary action buttons (WordPress/gutenberg#75721) (WordPress/gutenberg#75947) - Connectors: Add `_ai_` prefix to connector setting names and fix naming inconsistencies (WordPress/gutenberg#75948) - Connectors: Unhook Core callbacks in Gutenberg coexistence (WordPress/gutenberg#75935) - Unsynced patterns: Rename 'Disconnect pattern' to 'Detach pattern' in context menu (WordPress/gutenberg#75807) - Editor: Remove View dropdown and pinned items from revisions header (WordPress/gutenberg#75951) - Fix: Template revisions infinite spinner (WordPress/gutenberg#75953) - Backport: Avoid flickering while refreshing (WordPress/gutenberg#74572) (WordPress/gutenberg#75952) - Add wp_ prefix to real time collaberation option. (WordPress/gutenberg#75837) git-svn-id: https://develop.svn.wordpress.org/trunk@61750 602fd350-edb4-49c9-b593-d223f7449a82
CI run: WordPress/wordpress-develop#11059. See #64595. --- I've included a log of the Gutenberg changes with the following command: git log --reverse --format="- %s" 23b566c72e9c4a36219ef5d6e62890f05551f6cb..022d8dd3d461f91b15c1f0410649d3ebb027207f | sed 's|#\([0-9][0-9]*\)|https://github.com/WordPress/gutenberg/pull/\1|g; /github\.com\/WordPress\/gutenberg\/pull/!d' | pbcopy - Pattern Editing: Fix nested patterns/sections (WordPress/gutenberg#75772) - QuickEdit: rename status label and remove extra labels in popup (WordPress/gutenberg#75824) - Fix block editing modes not recomputing when isolated editor value changes (WordPress/gutenberg#75821) - Synced patterns: Fix block editing mode of synced pattern content when nested in an unsynced pattern (WordPress/gutenberg#75818) - Block Support: Fix custom CSS not saved when style schema is not defined (WordPress/gutenberg#75797) - Gallery: Fixes keyboard focus escaping the lightbox overlay when navigating a gallery with Tab/Shift+Tab. (WordPress/gutenberg#75852) - Navigation Overlay Close: Set Close as default text, rather than using a placeholder (WordPress/gutenberg#75692) - RTC: Fix entity save call / initial persistence. (WordPress/gutenberg#75841) - Real-time collaboration: Improve collaboration within the same rich text (WordPress/gutenberg#75703) - Client Side Media: Add device/browser capability detection (WordPress/gutenberg#75863) - Navigation editing: simplify edit/view buttons (WordPress/gutenberg#75819) - Add core/icon block to theme.json schema (WordPress/gutenberg#75813) - Fix error when undoing newly added pattern (WordPress/gutenberg#75850) - Page List Item: Replace RawHTML with dangerouslySetInnerHTML for label and title (WordPress/gutenberg#75890) - REST API: Make filter_wp_unique_filename() static to match core, plus avoid duplicate routes (WordPress/gutenberg#75782) - RichText: useAnchor: Fix TypeError in virtual element (WordPress/gutenberg#75900) - DataViews: Remove menu divider again. (WordPress/gutenberg#75908) - Theme: Add build plugins to inject design token fallbacks (WordPress/gutenberg#75901) - Theme: Remove global stylesheet (WordPress/gutenberg#75879) - Real-time collaboration: Remove ghost awareness state explicitly when refreshing (WordPress/gutenberg#75883) - Real-time collaboration: Expand mergeCrdtBlocks() automated testing (WordPress/gutenberg#75923) - Fix client-side media file naming (WordPress/gutenberg#75817) - Add: Connectors screen (WordPress/gutenberg#75833) - Merge document meta into state map (WordPress/gutenberg#75830) - Move WordPress meta key from sync package to core-data (WordPress/gutenberg#75846) - Bugfix: Fix casing of getPersistedCRDTDoc (WordPress/gutenberg#75922) - Add debug logging to SyncManager (WordPress/gutenberg#75924) - DataForm: fix label colors (WordPress/gutenberg#75730) - DataViews: minimize padding for primary action buttons (WordPress/gutenberg#75721) (WordPress/gutenberg#75947) - Connectors: Add `_ai_` prefix to connector setting names and fix naming inconsistencies (WordPress/gutenberg#75948) - Connectors: Unhook Core callbacks in Gutenberg coexistence (WordPress/gutenberg#75935) - Unsynced patterns: Rename 'Disconnect pattern' to 'Detach pattern' in context menu (WordPress/gutenberg#75807) - Editor: Remove View dropdown and pinned items from revisions header (WordPress/gutenberg#75951) - Fix: Template revisions infinite spinner (WordPress/gutenberg#75953) - Backport: Avoid flickering while refreshing (WordPress/gutenberg#74572) (WordPress/gutenberg#75952) - Add wp_ prefix to real time collaberation option. (WordPress/gutenberg#75837) Built from https://develop.svn.wordpress.org/trunk@61750 git-svn-id: http://core.svn.wordpress.org/trunk@61056 1a063a9b-81f0-0310-95a4-ce76da25c4cd

Summary
Fixes #75849
Implements the four new capability detection checks from #75849 in
detectClientSideMediaSupport():Workeris undefinedcredentiallessiframes, since cross-origin isolation breaks third-party embedsnavigator.deviceMemory2g/slow-2gAll new checks are ordered before the existing blob worker CSP test (the most expensive check). Check ordering:
Context
Part of #74333 (Client Side Media iteration for WordPress 7.0). Tracked in #75849.
Test plan
detectClientSideMediaSupport()returnssupported: falsewith correct reason in Chrome DevTools when simulating: slow network (2g), low memory, data saver🤖 Generated with Claude Code