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

Multi Month Plugin Forced reflow while executing JavaScript causing laggy interactions #7209

Open
1 task done
DevDotJoel opened this issue Feb 14, 2023 · 10 comments
Open
1 task done

Comments

@DevDotJoel
Copy link

DevDotJoel commented Feb 14, 2023

Reduced Test Case

https://codesandbox.io/s/quizzical-chandrasekhar-8kux86?file=/src/App.js

Do you understand that if a reduced test case is not provided, we will intentionally delay triaging of your ticket?

  • I understand

Which connector are you using (React/Angular/etc)?

React

Bug Description

Hello,

I'm using full-calendar 6.1.4 for the react connector.

When im using multiMonthPlugin with interactionPlugin and dayGridPlugin i get a warning on my console saying :
"[Violation] 'click' handler took 220ms"
"[Violation] Forced reflow while executing JavaScript took ms"

It happens everytime i load the page, change dates etc

Thanks.

@acerix acerix changed the title Multi Month Plugin Forced reflow while executing JavaScript Multi Month Plugin Forced reflow while executing JavaScript causing laggy interactions Feb 16, 2023
@septatrix
Copy link

This also happens with on some demo pages (e.g. event interaction) so I assume it is a general problem. Seems to be the same as #6741

@arshaw arshaw added this to the upcoming-release milestone Mar 13, 2023
@arshaw
Copy link
Member

arshaw commented Mar 13, 2023

@DevDotJoel and @septatrix , I believe you when you say this his happening, but unfortunately I'm not able to recreate. Does this happen upon page load, or after you do some action?

Could you record everything (including dev console where this error is appearing) with a screen capture tool like https://gifcap.dev/ ?

@arshaw
Copy link
Member

arshaw commented Mar 13, 2023

@acerix, a recreation from you would be great as well!

@acerix acerix removed the React Only label Mar 13, 2023
@septatrix
Copy link

As can be seen in the screencast it is not completely deterministic and probably depends on CPU utilization etc.

Screencast.from.2023-03-14.01-03-44.webm

@septatrix
Copy link

Making a performance recording seems to reveal that this is due to calling getBoundingClientRect() in the PositionCache which always results in a style recalculation, i.e. forced reflow, given that any of the DOM changed compared to the last time this was called:

let originClientRect = this.originClientRect = originEl.getBoundingClientRect() // relative to viewport top-left

As it seems like this cache exists precisely to reduce this impact there does not seems to be a simple fix for this. Improving DOM structure, CSS selectors/styles etc could improve this though that is likely a rather cumbersome process. However, I noticed that the only DOM change (at least in my case) is the addition and removal of the fc-unselectable class to the body element. I am not sure which purpose it fulfills though running document.body.classList.add = console.log and thus preventing the classlist from changing prevented the violations to show up. I am sure there is a reason to set this class but just wanted to share my investigation so far and confirm my suspicion about the reflow cause.

Finally, I am not sure whether @DevDotJoel is experiencing this in the same scenario or under slightly different circumstances as they also mention page loads and date changes. In those two cases I only rarely get the warning (though the calendar I am testing with is rather empty currently), and I fear that in those cases it will be a lot harder to change anything about it (as basically the whole DOM changes in those scenarios).

@arshaw
Copy link
Member

arshaw commented Mar 21, 2023

In v6.1.5 I've eliminated the fc-selectable className. The problem of reflow while clicking most likely won't be a problem anymore. Could @septatrix and @DevDotJoel please verify? If it helps, I've updated fullcalendar.io's demos page and docs examples to use the latest version

@septatrix
Copy link

While .fc-selectable no longer gets applied it seems that you simply set the CSS style directly which seems to still seems to invalidate the layout and leads to a forced reflow upon the subsequent getBoundingClientRect invocation. I am not sure why this is the case, maybe someone more knowledgeable in the CSS spec or the corresponding browser engines might explain what is going on here.

May I ask why the class/style gets applied and removed upon click/release? It seems like this is only the case for calendars with selectable or editable (at least by checking the different demo calendars). Would it be possible to simply apply the user-select: none style to the whole calendar upon initialization if one of those plugins is active and explicitly remove it on events which have editing disabled? This way it would not have to be set and removed all the time. Maybe someone could explain the purpose of why this is required.

Also I would like to emphasize that for me this is barely noticeable and hundreds of ms as reported by Joel. I mostly see values around 50ms. I mostly participate as it bugs me to see warnings in the dev console and problems like these can often point to underlying issues.

@DevDotJoel
Copy link
Author

While .fc-selectable no longer gets applied it seems that you simply set the CSS style directly which seems to still seems to invalidate the layout and leads to a forced reflow upon the subsequent getBoundingClientRect invocation. I am not sure why this is the case, maybe someone more knowledgeable in the CSS spec or the corresponding browser engines might explain what is going on here.

May I ask why the class/style gets applied and removed upon click/release? It seems like this is only the case for calendars with selectable or editable (at least by checking the different demo calendars). Would it be possible to simply apply the user-select: none style to the whole calendar upon initialization if one of those plugins is active and explicitly remove it on events which have editing disabled? This way it would not have to be set and removed all the time. Maybe someone could explain the purpose of why this is required.

Also I would like to emphasize that for me this is barely noticeable and hundreds of ms as reported by Joel. I mostly see values around 50ms. I mostly participate as it bugs me to see warnings in the dev console and problems like these can often point to underlying issues.

Hey,
im still facing the same issue but the ms is lower.
In my case im using a modal that when u choose a date it opens with input fields using states.
Everytime i delete the input it lags and it shows the reflow message

@arshaw arshaw modified the milestones: v6.1.5, next-release Apr 3, 2023
@arshaw arshaw removed this from the next-release milestone Sep 21, 2023
@DevDotJoel
Copy link
Author

DevDotJoel commented Jan 16, 2024

this problem is still ocurring in these versions:
"@fullcalendar/core": "^6.1.10",
"@fullcalendar/multimonth": "^6.1.10",
"@fullcalendar/react": "^6.1.10",

I also noticed this happens if i only use multiMonthPlugin

is there a fix for this anytime soon?

@DevDotJoel
Copy link
Author

this problem is still ocurring in these versions: "@fullcalendar/core": "^6.1.10", "@fullcalendar/multimonth": "^6.1.10", "@fullcalendar/react": "^6.1.10",

I also noticed this happens if i only use multiMonthPlugin

is there a fix for this anytime soon?

i even opened the example that you guys give here :
https://fullcalendar.io/docs/multimonth-stack-demo

When i open the console i saw the same warning : Forced reflow while executing JavaScript took 90ms.
Just refresh the page over and over and you will see.

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

No branches or pull requests

4 participants