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

Shadow causes drop in perf #8076

Open
vitonsky opened this issue Jul 22, 2022 · 11 comments
Open

Shadow causes drop in perf #8076

vitonsky opened this issue Jul 22, 2022 · 11 comments

Comments

@vitonsky
Copy link
Contributor

Version

5.2.1

Test Case

https://codesandbox.io/s/unruffled-black-bdcgfg

Information about environment

browser

Steps To Reproduce

  1. open test case https://codesandbox.io/s/unruffled-black-bdcgfg in chrome browser
  2. open iframe that contain result in new tab (url like https://bdcgfg.csb.app/)
  3. open frame rate meter (dev tools > ctrl + shift + p > write FPS)
  4. start move some object and look at FPS popup

Expected Behavior

60-120 FPS

Actual Behavior

8-12 FPS


If you will comment property shadow in function mkObject, you will have 60-120 FPS. The shadows it's our problem.

How it may be fixed?

@ShaMan123
Copy link
Contributor

ShaMan123 commented Jul 22, 2022

This is a known issue with caching.
fabric's power is in caching but shadows aren't cached because of shadow rotation/offset that are relative to canvas.
We are planning a rethink of caching but it's further down the line.
You are facing a perf issue, so think of a perf solution.
Since you interact only with one object at a time think of rendering the rest to a cache.
I wrote some POCs for that #7880 is one of them, https://fabricjs.com/raphael-vs-fabric-simple?n=2000&optimize_caching=1 is another.
But it might be that the simplest fix for you is overriding shouldCache and putting objects into caching groups as suggested in #7871

@ShaMan123 ShaMan123 changed the title Shadows make performance not usable Shadow causes drop in perf Jul 22, 2022
@ShaMan123
Copy link
Contributor

#7874

@asturur
Copy link
Member

asturur commented Jul 28, 2022

The correct answer is yes.
Shadow causes drop in perf => yes.
There is only one solution here.
If you can decide for the UX of what are you building, suggest a that the offsetX and offsetY of the shadow is 0, or decide if it doesn't matter that while offsets are positive number, the shadow won't stay put while the object rotate.

At that point sligly change the object render method to draw the shadow when is creating the cache ( i can help with that ),and not when is drawing the cache on top of the canvas.

You should go back to 60fps

@asturur
Copy link
Member

asturur commented Jul 28, 2022

as an alternative:

const mkObject = (props) => {
  const path = new fabric.Path(createPath(150, 150), {
    stroke: "#000",
    fill: "yellow",
    left: 0,
    top: 0,
    shadow: {
      color: "rgba(0,0,0,0.5)",
      offsetX: 0,
      offsetY: 0,
      blur: 10
    },
    ...props
  });
  return new fabric.Group([path]);
};

goes back to 60fps

@stale
Copy link

stale bot commented Aug 12, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale Issue marked as stale by the stale bot label Aug 12, 2022
@stale stale bot closed this as completed Oct 1, 2022
@vitonsky
Copy link
Contributor Author

vitonsky commented Oct 1, 2022

Not stale. Let's leave it opened to another people can found this issue and suggest solution

@ShaMan123 ShaMan123 added fix-next v6 and removed stale Issue marked as stale by the stale bot labels Oct 1, 2022
@ShaMan123
Copy link
Contributor

ShaMan123 commented Oct 1, 2022

I have labeled it so the bot will stop harrassing this issue.
@vitonsky I am working on a fix that should solve this entirely #8298
I would appreciate your feedback/testing and any other way that you would like (if of course) to contribute

It seems stable already.

@ShaMan123 ShaMan123 reopened this Oct 1, 2022
@ShaMan123
Copy link
Contributor

ShaMan123 commented Oct 1, 2022

After experimenting a bit it with #8298 I suggest:

  • putting all objects into a group
  • force the group to cache by overriding shouldCache (which is a perf sinkhole for group so that's 2 birds)
  • when rotating force it not to perform caching
  • listen to mousedown with subTargetCheck: true and manually set the active object to the subtarget while forcing the group to render without it and cache

This can be achieved in the current state of the code pretty much as well

@ShaMan123
Copy link
Contributor

Edit fabric-vanillajs-sandbox (forked)

The rendering at mousedown takes too long
That can be mitigated by using more group under the main group or with a visual effect to distract the user

@ShaMan123
Copy link
Contributor

Truth be told #8298 doesn't really solve anything here. Only makes it simpler to instruct group to cache or not.
It is a large group perf issue which I discussed at the top of the thread

@vitonsky
Copy link
Contributor Author

vitonsky commented Oct 2, 2022

Thank you for research, it looks very useful, i will try suggested approach and will leave feedback

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

No branches or pull requests

3 participants