Skip to content

Conversation

@Glandos
Copy link

@Glandos Glandos commented Jun 8, 2021

What kind of change does this PR introduce? (check at least one)

  • Bugfix
  • Feature
  • Code style update
  • Refactor
  • Build-related changes
  • Other, please describe: Performance

Does this PR introduce a breaking change? (check one)

  • Yes
  • No

If yes, please describe the impact and migration path for existing applications:

The PR fulfills these requirements:

If adding a new feature, the PR's description includes:

  • A convincing reason for adding this feature (to avoid wasting your time, it's best to open a suggestion issue first and wait for approval before working on it)

Other information:

getType is called a lot, and it just run the same regexp over and over on the same base types.
A cache increase its own efficiency by more than 80% for basic types.
On a real world application with a lot of components, getType was profiled for 8% of call duration before this patch, and about 0.5% after.
The impact is more limited for smaller applications.

Light application

Before:
Profile light without cache
After:
Profile light with cache

Heavy application

Before:
Profile heavy without cache
After:
Profile heavy with cache

Test was done on a laptop with Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz, Chromium Version 90.0.4430.212

@posva
Copy link
Member

posva commented Jun 8, 2021

Thank you. Do you have a runnable sample in a single index.html file to check the perf gain?

@Glandos
Copy link
Author

Glandos commented Jun 8, 2021

No :( I performed the test on my company's application that I'm currently developing. If I don't have the time to build one myself, the result were done when there is a lot of reactivity in a lot of component instances.

@myfreeer
Copy link

Quick sample here:
image
image

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue 2 demo for https://github.com/vuejs/vue/pull/12123</title> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> </head> <body> <button id="mount" type="button">click to mount</button> <div id="app"></div> <script> var exampleLength = 50000; var app = new Vue(({ render(h) { var children = [] for (let i = 0, len = this.arr.length; i < len; i++) { children.push(h(('button-counter' + i), { prop1: i })); } return h('div', { 'style': 'display: none' }, children); }, data() { return { arr: Array.from({length: exampleLength}, (_, i) => i) } } })); { for (let i = 0; i < exampleLength; i++) { Vue.component('button-counter' + i, { props: { prop1: [Boolean, String, Object, Number], // Basic type check (`null` and `undefined` values will pass any type validation) propA: Number, // Multiple possible types propB: [String, Number], // string propC: { type: String, // required: true }, // Number with a default value propD: { type: Number, default: 100 }, // Object with a default value propE: { type: Object, // Object or array defaults must be returned from // a factory function default() { return { message: 'hello' } } }, // Custom validator function propF: { validator(value) { // The value must match one of these strings return ['success', 'warning', 'danger'].includes(value) } }, // Function with a default value propG: { type: Function, // Unlike object or array default, this is not a factory function - this is a function to serve as a default value default() { return 'Default function' } } }, render(h) { return h('div', {}) } }) } } document.getElementById('mount').onclick = () => { if (console.timeStamp) console.timeStamp('mount-start'); var time = Date.now(); app.$mount(document.getElementById('app')) console.log('mount', Date.now() - time) if (console.timeStamp) console.timeStamp('mount-end'); } </script> </body> </html>
@Glandos
Copy link
Author

Glandos commented Dec 7, 2021

I am really new to Vue internals, but I'm wondering if the test-e2e failed because of this patch, or some other external cause. Is it useful to re-run them?

@leadingGo
Copy link

leadingGo commented Dec 7, 2021 via email

@ycw984512
Copy link

ycw984512 commented Dec 7, 2021 via email

@FFWLei
Copy link

FFWLei commented Dec 7, 2021 via email

@Glandos
Copy link
Author

Glandos commented Sep 20, 2022

Is there anything I can do to finalize this work? Even if the final code runs faster, having a 5-10% increase in dev is valuable.
And it seems it can also be ported to Vue 3 in https://github.com/vuejs/vue/blob/main/src/core/util/props.ts#L193

@myfreeer
Copy link

The getType function for vue 3 is here:

https://github.com/vuejs/core/blob/96eb7452548293c343613ab778248a5da9619f45/packages/runtime-core/src/componentProps.ts#L559-L562

And the code at https://github.com/vuejs/vue/blob/main/src/core/util/props.ts#L193 is currently for vue 2.7.x

@Havunen
Copy link

Havunen commented Mar 6, 2023

@Glandos Please get latest changes from the upstream and that should fix the error

getType is called a lot, and it just run the same regexp over and over on the same base types. A cache increase its own efficiency by more than 80% for basic types. On a real world application with a lot of components, getType was profiled for 8% of call duration before this patch, and about 0.5% after. The impact is more limited for smaller applications.
@Glandos Glandos force-pushed the performance_get_type branch from 4b2a5d9 to f06f110 Compare March 6, 2023 13:35
@Glandos
Copy link
Author

Glandos commented Mar 6, 2023

@Havunen I've rebased against dev branch, as this PR was opened against it, but I see that the most active branch is now main. Should I try to reopen this against main instead?

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

Labels

None yet

7 participants