quasarframework / quasar

Quasar Framework - Build high-performance VueJS user interfaces in record time
https://quasar.dev
MIT License
25.87k stars 3.51k forks source link

Performance issues while rendering a lot of q-input components #12369

Open Codebreaker101 opened 2 years ago

Codebreaker101 commented 2 years ago

What happened?

When having a lot of q-input components on a page it takes a while to render, especially if you have label and hint enabled.

Here are some screenshots from vue dev tools: Screenshot from 2022-02-06 15-58-29 Screenshot from 2022-02-06 15-59-04

Is this how it is supposed to be? If yes, what can one do to improve performance while rendering lots of inputs?

What did you expect to happen?

I expected for it not to be that slow.

Reproduction URL

https://codesandbox.io/s/musing-glade-nlkdp?file=/src/pages/Index.vue

How to reproduce?

  1. Go to provided link
  2. Click on TRIGGER
  3. Depending on you machine you can increase the number of components rendered

Flavour

Quasar CLI (@quasar/cli | @quasar/app)

Areas

Components (quasar)

Platforms/Browsers

Firefox, Chrome

Quasar info output

Operating System - Linux(5.10.93-1-MANJARO) - linux/x64
NodeJs - 14.17.6

Global packages
  NPM - 6.14.15
  yarn - 1.22.17
  @quasar/cli - 1.2.1
  @quasar/icongenie - 2.4.0
  cordova - Not installed

Important local packages
  quasar - 2.5.1 -- Build high-performance VueJS user interfaces (SPA, PWA, SSR, Mobile and Desktop) in record time
  @quasar/app - 3.3.2 -- Quasar Framework local CLI
  @quasar/extras - 1.12.4 -- Quasar Framework fonts, icons and animations
  eslint-plugin-quasar - Not installed
  vue - 3.2.29 -- The progressive JavaScript framework for building modern web UI.
  vue-router - 4.0.12
  vuex - 4.0.2 -- state management for Vue.js
  electron - 17.0.0 -- Build cross platform desktop apps with JavaScript, HTML, and CSS
  electron-packager - 15.4.0 -- Customize and package your Electron app with OS-specific bundles (.app, .exe, etc.) via JS or CLI
  electron-builder - Not installed
  @babel/core - 7.16.12 -- Babel compiler core.
  webpack - 5.68.0 -- Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.
  webpack-dev-server - 4.7.3 -- 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.5.5 -- TypeScript is a language for application scale JavaScript development
  @capacitor/core - 3.2.4 -- Capacitor: Cross-platform apps with JavaScript and the web
  @capacitor/cli - 3.2.4 -- Capacitor: Cross-platform apps with JavaScript and the web
  @capacitor/android - 3.2.4 -- Capacitor: Cross-platform apps with JavaScript and the web
  @capacitor/ios - Not installed

Quasar App Extensions
  *None installed*

Relevant log output

No response

Additional context

No response

cohlar commented 1 year ago

+1 I use Quasar with Vite, I also have pages with a lot of inputs and it makes my app ridiculously slow. Would love some performance tips.

khanhnm222 commented 1 year ago

I have used both Vite and Webpack build modes for my project, which renders a lot of q-table/q-btn,... components on one page, and my app loads very slowly. Hopefully, there will be a solution to improve performance.

azizaza commented 1 year ago

same here! any solution? i'm using quasar with vite

AlexDaniel commented 10 months ago

Ugh, the only solution I know (and use) is to create a progressiveLoading ref which is just a counter.

Then you do:

function bumpProgressiveLoading() {
  progressiveLoading.value += 1;
  const maxLength = myArrayWithElements.length;
  if (progressiveLoading.value < maxLength - 1) {
    nextTick(() => {
      setTimeout(bumpProgressiveLoading, 1);
    });
  }
}
onMounted(bumpProgressiveLoading);

Then, in your template, add a v-if/v-else based on the index. Render a q-skeleton if the index didn't reach the element's index. q-skeletons are very fast to render compared to q-inputs.

This means that as the user navigates to your page, they will just see a list of skeletons first, and that list will progressively turn into something useful. Pay attention to rerenders and ensure that your q-inputs don't get rerendered every time (you will probably need to create components for each item in the array even if you don't want to).

Basically, it's manual time slicing.

AlexDaniel commented 10 months ago

Actually, this makes me think that Vue should provide a helper for time-slicing… This way, you could batch many updates into a single render cycle while maintaining responsiveness.

That being said, still, why the hell are q-inputs so slow to render?