mirror of https://github.com/vuejs/core.git
chore: benchmark reference
This commit is contained in:
parent
c317a06043
commit
6df8c01cd0
|
@ -11,3 +11,4 @@ TODOs.md
|
||||||
dts-build/packages
|
dts-build/packages
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
*.tgz
|
*.tgz
|
||||||
|
packages-private/benchmark/reference
|
||||||
|
|
|
@ -1,22 +1,10 @@
|
||||||
<script setup lang="ts">
|
<script setup>
|
||||||
import {
|
import { shallowRef, triggerRef } from 'vue'
|
||||||
shallowRef,
|
|
||||||
triggerRef,
|
|
||||||
type ShallowRef,
|
|
||||||
// createSelector,
|
|
||||||
} from 'vue'
|
|
||||||
import { buildData } from './data'
|
import { buildData } from './data'
|
||||||
import { defer, wrap } from './profiling'
|
import { defer, wrap } from './profiling'
|
||||||
|
|
||||||
const isVapor = !!import.meta.env.IS_VAPOR
|
const selected = shallowRef()
|
||||||
|
const rows = shallowRef([])
|
||||||
const selected = shallowRef<number>()
|
|
||||||
const rows = shallowRef<
|
|
||||||
{
|
|
||||||
id: number
|
|
||||||
label: ShallowRef<string>
|
|
||||||
}[]
|
|
||||||
>([])
|
|
||||||
|
|
||||||
// Bench Add: https://jsbench.me/45lzxprzmu/1
|
// Bench Add: https://jsbench.me/45lzxprzmu/1
|
||||||
const add = wrap('add', () => {
|
const add = wrap('add', () => {
|
||||||
|
@ -24,7 +12,7 @@ const add = wrap('add', () => {
|
||||||
triggerRef(rows)
|
triggerRef(rows)
|
||||||
})
|
})
|
||||||
|
|
||||||
const remove = wrap('remove', (id: number) => {
|
const remove = wrap('remove', id => {
|
||||||
rows.value.splice(
|
rows.value.splice(
|
||||||
rows.value.findIndex(d => d.id === id),
|
rows.value.findIndex(d => d.id === id),
|
||||||
1,
|
1,
|
||||||
|
@ -32,7 +20,7 @@ const remove = wrap('remove', (id: number) => {
|
||||||
triggerRef(rows)
|
triggerRef(rows)
|
||||||
})
|
})
|
||||||
|
|
||||||
const select = wrap('select', (id: number) => {
|
const select = wrap('select', id => {
|
||||||
selected.value = id
|
selected.value = id
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -77,13 +65,11 @@ async function bench() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// const isSelected = createSelector(selected)
|
|
||||||
|
|
||||||
const globalThis = window
|
const globalThis = window
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<h1>Vue.js ({{ isVapor ? 'Vapor' : 'Virtual DOM' }}) Benchmark</h1>
|
<h1>Vue.js (VDOM) Benchmark</h1>
|
||||||
|
|
||||||
<div style="display: flex; gap: 4px; margin-bottom: 4px">
|
<div style="display: flex; gap: 4px; margin-bottom: 4px">
|
||||||
<label>
|
<label>
|
||||||
|
@ -110,31 +96,37 @@ const globalThis = window
|
||||||
>
|
>
|
||||||
<button @click="bench">Benchmark mounting</button>
|
<button @click="bench">Benchmark mounting</button>
|
||||||
<button id="run" @click="run">Create 1,000 rows</button>
|
<button id="run" @click="run">Create 1,000 rows</button>
|
||||||
<button id="runLots" @click="runLots">Create 10,000 rows</button>
|
<button id="runlots" @click="runLots">Create 10,000 rows</button>
|
||||||
<button id="add" @click="add">Append 1,000 rows</button>
|
<button id="add" @click="add">Append 1,000 rows</button>
|
||||||
<button id="update" @click="update">Update every 10th row</button>
|
<button id="update" @click="update">Update every 10th row</button>
|
||||||
<button id="clear" @click="clear">Clear</button>
|
<button id="clear" @click="clear">Clear</button>
|
||||||
<button id="swaprows" @click="swapRows">Swap Rows</button>
|
<button id="swaprows" @click="swapRows">Swap Rows</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="time"></div>
|
<div id="time"></div>
|
||||||
<table>
|
<table class="table table-hover table-striped test-data">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr
|
<tr
|
||||||
v-for="row of rows"
|
v-for="row of rows"
|
||||||
:key="row.id"
|
:key="row.id"
|
||||||
:class="{ danger: selected === row.id }"
|
:class="selected === row.id ? 'danger' : ''"
|
||||||
>
|
>
|
||||||
<td>{{ row.id }}</td>
|
<td class="col-md-1">{{ row.id }}</td>
|
||||||
<td>
|
<td class="col-md-4">
|
||||||
<a @click="select(row.id)">{{ row.label.value }}</a>
|
<a @click="select(row.id)">{{ row.label.value }}</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td class="col-md-1">
|
||||||
<button @click="remove(row.id)">x</button>
|
<a @click="remove(row.id)">
|
||||||
|
<span class="glyphicon glyphicon-remove" aria-hidden="true">x</span>
|
||||||
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td class="col-md-6"></td>
|
<td class="col-md-6"></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<span
|
||||||
|
class="preloadicon glyphicon glyphicon-remove"
|
||||||
|
aria-hidden="true"
|
||||||
|
></span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -1,22 +1,10 @@
|
||||||
<script setup vapor lang="ts">
|
<script setup vapor>
|
||||||
import {
|
import { shallowRef, triggerRef } from 'vue'
|
||||||
shallowRef,
|
|
||||||
triggerRef,
|
|
||||||
type ShallowRef,
|
|
||||||
// createSelector,
|
|
||||||
} from 'vue'
|
|
||||||
import { buildData } from './data'
|
import { buildData } from './data'
|
||||||
import { defer, wrap } from './profiling'
|
import { defer, wrap } from './profiling'
|
||||||
|
|
||||||
const isVapor = !!import.meta.env.IS_VAPOR
|
const selected = shallowRef()
|
||||||
|
const rows = shallowRef([])
|
||||||
const selected = shallowRef<number>()
|
|
||||||
const rows = shallowRef<
|
|
||||||
{
|
|
||||||
id: number
|
|
||||||
label: ShallowRef<string>
|
|
||||||
}[]
|
|
||||||
>([])
|
|
||||||
|
|
||||||
// Bench Add: https://jsbench.me/45lzxprzmu/1
|
// Bench Add: https://jsbench.me/45lzxprzmu/1
|
||||||
const add = wrap('add', () => {
|
const add = wrap('add', () => {
|
||||||
|
@ -24,7 +12,7 @@ const add = wrap('add', () => {
|
||||||
triggerRef(rows)
|
triggerRef(rows)
|
||||||
})
|
})
|
||||||
|
|
||||||
const remove = wrap('remove', (id: number) => {
|
const remove = wrap('remove', id => {
|
||||||
rows.value.splice(
|
rows.value.splice(
|
||||||
rows.value.findIndex(d => d.id === id),
|
rows.value.findIndex(d => d.id === id),
|
||||||
1,
|
1,
|
||||||
|
@ -32,7 +20,7 @@ const remove = wrap('remove', (id: number) => {
|
||||||
triggerRef(rows)
|
triggerRef(rows)
|
||||||
})
|
})
|
||||||
|
|
||||||
const select = wrap('select', (id: number) => {
|
const select = wrap('select', id => {
|
||||||
selected.value = id
|
selected.value = id
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -77,13 +65,11 @@ async function bench() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// const isSelected = createSelector(selected)
|
|
||||||
|
|
||||||
const globalThis = window
|
const globalThis = window
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<h1>Vue.js ({{ isVapor ? 'Vapor' : 'Virtual DOM' }}) Benchmark</h1>
|
<h1>Vue.js (Vapor) Benchmark</h1>
|
||||||
|
|
||||||
<div style="display: flex; gap: 4px; margin-bottom: 4px">
|
<div style="display: flex; gap: 4px; margin-bottom: 4px">
|
||||||
<label>
|
<label>
|
||||||
|
@ -110,31 +96,37 @@ const globalThis = window
|
||||||
>
|
>
|
||||||
<button @click="bench">Benchmark mounting</button>
|
<button @click="bench">Benchmark mounting</button>
|
||||||
<button id="run" @click="run">Create 1,000 rows</button>
|
<button id="run" @click="run">Create 1,000 rows</button>
|
||||||
<button id="runLots" @click="runLots">Create 10,000 rows</button>
|
<button id="runlots" @click="runLots">Create 10,000 rows</button>
|
||||||
<button id="add" @click="add">Append 1,000 rows</button>
|
<button id="add" @click="add">Append 1,000 rows</button>
|
||||||
<button id="update" @click="update">Update every 10th row</button>
|
<button id="update" @click="update">Update every 10th row</button>
|
||||||
<button id="clear" @click="clear">Clear</button>
|
<button id="clear" @click="clear">Clear</button>
|
||||||
<button id="swaprows" @click="swapRows">Swap Rows</button>
|
<button id="swaprows" @click="swapRows">Swap Rows</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="time"></div>
|
<div id="time"></div>
|
||||||
<table>
|
<table class="table table-hover table-striped test-data">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr
|
<tr
|
||||||
v-for="row of rows"
|
v-for="row of rows"
|
||||||
:key="row.id"
|
:key="row.id"
|
||||||
:class="{ danger: selected === row.id }"
|
:class="selected === row.id ? 'danger' : ''"
|
||||||
>
|
>
|
||||||
<td>{{ row.id }}</td>
|
<td class="col-md-1">{{ row.id }}</td>
|
||||||
<td>
|
<td class="col-md-4">
|
||||||
<a @click="select(row.id)">{{ row.label.value }}</a>
|
<a @click="select(row.id)">{{ row.label.value }}</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td class="col-md-1">
|
||||||
<button @click="remove(row.id)">x</button>
|
<a @click="remove(row.id)">
|
||||||
|
<span class="glyphicon glyphicon-remove" aria-hidden="true">x</span>
|
||||||
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td class="col-md-6"></td>
|
<td class="col-md-6"></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<span
|
||||||
|
class="preloadicon glyphicon glyphicon-remove"
|
||||||
|
aria-hidden="true"
|
||||||
|
></span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -24,7 +24,8 @@ const {
|
||||||
count: countStr,
|
count: countStr,
|
||||||
warmupCount: warmupCountStr,
|
warmupCount: warmupCountStr,
|
||||||
noHeadless,
|
noHeadless,
|
||||||
devBuild,
|
noMinify,
|
||||||
|
reference,
|
||||||
},
|
},
|
||||||
} = parseArgs({
|
} = parseArgs({
|
||||||
allowNegative: true,
|
allowNegative: true,
|
||||||
|
@ -67,9 +68,12 @@ const {
|
||||||
noHeadless: {
|
noHeadless: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
},
|
},
|
||||||
devBuild: {
|
noMinify: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
short: 'd',
|
},
|
||||||
|
reference: {
|
||||||
|
type: 'boolean',
|
||||||
|
short: 'r',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -79,10 +83,10 @@ const count = +(/** @type {string}*/ (countStr))
|
||||||
const warmupCount = +(/** @type {string}*/ (warmupCountStr))
|
const warmupCount = +(/** @type {string}*/ (warmupCountStr))
|
||||||
const sha = await getSha(true)
|
const sha = await getSha(true)
|
||||||
|
|
||||||
if (!skipLib) {
|
if (!skipLib && !reference) {
|
||||||
await buildLib()
|
await buildLib()
|
||||||
}
|
}
|
||||||
if (!skipApp) {
|
if (!skipApp && !reference) {
|
||||||
await rm('client/dist', { recursive: true }).catch(() => {})
|
await rm('client/dist', { recursive: true }).catch(() => {})
|
||||||
vdom && (await buildApp(false))
|
vdom && (await buildApp(false))
|
||||||
!noVapor && (await buildApp(true))
|
!noVapor && (await buildApp(true))
|
||||||
|
@ -103,13 +107,10 @@ async function buildLib() {
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
env: { ...process.env, BENCHMARK: 'true' },
|
env: { ...process.env, BENCHMARK: 'true' },
|
||||||
}
|
}
|
||||||
const buildOptions = devBuild ? '-df' : '-pf'
|
|
||||||
const [{ ok }, { ok: ok2 }, { ok: ok3 }] = await Promise.all([
|
const [{ ok }, { ok: ok2 }, { ok: ok3 }] = await Promise.all([
|
||||||
exec(
|
exec(
|
||||||
'pnpm',
|
'pnpm',
|
||||||
`run --silent build shared compiler-core compiler-dom ${buildOptions} cjs`.split(
|
`run --silent build shared compiler-core compiler-dom -pf cjs`.split(' '),
|
||||||
' ',
|
|
||||||
),
|
|
||||||
options,
|
options,
|
||||||
),
|
),
|
||||||
exec(
|
exec(
|
||||||
|
@ -121,7 +122,9 @@ async function buildLib() {
|
||||||
),
|
),
|
||||||
exec(
|
exec(
|
||||||
'pnpm',
|
'pnpm',
|
||||||
`run --silent build vue ${buildOptions} esm-browser-vapor`.split(' '),
|
`run --silent build shared reactivity runtime-core runtime-dom runtime-vapor vue -f esm-bundler+esm-bundler-runtime`.split(
|
||||||
|
' ',
|
||||||
|
),
|
||||||
options,
|
options,
|
||||||
),
|
),
|
||||||
])
|
])
|
||||||
|
@ -138,15 +141,15 @@ async function buildApp(isVapor) {
|
||||||
colors.blue(`\nBuilding ${isVapor ? 'Vapor' : 'Virtual DOM'} app...\n`),
|
colors.blue(`\nBuilding ${isVapor ? 'Vapor' : 'Virtual DOM'} app...\n`),
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!devBuild) process.env.NODE_ENV = 'production'
|
process.env.NODE_ENV = 'production'
|
||||||
|
|
||||||
const CompilerSFC = await import(
|
const CompilerSFC = await import(
|
||||||
'../../packages/compiler-sfc/dist/compiler-sfc.cjs.js'
|
'../../packages/compiler-sfc/dist/compiler-sfc.cjs.js'
|
||||||
)
|
)
|
||||||
const prodSuffix = devBuild ? '.js' : '.prod.js'
|
|
||||||
|
|
||||||
const runtimePath = path.resolve(
|
const runtimePath = path.resolve(
|
||||||
import.meta.dirname,
|
import.meta.dirname,
|
||||||
'../../packages/vue/dist/vue.runtime-with-vapor.esm-browser' + prodSuffix,
|
'../../packages/vue/dist/vue.runtime.esm-bundler.js',
|
||||||
)
|
)
|
||||||
|
|
||||||
const mode = isVapor ? 'vapor' : 'vdom'
|
const mode = isVapor ? 'vapor' : 'vdom'
|
||||||
|
@ -157,7 +160,7 @@ async function buildApp(isVapor) {
|
||||||
'import.meta.env.IS_VAPOR': String(isVapor),
|
'import.meta.env.IS_VAPOR': String(isVapor),
|
||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
minify: !devBuild,
|
minify: !noMinify,
|
||||||
outDir: path.resolve('./client/dist', mode),
|
outDir: path.resolve('./client/dist', mode),
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
onwarn(log, handler) {
|
onwarn(log, handler) {
|
||||||
|
@ -181,8 +184,10 @@ async function buildApp(isVapor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function startServer() {
|
function startServer() {
|
||||||
const server = connect().use(sirv('./client/dist')).listen(port)
|
const server = connect()
|
||||||
printPort(port)
|
.use(sirv(reference ? './reference' : './client/dist', { dev: true }))
|
||||||
|
.listen(port)
|
||||||
|
printPort()
|
||||||
process.on('SIGTERM', () => server.close())
|
process.on('SIGTERM', () => server.close())
|
||||||
return server
|
return server
|
||||||
}
|
}
|
||||||
|
@ -203,18 +208,25 @@ async function benchmark() {
|
||||||
await browser.close()
|
await browser.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {boolean} isVapor
|
||||||
|
*/
|
||||||
|
function getURL(isVapor) {
|
||||||
|
return `http://localhost:${port}/${reference ? '' : isVapor ? 'vapor' : 'vdom'}/`
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {import('puppeteer').Browser} browser
|
* @param {import('puppeteer').Browser} browser
|
||||||
* @param {boolean} isVapor
|
* @param {boolean} isVapor
|
||||||
*/
|
*/
|
||||||
async function doBench(browser, isVapor) {
|
async function doBench(browser, isVapor) {
|
||||||
const mode = isVapor ? 'vapor' : 'vdom'
|
const mode = reference ? `reference` : isVapor ? 'vapor' : 'vdom'
|
||||||
console.info('\n\nmode:', mode)
|
console.info('\n\nmode:', mode)
|
||||||
|
|
||||||
const page = await browser.newPage()
|
const page = await browser.newPage()
|
||||||
page.emulateCPUThrottling(4)
|
page.emulateCPUThrottling(4)
|
||||||
await page.goto(`http://localhost:${port}/${mode}`, {
|
await page.goto(getURL(isVapor), {
|
||||||
waitUntil: 'networkidle0',
|
waitUntil: 'networkidle0',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -256,7 +268,7 @@ async function doBench(browser, isVapor) {
|
||||||
await clickButton('add') // append rows to large table
|
await clickButton('add') // append rows to large table
|
||||||
|
|
||||||
await withoutRecord(() => clickButton('clear'))
|
await withoutRecord(() => clickButton('clear'))
|
||||||
await clickButton('runLots') // create many rows
|
await clickButton('runlots') // create many rows
|
||||||
await withoutRecord(() => clickButton('clear'))
|
await withoutRecord(() => clickButton('clear'))
|
||||||
|
|
||||||
// TODO replace all rows
|
// TODO replace all rows
|
||||||
|
@ -293,7 +305,7 @@ async function doBench(browser, isVapor) {
|
||||||
for (let i = 1; i <= 10; i++) {
|
for (let i = 1; i <= 10; i++) {
|
||||||
await page.click(`tbody > tr:nth-child(2) > td:nth-child(2) > a`)
|
await page.click(`tbody > tr:nth-child(2) > td:nth-child(2) > a`)
|
||||||
await page.waitForSelector(`tbody > tr:nth-child(2).danger`)
|
await page.waitForSelector(`tbody > tr:nth-child(2).danger`)
|
||||||
await page.click(`tbody > tr:nth-child(2) > td:nth-child(3) > button`)
|
await page.click(`tbody > tr:nth-child(2) > td:nth-child(3) > a`)
|
||||||
await wait()
|
await wait()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -372,13 +384,10 @@ function round(n) {
|
||||||
return +n.toFixed(2)
|
return +n.toFixed(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @param {number} port */
|
function printPort() {
|
||||||
function printPort(port) {
|
|
||||||
const vaporLink = !noVapor
|
const vaporLink = !noVapor
|
||||||
? `\nVapor: ${colors.blue(`http://localhost:${port}/vapor`)}`
|
? `\n${reference ? `Reference` : `Vapor`}: ${colors.blue(getURL(true))}`
|
||||||
: ''
|
|
||||||
const vdomLink = vdom
|
|
||||||
? `\nvDom: ${colors.blue(`http://localhost:${port}/vdom`)}`
|
|
||||||
: ''
|
: ''
|
||||||
|
const vdomLink = vdom ? `\nvDom: ${colors.blue(getURL(false))}` : ''
|
||||||
console.info(`\n\nServer started at`, vaporLink, vdomLink)
|
console.info(`\n\nServer started at`, vaporLink, vdomLink)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "pnpm start --devBuild --skipBench --vdom",
|
"dev": "pnpm start --noMinify --skipBench --vdom",
|
||||||
"start": "node index.js"
|
"start": "node index.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
Loading…
Reference in New Issue