eslint-plugin-vue-perf
v0.1.0
Published
ESLint rules that catch Vue patterns which cause wasted component re-renders. Measured, not guessed.
Downloads
23
Maintainers
Readme
eslint-plugin-vue-perf
ESLint rules that catch Vue patterns which cause wasted component re-renders. Measured, not guessed. See the write-up and the data behind it: Which Vue props actually waste a re-render?
What it catches
When you build a new object or array from reactive data in the template and pass it to a child component, it gets a fresh identity every render, so the child re-renders even when its data hasn't changed:
<UserCard :profile="{ name: user.name }" /> <!-- warns -->
<TodoList :items="todos.filter(t => !t.done)" /> <!-- warns -->It leaves the safe stuff alone. Static literals get hoisted by the compiler, and inline props on native elements are a different, cheap story:
<UserCard :profile="profile" /> <!-- ok: stable ref/computed -->
<Flags :config="{ a: 1 }" /> <!-- ok: static literal, hoisted -->
<div :style="{ color: c }" /> <!-- ok: native element -->
<Child @click="() => save()" /> <!-- ok: handlers are cached -->The fix is to give the value a stable identity, usually a computed:
const profile = computed(() => ({ name: user.name }))
const activeTodos = computed(() => todos.filter((t) => !t.done))Install
npm i -D eslint-plugin-vue-perfUsage (flat config, ESLint 9+)
// eslint.config.js
import vueParser from "vue-eslint-parser"
import vuePerf from "eslint-plugin-vue-perf"
export default [
{
files: ["**/*.vue"],
languageOptions: { parser: vueParser },
plugins: { "vue-perf": vuePerf },
rules: {
"vue-perf/no-unstable-component-props": "warn",
},
},
]Or use the bundled config:
import vuePerf from "eslint-plugin-vue-perf"
export default [vuePerf.configs.recommended]Usage (legacy .eslintrc)
{
"plugins": ["vue-perf"],
"parser": "vue-eslint-parser",
"rules": {
"vue-perf/no-unstable-component-props": "warn"
}
}Rules
| rule | what it flags |
| --- | --- |
| no-unstable-component-props | inline objects / arrays / array-method calls built from reactive data and passed to a component |
When to care
This only matters when the child is heavy or rendered many times (a big list
row, a chart, a card you render 50 times). For a small leaf component the extra
render is a rounding error. The rule defaults to warn for that reason, tune it
to your app.
Credit
By Sam Kavanagh. The patterns it flags come from a measured investigation (data + harness), built with Claude Code.
License
MIT
