quasar icon indicating copy to clipboard operation
quasar copied to clipboard

fix(QScrollArea): prevent content re-rendering on scroll or mousemove (fix #16579)

Open thexeos opened this issue 1 year ago • 3 comments

What kind of change does this PR introduce?

  • [X] Bugfix

Does this PR introduce a breaking change?

  • [X] No

The PR fulfills these requirements:

  • [X] It's submitted to the dev branch (or v[X] branch)
  • [X] When resolving a specific issue, it's referenced in the PR's title (e.g. fix: #xxx[,#xxx], where "xxx" is the issue number)
  • [ ] It's been tested on a Cordova (iOS, Android) app
  • [ ] It's been tested on an Electron app

Other information:

After separating out the thumb rendering logic into a separate component we can isolate the rendering when scroll position is updated or thumb is shown/hidden.

The HTML and CSS output remains unchanged. The functionality remains unchanged. UI tests under ui/dev (ui/playground) all appear to be functioning as expected.

Before the change

chrome_WAZ7HH9OAi

After the change

chrome_NNniFDGsQY

This would fix #16579

thexeos avatar Mar 27 '24 06:03 thexeos

I found an edge case where it still triggers re-rendering. So this requires a little more work.

thexeos avatar Mar 27 '24 07:03 thexeos

UI Tests Results

0 tests   0 :white_check_mark:  0s :stopwatch: 0 suites  0 :zzz: 0 files    0 :x:

Results for commit d9e2a5f0.

:recycle: This comment has been updated with latest results.

github-actions[bot] avatar Mar 27 '24 09:03 github-actions[bot]

It turns out that Vue behaves slightly differently in dev and prod modes. It seems the effect isolation is more strict in dev and so it was not triggering the re-rendering of scrollable content when mainStyle was re-computed after hover ref was updated in @mouseenter and @mouseleave event handlers.

A complete solution is not possible without changing the code flow, as QScrollArea render function ultimately depends on scroll.vertical.thumbHidden and scroll.horizontal.thumbHidden values, which in turn change when showing/hiding the scrollbars in "default" visible mode.

Despite not being a complete solution, this change achieves:

  • No more pointless re-rendering of content when scrolling [had the largest affect on performance]
  • No more pointless re-rendering of content when showing/hiding the scrollbars, as long as contentStyle or contentActiveStyle props of QScrollArea were not set

This PR should be ready for merging.

thexeos avatar Mar 27 '24 22:03 thexeos

Hi,

Huge thanks for contributing! There were merge errors so written this myself using your great sub-component idea. Perf improvement will be available in Quasar v2.17.0

rstoenescu avatar Sep 11 '24 12:09 rstoenescu

Again, excellent work!

rstoenescu avatar Sep 11 '24 12:09 rstoenescu