quasar icon indicating copy to clipboard operation
quasar copied to clipboard

Functions inside qscrollarea keeps getting called over and over when scrollbar changes (visibility or movement)

Open arogan opened this issue 2 years ago • 4 comments
trafficstars

What happened?

So I'm noticing odd function call behavior inside a qscrollarea. It seems anytime I mouse over the scroll area the function gets called which is not what happened in v1. Computed behaves as expected. And you don't even have to scroll. Just mouse enter and leave and you'll see the function get hit. How do I revert back to how v1 behaved or is this some odd vue 3 reactivity interaction I'm not understanding. It seems to be tied to scroll bar. If I set it to visible I can mouse over and out all day and it won't trigger b/c the scroll bar isn't fading in and out. Unfortunately, moving the scroll bar will also trigger the function call.

What did you expect to happen?

I expected it to not constantly call functions inside qScrollArea. Quasar v1 does not exhibit this behavior.

Reproduction URL

https://codepen.io/aroganx/pen/gOqWgBY

How to reproduce?

Run the codepen and just mouse over in and out of scroll area. Scrolling in the scroll area will also cause the function to get called repeatedly.

Flavour

Quasar CLI with Webpack (@quasar/cli | @quasar/app-webpack)

Areas

Components (quasar)

Platforms/Browsers

Chrome

Quasar info output

Operating System - Windows_NT(10.0.22621) - win32/x64
NodeJs - 18.17.1

Global packages
  NPM - 9.8.1
  yarn - 1.22.19
  @quasar/cli - 2.2.3
  @quasar/icongenie - Not installed
  cordova - Not installed

Important local packages
  quasar - 2.12.5 -- Build high-performance VueJS user interfaces (SPA, PWA, SSR, Mobile and Desktop) in record time
  @quasar/app-webpack - 3.9.6 -- Quasar Framework App CLI with Webpack
  @quasar/extras - 1.16.6 -- Quasar Framework fonts, icons and animations
  eslint-plugin-quasar - Not installed
  vue - 3.3.4 -- The progressive JavaScript framework for building modern web UI.
  vue-router - 4.2.4
  pinia - Not installed
  vuex - 4.1.0 -- state management for Vue.js
  electron - Not installed
  electron-packager - Not installed
  electron-builder - Not installed
  @babel/core - 7.22.11 -- Babel compiler core.
  webpack - 5.88.2 -- Packs ECMAScript/CommonJs/AMD modules for the browser. Allows you to split your codebase into multiple bundles, which can be loaded on demand. Supports loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.
  webpack-dev-server - 4.11.1 -- Serves a webpack app. Updates the browser on changes.
  workbox-webpack-plugin - Not installed
  register-service-worker - 1.7.2 -- Script for registering service worker, with hooks
  typescript - 4.9.4 -- TypeScript is a language for application scale JavaScript development
  @capacitor/core - Not installed
  @capacitor/cli - Not installed
  @capacitor/android - Not installed
  @capacitor/ios - Not installed

Quasar App Extensions
  @quasar/quasar-app-extension-qcalendar - 4.0.0-beta.16 -- A Quasar App Extension for @quasar/quasar-ui-qcalendar
  @toby.mosque/quasar-app-extension-qdatetimepicker - 2.0.0-rc.3 -- Quasar Date Time Picker Extension
  @quasar/quasar-app-extension-qmarkdown - 2.0.0-beta.10 -- Display inline markdown in your Quasar App

Relevant log output

testComputed: 1
testFx: 16
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua

Additional context

No response

arogan avatar Nov 10 '23 17:11 arogan

If you want to call functions inside the content then put your content in a component, so that vue can optimize the rendering

pdanpdan avatar Nov 14 '23 07:11 pdanpdan

Extracting everything inside q-scroll-area into a separate component does indeed solve the issue. It's still not ideal as I have about 10 places I need to do this and it requires creating a new component, and extracting out logic into a mixin. But it's a path forward.

arogan avatar Nov 21 '23 20:11 arogan

Strangely search didn't pick up this one. Copying the suggestions over from my report:

Since all the computed value updates relate to thumb display, the straight forward solution would be to pull out the thumb rendering logic into pure JS world. I also suspect there is a way to rewrite the render function (rather than relying on the compiler) using vnode creation calls to mark the child nodes (ones inserted via the slot) as isolated from thumb-related nodes.

If you want to call functions inside the content then put your content in a component, so that vue can optimize the rendering

Separate component does not solve the underlying issue: Vue will still invoke the render function of that separate component for every value update inside QScrollArea.

Known workaround

For those that are seeking a workaround, you can use v-memo or v-once on your components rendered within QScrollArea. But make sure you understand how they behave, before using them in production.

thexeos avatar Jan 24 '24 01:01 thexeos

Hi! I am building a component based on QScrollArea and I've encountered the same performance issue highlighted by @thexeos here and in #16813 and #17041. The biggest concern is the re-rendering of every component during scroll. I've tried both v-once and v-memo on content inside the default slot but it keeps getting rerendered. The difference is obviously noticeable if i don't use components at all.

Hope the PR gets merged soon :smile: , for now i'll use a simple scrolling div instead of QScrollArea.

sullyD64 avatar May 02 '24 10:05 sullyD64