Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slow getMaxCanvasWidth() with Firefox's 'strict' protection #1524

Closed
Mr-Kanister opened this issue Jan 1, 2025 · 1 comment
Closed

Slow getMaxCanvasWidth() with Firefox's 'strict' protection #1524

Mr-Kanister opened this issue Jan 1, 2025 · 1 comment
Labels
Milestone

Comments

@Mr-Kanister
Copy link

Mr-Kanister commented Jan 1, 2025

Describe the bug

When using the equirectangular-tiles adapter in a Firefox browser set to security protection level 'strict', I noticed that the load times of the viewer took off to about 3 seconds while completely freezing the page despite using promises. When using the normal security protection or another browser, those load times were much shorter.

I tracked it down to this canvas read:

if (ctx.getImageData(0, 0, 1, 1).data[0] > 0) {

I assume, in order to read the canvas, firefox first completely shuffles it via the cpu (effectively anonymizing it) which takes quite some time. After a quick search, I found this repo: https://github.com/jhildenbiddle/canvas-size, which was cited here in another issue some time ago. I tried their approach on fixing this issue: https://github.com/jhildenbiddle/canvas-size/blob/master/src/canvas-test.js#L52

They first copy the desired pixel from the big canvas to a 1x1 canvas and read it from there. If firefox decides to randomize this one, it will take just a short glimpse and won't disturb the user.

To be explicit, I hacked together the following code, which reduced the wait times:

function getMaxCanvasWidth(maxWidth) {
	let width = maxWidth;
	let pass = false;
	while (width > 1024 && !pass) {
	  console.log(width);
    const testCvs = document.createElement("canvas");
    testCvs.width = width;
    testCvs.height = width / 2;
    const cropCvs = document.createElement("canvas");
	cropCvs.width = 1;
	cropCvs.height = 1;
    const testCtx = testCvs.getContext("2d");
    const cropCtx = cropCvs.getContext("2d");
    testCtx.fillStyle = "white";
    testCtx.fillRect(0, 0, 1, 1);
	cropCtx.drawImage(testCvs, 0, 0, 1, 1, 0, 0, 1, 1);
    try {
			
      if (cropCtx.getImageData(0, 0, 1, 1).data[0] > 0) {
        pass = true;
      }
    } catch {
    }
    testCvs.width = 0;
    testCvs.height = 0;
    if (!pass) {
      width /= 2;
    }
  }
  if (pass) {
    return width;
  } else {
    throw new PSVError("Unable to detect system capabilities");
  }
}

Maybe we should consider using the node package of the above mentioned repo to stay up to date on any changes: https://www.npmjs.com/package/canvas-size

Online demo URL

https://photo-sphere-viewer.js.org/guide/adapters/equirectangular-tiles.html

Photo Sphere Viewer version

5.11.4

Plugins loaded

No response

OS & browser

Debian 12, Firefox 128.5.0esr

Additional context

No response

@Mr-Kanister Mr-Kanister added the bug label Jan 1, 2025
@mistic100 mistic100 added this to the 5.11.5 milestone Jan 1, 2025
@mistic100
Copy link
Owner

Thank you for the deep analysis.

I refrain from using external libraries when not needing, especially here where I only need 10% of the code.

I only copied the relevant code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants