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
Performance of templates vs render functions #1936
Comments
Warning: Just my opinion I'd expect that render functions are generally faster in more scenarios since everything is manually created with no overhead, whereas, with templates, they need to be compiled and won't be as optimised as render functions in some cases, as additional overhead may be included. But Vue 3's template compiler should be getting tonnes of new optimisations. I don't think it matters much in any real-life cases, so just use what's easier to maintain and develop. |
Thanks for the response @DominusVilicus. I have been doing some preliminary performance testing of templates vs JSX, with Vue v2.5, and so far the results generally support your conclusion that it may not matter much in real-life scenarios. I suspect that Vue 3's optimizations may make templates more performant for larger, complex applications, but that's just a guess. |
As long as we talk ab out a template and a render function doing the same thing, the opposite is the case, pretty much.
It may of course be the case that in specific situations, you can write a more perfomant render function because of the dynamic nature of JSX. But for the bulk of the usual markup that you have to create, the render functions from .vue files will be faster than their hand-written counterparts. How much faster? To be honest I personally don't know. |
Awesome, thanks @LinusBorg! |
@betweenbrain As your issue seems to have been clarified, I'm closing this. Feel free to open another if you think it's necessary. |
I know this is closed but Vue 3.x is in a more stable spot now so I'm curious if any opinions have changed or if there's any new information regarding performance between the two options. I've been building a small component library to test out / learn Vue 3.x and would love to hear thoughts on just how optimized the templates can be vs manually writings render functions. Let's take a simple example (hopefully these are identical, I haven't actually tested them): Render function approach import { defineComponent, h } from "vue"
export default defineComponent({
name: "MyComponent",
props: {
someProp: {
type: Boolean
}
},
render() {
const { someProp } = this.$props
const { default: defaultSlot, slotOne, slotTwo } = this.$slots
const child = h("span", { class: "inner" }, defaultSlot)
return h(
"div",
{
class: {
"static-class": true,
"some-class": someProp
}
},
[slotOne && slotOne(), child, slotTwo && slotTwo()]
)
}
}) Template approach <template>
<div class="static-class" :class="{ 'some-class': someProp }">
<slot name="slotOne" />
<span class="inner">
<slot name="default" />
</span>
<slot name="slotTwo" />
</div>
</template>
<script>
import { defineComponent } from "vue"
export default defineComponent({
name: "MyComponent",
props: {
someProp: {
type: Boolean
}
}
})
</script> This example may not be great... I'm just trying to determine if the improvements in the static analysis in Vue 3.x have improved the generated render functions beyond what someone could write manually, and / or if the convenience of using pure JS to handle complex user input is the only benefit to manually writing them. I'm seeing in the Functional Components RFC that is pretty much pointless to write those now other than for simplicity... I wonder if this is related or can be used to extrapolate that templates are just the 💣 now? Here's an actual component if it helps
import { defineComponent, h, mergeProps } from "vue"
import { RouterLink } from "vue-router"
import { validatePropFromEnum } from "../../utils"
import { Colors, Sizes } from "../types"
import "./styles.scss"
enum ButtonTypes {
button = "button",
submit = "submit",
reset = "reset"
}
type Elevations = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
export namespace OnyxButton {
export type Props = {
disabled?: boolean
fill?: boolean
flat?: boolean
fab?: boolean
type?: keyof typeof ButtonTypes
color?: keyof typeof Colors
size?: keyof typeof Sizes
elevation?: Elevations
href?: string
to?: string
}
}
export default defineComponent({
name: "OnyxBtn",
props: {
fill: {
type: Boolean
},
type: {
type: String,
default: ButtonTypes.button,
validator: (prop: keyof typeof ButtonTypes): boolean =>
validatePropFromEnum(prop, ButtonTypes)
},
disabled: {
type: Boolean
},
fab: {
type: Boolean
},
flat: {
type: Boolean
},
color: {
type: String,
default: Colors.default,
validator: (prop: keyof typeof Colors): boolean =>
validatePropFromEnum(prop, Colors)
},
size: {
type: String,
default: Sizes.medium,
validator: (prop: keyof typeof Sizes): boolean =>
validatePropFromEnum(prop, Sizes)
},
elevation: {
type: Number,
default: 0,
/** @todo Define a max elevation */
validator: (prop: Elevations): boolean => prop <= 7 && prop >= 0
},
href: {
type: String
},
to: {
type: String
}
},
render() {
const {
href,
to,
fill,
flat,
fab,
type,
color,
size,
elevation
}: Readonly<OnyxButton.Props> = this.$props
let component: any = "button"
if (href && to) {
console.error(`"href" and "to" props shouldn't be used together.`)
} else if (href) {
component = "a"
} else if (to) {
component = RouterLink
}
if (fab && fill) {
console.error(`"fill" and "fab" props shouldn't be used together`)
}
return h(
component,
mergeProps(this.$props, {
class: {
button: true,
[`button-${size}`]: true,
[`button-${color}`]: true,
[`button-elevation-${elevation}`]: true,
fill: fill && !fab,
fab,
flat
},
type
}),
this.$slots
)
}
}) |
My repo include some test cases about renderFn, template, computedVDOM stuff (all in vue 3). I think using vue template is the best approach cause it reduce _createVNode function call a lot. |
Render Functions & JSX: Basics states that templates are recommended in the majority of cases. I understand that templates are compiled to render functions. Evan’s keynote at VueConf Toronto 2018 got me wondering about the performance of using templates vs render functions and even to JSX. More specifically, Even discussed how the Vue template compiler optimizes code, and that in Vue 3.0, it should further be optimized by the compiler. It would be great to document if there are any performance gains of using over.
The text was updated successfully, but these errors were encountered: