Testing composer image optimization

Pretty cool photo! From 28MB to 113KB is a pretty good ratio!

So this new feature only changes the ‘pre-upload’ phase. We intercept the file you try to upload, apply transformations on it and then swap the new smaller file and resume the old upload process.

It stays at 0% and uses “Processing…” in the pre-upload phase, so that is expected. I will try to also swap the “Uploading…” string at the bottom too.

4MB is still forbidden, the trick is that we optimize the image so it’s >4MB when possible, so it can survive the file size limitation.

I tried a few images from that site, but they all use PNG opacity so I can’t safely convert to JPG and the optimizer bails out.

I tested a 60MB PNG now, and the optimizer can deal with it, but uses over 4GB RAM while doing so to end up with a 360KB JPG.

What device, browser and OS version you were using on this test?

5 Likes

I added a new ‘Processing Upload’ composer status message so you know exactly what is happening now.

This feature is safe to be tested now, please let me know how it goes in your community!

9 Likes

Trying with a 1.6MB photo I took on my iPhone:

Wow, 300k and very high quality.

6 Likes

5 Likes

8 Likes

Hello Falco,

I started use the composer image optimization. I notice if i want to upload more photos then it will activate the reply button after the first image uploaded and only deactivate when the next image optimization finish. If click the reply button in this time then the other image uploads stuck and will compose only the text (processing). I cannot repro here because on Meta change the button quickly but on my site it hang most of the time ~10sec or more between uploads. I use the default settings and 3x ~3-4MB images

I tried it with Huawei P20 Pro Android 10 (Chrome 91.0. 4472.120) Webapp.

As you see on the video after the uploads (Feltöltés) the reply button activate. Each image ~2.3MB.

Is that possible to disable Reply button all the time while images upload?


I am confused with this settings. Is “kilobytes” is correct?

Screenshot 2021-07-16 at 10.41.51

Thank you for the answer! :slight_smile:

3 Likes

Thanks for the report! There was a bug when calculating the disabled status of the button:

Yes Kilobyte - Wikipedia. It defaults to half a megabyte, but you can tweak as you need. I’d recommend going as low as ~300kb if you want to save the most space.

5 Likes

Thanks for the fix. :slightly_smiling_face:

I see. I just thought that this is a misspelling bytes to kilobytes. Because I put 524288kb to the converter and it says 512mb. That was I confused it. But yeah now I understand :slightly_smiling_face: Thanks

3 Likes

Ohhhhh I see it now. My bad!

3 Likes

Hello,

Thanks for the fix :slight_smile: Now it is working great!

I have a question about mobile uploads. When i upload image from mobile it will not resize the image to the target px width. I think only the quality changes. If i try it on Desktop pc the resize working. Am I missed something? Thanks :slight_smile:

2 Likes

We try to resize on both mobile and desktop, but the resize operation may fail if your device hardware is too weak. When that’s the case we skip it.

4 Likes

Ahh I see… It seems to my Huawei too weak to do it, but I tried it now with my iPhone and the resize function also works well. That’s great! Thanks :slightly_smiling_face:

3 Likes

This 9mb image works here but not on our site running 2.8.0.beta3 (Chrome win desktop 91). When selected for upload (not dragged, picked through the device file picker) there is no error or user message shown, it just seems to be rejected for upload silently.

Our Files settings are all default I think (4096 max image size kb, composer media optimization image enabled, s3 storage, Cloudfront CDN etc).

I can’t see anything in the logs or browser console logs. Smaller files seem to work and rescale fine.

What to do, as in what info can I go find out to help diagnose this some more? :slight_smile:

2 Likes

Try enabling verbose logs:

#ssh into the server

cd /var/discourse
./launcher enter app
rails c
SiteSetting.composer_media_optimization_debug_mode = true

Then try uploading the image again, and after the failure open the browser logs.

Also, can you share the original image?

5 Likes

Here’s the original file: 9.01 MB file on MEGA

I’ve enabled SiteSetting.composer_media_optimization_debug_mode = true in the rails console but am not seeing anything in terms of extra output in the Chrome browser log as yet. Here’s the Chrome log for

  1. Creating a reply on an existing topic after enabling the debug site setting in the console.
  2. In the composer using the ‘file upload’ widget to pick the 9mb jpg.
Navigated to https://forums.mudspike.com/t/fyi-discourse-forum-software-update-thread/11937/51
64fdc2109944d83fbd7a700960b4b25bb93228af.js?__ws=forums.mudspike.com:2 Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src https://forums.mudspike.com/logs/ https://forums.mudspike.com/sidekiq/ https://forums.mudspike.com/mini-profiler-resources/ https://forums.mudspike.com/assets/ https://forums.mudspike.com/brotli_asset/ https://forums.mudspike.com/extra-locales/ https://forums.mudspike.com/highlight-js/ https://forums.mudspike.com/javascripts/ https://forums.mudspike.com/plugins/ https://forums.mudspike.com/theme-javascripts/ https://forums.mudspike.com/svg-sprite/ https://www.google-analytics.com/analytics.js".

(anonymous) @ 64fdc2109944d83fbd7a700960b4b25bb93228af.js?__ws=forums.mudspike.com:2
51:1 Refused to load the script 'https://static.cloudflareinsights.com/beacon.min.js' because it violates the following Content Security Policy directive: "script-src https://forums.mudspike.com/logs/ https://forums.mudspike.com/sidekiq/ https://forums.mudspike.com/mini-profiler-resources/ https://forums.mudspike.com/assets/ https://forums.mudspike.com/brotli_asset/ https://forums.mudspike.com/extra-locales/ https://forums.mudspike.com/highlight-js/ https://forums.mudspike.com/javascripts/ https://forums.mudspike.com/plugins/ https://forums.mudspike.com/theme-javascripts/ https://forums.mudspike.com/svg-sprite/ https://www.google-analytics.com/analytics.js". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.

application-82efa29739b1af3218502dce3f278a83b96bd1c738954f44a36624a240f8a9b0.js:1 Deprecation notice: Import the User class instead of using User (deprecated since Discourse 2.4.0) (removal in Discourse 2.6.0)
e.default @ application-82efa29739b1af3218502dce3f278a83b96bd1c738954f44a36624a240f8a9b0.js:1
get @ application-82efa29739b1af3218502dce3f278a83b96bd1c738954f44a36624a240f8a9b0.js:1
(anonymous) @ 39ea5db47cef6f4231b07f808d8907fea1fd31fa.js?__ws=forums.mudspike.com:1
e.withPluginApi @ application-82efa29739b1af3218502dce3f278a83b96bd1c738954f44a36624a240f8a9b0.js:1
initialize @ 39ea5db47cef6f4231b07f808d8907fea1fd31fa.js?__ws=forums.mudspike.com:1
i.initialize @ application-82efa29739b1af3218502dce3f278a83b96bd1c738954f44a36624a240f8a9b0.js:1
(anonymous) @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
e.each @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
e.walk @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
e.each @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
e.topsort @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
_runInitializer @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
runInstanceInitializers @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
_bootSync @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
didBecomeReady @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
t.invoke @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
t.flush @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
t.flush @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
n._end @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
n.end @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
n._run @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
n._join @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
n.join @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
d @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
(anonymous) @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
l @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:22
c @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:22
setTimeout (async)
(anonymous) @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:22
u @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:22
fireWith @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:22
fire @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:22
u @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:22
fireWith @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:22
ready @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:22
B @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:22
vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:22 [Violation] Added non-passive event listener to a scroll-blocking 'touchstart' event. Consider marking event handler as 'passive' to make the page more responsive. See https://www.chromestatus.com/feature/5745543795965952
add @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:22
(anonymous) @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:22
each @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:13
each @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:13
Se @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:22
on @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:22
setupHandler @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
setup @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
setupEventDispatcher @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
_bootSync @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
didBecomeReady @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
t.invoke @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
t.flush @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
t.flush @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
n._end @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
n.end @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
n._run @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
n._join @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
n.join @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
d @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
(anonymous) @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
l @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:22
c @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:22
vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:22 [Violation] Added non-passive event listener to a scroll-blocking 'touchstart' event. Consider marking event handler as 'passive' to make the page more responsive. See https://www.chromestatus.com/feature/5745543795965952
add @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:22
(anonymous) @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:22
each @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:13
each @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:13
Se @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:22
on @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:22
setupComposerResizeEvents @ application-82efa29739b1af3218502dce3f278a83b96bd1c738954f44a36624a240f8a9b0.js:1
didInsertElement @ application-82efa29739b1af3218502dce3f278a83b96bd1c738954f44a36624a240f8a9b0.js:1
n @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
trigger @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
n @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
o.didCreate @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
t.commit @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
n.commit @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
o.commit @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
t._renderRoots @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
t._renderRootsTransaction @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
t._renderRoot @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
t._appendDefinition @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
t.appendOutletView @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
t.invoke @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
t.flush @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
t.flush @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
n._end @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
n.end @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
n._run @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
n._join @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
n.join @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
d @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
(anonymous) @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:30
l @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:22
c @ vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:22
Show 2 more frames
vendor-9297d3b5d396b76cde3e1a19c960cf10c5edf8be99b1f5aeff21012e3ae57a34.js:22 [Violation] 'setTimeout' handler took 373ms

The https://forums.mudspike.com/logs/ is empty, as in, no new entries.

2 Likes

Your site has two problems.

  1. Site is behind Cloudflare full site proxy. You can go into your DNS settings and make the orange cloud gray to disable this. Discourse is know to break randomly when behind Cloudflare transformations.

  2. Your site is not configured for HTTPS. You did not find this earlier because of 1. Every new browser API nowadays is exclusive to HTTPS, and every public site should be HTTPS. You need to properly setup HTTPS and go into the rails console again and run SiteSetting.force_https = true.

4 Likes

Problems is such a strong word, more just deliberate weirdness :slight_smile: - we’ll just disable this new feature if you are now confident that it is known not to play well with Cloudflare. We don’t use Brotli or Rocket Loader.

We use Cloudflare as a way of wildcarding over S3/Cloudfront, and page rules for redirecting over HTTPS, so this is deliberate for us and saves us some self hosting costs - S3 upload bucket, cdn url and bucket name in CNAME - #7 by fearlessfrog

The main problem is that if your site if available over HTTPS, SiteSetting.force_https must be true. Can you try that?

We use that setting for generating the Discourse forum links, without it link in emails for example will default to HTTP:

3 Likes

Yep, that seems to work - thank you!

We left that off for so long, as the ‘Flexible’ SSL on the Cloudflare side was pretty much open security wise anyway, so anything that arrives was redirect to HTTPS via the page rule anyway and I wasn’t sure of the impact. We have other sites under the .mudspike.com domain that need this CF set-up, so the poor forum has been misconfigured like this for a while now.

I do get this in the browser log when uploaded, but the image does client compress/resize ok, so this might just be valid fall backs as part of the moxjpeg encoding anyway.

mozjpeg_enc.js:1 wasm streaming compile failed: TypeError: Failed to execute 'compile' on 'WebAssembly': Incorrect response MIME type. Expected 'application/wasm'.
(anonymous) @ mozjpeg_enc.js:1
Promise.then (async)
(anonymous) @ mozjpeg_enc.js:1
Promise.then (async)
instantiateAsync @ mozjpeg_enc.js:1
createWasm @ mozjpeg_enc.js:1
(anonymous) @ mozjpeg_enc.js:1
loadLibs @ media-optimization-worker.js:12
optimize @ media-optimization-worker.js:6
onmessage @ media-optimization-worker.js:11
mozjpeg_enc.js:1 falling back to ArrayBuffer instantiation
(anonymous) @ mozjpeg_enc.js:1
Promise.then (async)
(anonymous) @ mozjpeg_enc.js:1
Promise.then (async)
instantiateAsync @ mozjpeg_enc.js:1
createWasm @ mozjpeg_enc.js:1
(anonymous) @ mozjpeg_enc.js:1
loadLibs @ media-optimization-worker.js:12
optimize @ media-optimization-worker.js:6
onmessage @ media-optimization-worker.js:11
squoosh_resize.js:9 `WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:
 TypeError: Failed to execute 'compile' on 'WebAssembly': Incorrect response MIME type. Expected 'application/wasm'.
load @ squoosh_resize.js:9
async function (async)
load @ squoosh_resize.js:9
init @ squoosh_resize.js:14
async function (async)
init @ squoosh_resize.js:14
loadLibs @ media-optimization-worker.js:12
async function (async)
loadLibs @ media-optimization-worker.js:12
optimize @ media-optimization-worker.js:6
onmessage @ media-optimization-worker.js:11

Thanks for your help.

1 Like

That was fixed in our nginx some time ago. When did you last rebuild? Can you try rebuilding?

2 Likes