Vue event bad performance
I have big performance problem with my vue app.
I have table with ~50 rows its has a slot-scope="scope" attribute
When i try to make some event on selected row for example open Element UI select element whole page freezes for a long time.
I checked in chrome webdev performance tab and it look like site is doing much function calls:
browser performance test
Its working fast if i have only few rows in a table.
Here is my component code:
<template>
<div>
<el-card>
<div slot="header">
Quotes
<el-button
type="primary"
size="small"
@click="exportQuotes"
icon="el-icon-download"
class="pull-right card-header-item">
Export
</el-button>
<el-button
type="success"
size="small"
@click="$router.push({name: 'quote-create'})"
icon="el-icon-plus"
class="pull-right card-header-item">
Create new quote
</el-button>
</div>
<el-table
:data="quotes"
size="small"
style="width: 100%"
:row-class-name="tableRowHighlight"
v-loading="loading">
<el-table-column prop="ref_number" label="Ref #" width="107">
<template slot-scope="scope">
<el-popover
placement="bottom"
title="Edit Ref #:"
width="150"
v-model="scope.row.ref_number_edit"
@show="tmp_value = scope.row.ref_number">
<el-form
@submit.prevent="updateRefNumber(scope.row, tmp_value)"
inline
size="mini">
<el-input
type="text"
v-model="tmp_value"
size="mini"
class="pull-left"
style="width: 100px;margin-right:5px">
</el-input>
<el-button
type="primary"
native-type="submit"
icon="el-icon-check"
size="mini"
@click="updateRefNumber(scope.row, tmp_value)">
</el-button>
</el-form>
<span slot="reference" @click="scope.row.ref_number_edit = true">{{ scope.row.ref_number }}</span>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="created_date" label="Date"></el-table-column>
<el-table-column prop="work_type" label="Work type"></el-table-column>
<el-table-column prop="address_state" label="State" width="40"></el-table-column>
<el-table-column prop="customer_name" label="Customer"></el-table-column>
<el-table-column prop="address_name" label="Site"></el-table-column>
<el-table-column prop="po" label="PO #"></el-table-column>
<el-table-column prop="description" label="Description"></el-table-column>
<el-table-column prop="scope" label="Scope"></el-table-column>
<el-table-column prop="av" label="A/V" align="center" width="40"></el-table-column>
<el-table-column prop="si" label="S/I" align="center"></el-table-column>
<el-table-column prop="service_provider_name" label="Service Provider"></el-table-column>
<el-table-column prop="status" label="Status">
<template slot-scope="scope">
<el-popover
placement="bottom"
title="Edit status:"
width="230"
v-model="scope.row.status_edit"
@show="tmp_value = scope.row.status">
<el-form
@submit.prevent="updateStatus(scope.row, tmp_value)"
inline
size="mini">
<el-select
v-model="tmp_value"
size="mini"
style="width: 180px;margin-right:5px">
<el-option
v-for="(label, key) in statuses"
:key="key"
:label="label"
:value="key">
</el-option>
</el-select>
<el-button
type="primary"
native-type="submit"
icon="el-icon-check"
size="mini"
@click="updateStatus(scope.row, tmp_value)">
</el-button>
</el-form>
<span slot="reference" @click="scope.row.status_edit = true">{{ scope.row.status }}</span>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="days_to_quote" label="Days to Quote" align="center">
<template slot-scope="scope">
<el-popover
placement="bottom"
title="Edit days to quote:"
width="150"
v-model="scope.row.days_to_quote_edit"
@show="tmp_value = scope.row.days_to_quote">
<el-form
@submit.prevent="updateDaysToQuote(scope.row, tmp_value)"
inline
size="mini">
<el-input-number
type="text"
v-model="tmp_value"
size="mini"
class="pull-left"
style="width: 100px;margin-right:5px">
</el-input-number>
<el-button
type="primary"
native-type="submit"
icon="el-icon-check"
size="mini"
@click="updateDaysToQuote(scope.row, tmp_value)">
</el-button>
</el-form>
<span slot="reference" @click="scope.row.days_to_quote_edit = true">{{ scope.row.days_to_quote }}</span>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="api_cost" label="API Cost" align="right">
<template slot-scope="scope">
<el-popover
placement="bottom"
title="Edit API cost:"
width="130"
v-model="scope.row.api_cost_edit"
@show="tmp_value = scope.row.api_cost">
<el-form
@submit.prevent="updateApiCost(scope.row, tmp_value)"
inline
size="mini">
<el-input-number
type="text"
v-model="tmp_value"
:precision="2"
size="mini"
:controls="false"
class="pull-left"
style="width: 105px">
</el-input-number>
<el-button
type="primary"
native-type="submit"
icon="el-icon-check"
size="mini"
@click="updateApiCost(scope.row, tmp_value)">
</el-button>
</el-form>
<span slot="reference" @click="scope.row.api_cost_edit = true">{{ scope.row.api_cost }}</span>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="customer_cost" label="Customer Cost" align="right">
<template slot-scope="scope">{{ scope.row.customer_cost }}</template>
</el-table-column>
<el-table-column prop="gpm" label="GPM" align="right">
<template slot-scope="scope">{{ scope.row.gpm }}%</template>
</el-table-column>
<el-table-column prop="total_approved" label="Total Approved" align="right">
<template slot-scope="scope">{{ scope.row.total_approved }}</template>
</el-table-column>
<el-table-column prop="total_approved_api" label="Total Approved API" align="right">
<template slot-scope="scope">{{ scope.row.total_approved_api }}</template>
</el-table-column>
<el-table-column prop="total_rejected" label="Total Rejected" align="right">
<template slot-scope="scope">{{ scope.row.total_rejected }}</template>
</el-table-column>
<el-table-column prop="margin_approved" label="Margin on Approved" align="right">
<template slot-scope="scope">{{ scope.row.margin_approved }}</template>
</el-table-column>
<el-table-column prop="total_pending" label="Total Pending" align="right">
<template slot-scope="scope">{{ scope.row.total_pending }}</template>
</el-table-column>
<el-table-column label="Actions" align="center" width="100" fixed="right">
<template slot-scope="scope">
<el-button
type="primary"
size="mini"
icon="el-icon-edit"
@click="editQuote(scope.row.id)">
</el-button>
<el-button
type="danger"
size="mini"
icon="el-icon-delete"
@click.prevent.stop="deleteQuote(scope.row.id, $event)">
</el-button>
</template>
</el-table-column>
<template slot="empty">
<p>
You don't have any saved quotes yet.<br>
</p>
</template>
</el-table>
<div class="pagination">
<el-pagination
background
small
layout="prev, pager, next"
@current-change="changePage"
:page-size="per_page"
:current-page="current_page"
:total="total">
</el-pagination>
</div>
</el-card>
</div>
</template>
<script>
export default {
data () {
return {
tmp_value: '',
loading: false,
per_page: null,
current_page: null,
total: null,
quotes: ,
statuses:
}
},
methods: {
editQuote (quoteId) {
this.$router.push({
name: 'quote-edit',
params: { quoteId: quoteId }
})
},
viewQuote (quoteId) {
this.$router.push({
name: 'quote-view',
params: { quoteId: quoteId }
})
},
tableRowHighlight ({row, rowIndex}) {
if (row.status == 'APPROVED') {
return 'bg-success'
} else if (row.status == 'REJECTED') {
return 'bg-danger'
} else {
return ''
}
},
fetchQuotes () {
this.loading = true
this.$http
.get('/quotes', {
params: { page: this.current_page }
})
.then(res => {
this.loading = false
this.statuses = res.data.statuses
this.quotes = res.data.quotes.data
console.log(this.quotes)
this.current_page = res.data.quotes.current_page
this.per_page = res.data.quotes.per_page
this.total = res.data.quotes.total
})
.catch(err => {
this.loading = false
console.log(err)
})
},
changePage (page) {
this.current_page = page
this.fetchQuotes()
},
exportQuotes () {
window.open('/quotes/export', '_blank');
},
updateApiCost (quote, value) {
this.$http
.post('/quotes/' + quote.id + '/inline', {api_cost: value})
.then(res => {
quote.api_cost_edit = false
this.fetchQuotes()
this.$message({
message: 'API cost has been successfuly updated.',
type: 'success'
})
})
.catch(err => {
this.showErrorAlert(err.response.data.message)
})
},
updateRefNumber (quote, value) {
this.$http
.post('/quotes/' + quote.id + '/inline', {ref_number: value})
.then(res => {
quote.ref_number_edit = false
this.fetchQuotes()
this.$message({
message: 'Reference # has been successfuly updated.',
type: 'success'
})
})
.catch(err => {
this.showErrorAlert(err.response.data.message)
})
},
updateStatus (quote, value) {
this.$http
.post('/quotes/' + quote.id + '/inline', {status: value})
.then(res => {
quote.status_edit = false
this.fetchQuotes()
this.$message({
message: 'Status has been successfuly updated.',
type: 'success'
})
})
.catch(err => {
this.showErrorAlert(err.response.data.message)
})
},
updateDaysToQuote (quote, value) {
this.$http
.post('/quotes/' + quote.id + '/inline', {days_to_quote: value})
.then(res => {
quote.days_to_quote_edit = false
this.fetchQuotes()
this.$message({
message: 'Days to quote have been successfuly updated.',
type: 'success'
})
})
.catch(err => {
this.showErrorAlert(err.response.data.message)
})
},
deleteQuote (quoteId) {
this.$confirm('Are you sure you want to delete this quote?', 'Warning', {
confirmButtonText: 'OK',
cancelButtonText: 'Cancel',
type: 'warning'
})
.then(() => {
this.$http
.delete('/quotes/' + quoteId)
.then(res => {
this.fetchQuotes()
this.$message({
type: 'success',
message: res.data.message
})
})
.catch(err => {
this.showErrorAlert(err.response.data.message)
})
})
.catch(err => {
console.log(err);
})
},
showErrorAlert (message) {
message = '<b>' + message + '</b><br>Please contact with administrator to fix this issue.'
this.$alert(message, 'Error', {
dangerouslyUseHTMLString: true,
confirmButtonText: 'OK',
type: 'error',
center: true
})
}
},
mounted () {
this.fetchQuotes()
}
}
</script>
<style lang="scss" scoped>
.pagination {
float: right;
margin: 20px 0
}
</style>
Hope you guys will help me find a solution.
Thanks!
javascript performance vue.js
add a comment |
I have big performance problem with my vue app.
I have table with ~50 rows its has a slot-scope="scope" attribute
When i try to make some event on selected row for example open Element UI select element whole page freezes for a long time.
I checked in chrome webdev performance tab and it look like site is doing much function calls:
browser performance test
Its working fast if i have only few rows in a table.
Here is my component code:
<template>
<div>
<el-card>
<div slot="header">
Quotes
<el-button
type="primary"
size="small"
@click="exportQuotes"
icon="el-icon-download"
class="pull-right card-header-item">
Export
</el-button>
<el-button
type="success"
size="small"
@click="$router.push({name: 'quote-create'})"
icon="el-icon-plus"
class="pull-right card-header-item">
Create new quote
</el-button>
</div>
<el-table
:data="quotes"
size="small"
style="width: 100%"
:row-class-name="tableRowHighlight"
v-loading="loading">
<el-table-column prop="ref_number" label="Ref #" width="107">
<template slot-scope="scope">
<el-popover
placement="bottom"
title="Edit Ref #:"
width="150"
v-model="scope.row.ref_number_edit"
@show="tmp_value = scope.row.ref_number">
<el-form
@submit.prevent="updateRefNumber(scope.row, tmp_value)"
inline
size="mini">
<el-input
type="text"
v-model="tmp_value"
size="mini"
class="pull-left"
style="width: 100px;margin-right:5px">
</el-input>
<el-button
type="primary"
native-type="submit"
icon="el-icon-check"
size="mini"
@click="updateRefNumber(scope.row, tmp_value)">
</el-button>
</el-form>
<span slot="reference" @click="scope.row.ref_number_edit = true">{{ scope.row.ref_number }}</span>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="created_date" label="Date"></el-table-column>
<el-table-column prop="work_type" label="Work type"></el-table-column>
<el-table-column prop="address_state" label="State" width="40"></el-table-column>
<el-table-column prop="customer_name" label="Customer"></el-table-column>
<el-table-column prop="address_name" label="Site"></el-table-column>
<el-table-column prop="po" label="PO #"></el-table-column>
<el-table-column prop="description" label="Description"></el-table-column>
<el-table-column prop="scope" label="Scope"></el-table-column>
<el-table-column prop="av" label="A/V" align="center" width="40"></el-table-column>
<el-table-column prop="si" label="S/I" align="center"></el-table-column>
<el-table-column prop="service_provider_name" label="Service Provider"></el-table-column>
<el-table-column prop="status" label="Status">
<template slot-scope="scope">
<el-popover
placement="bottom"
title="Edit status:"
width="230"
v-model="scope.row.status_edit"
@show="tmp_value = scope.row.status">
<el-form
@submit.prevent="updateStatus(scope.row, tmp_value)"
inline
size="mini">
<el-select
v-model="tmp_value"
size="mini"
style="width: 180px;margin-right:5px">
<el-option
v-for="(label, key) in statuses"
:key="key"
:label="label"
:value="key">
</el-option>
</el-select>
<el-button
type="primary"
native-type="submit"
icon="el-icon-check"
size="mini"
@click="updateStatus(scope.row, tmp_value)">
</el-button>
</el-form>
<span slot="reference" @click="scope.row.status_edit = true">{{ scope.row.status }}</span>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="days_to_quote" label="Days to Quote" align="center">
<template slot-scope="scope">
<el-popover
placement="bottom"
title="Edit days to quote:"
width="150"
v-model="scope.row.days_to_quote_edit"
@show="tmp_value = scope.row.days_to_quote">
<el-form
@submit.prevent="updateDaysToQuote(scope.row, tmp_value)"
inline
size="mini">
<el-input-number
type="text"
v-model="tmp_value"
size="mini"
class="pull-left"
style="width: 100px;margin-right:5px">
</el-input-number>
<el-button
type="primary"
native-type="submit"
icon="el-icon-check"
size="mini"
@click="updateDaysToQuote(scope.row, tmp_value)">
</el-button>
</el-form>
<span slot="reference" @click="scope.row.days_to_quote_edit = true">{{ scope.row.days_to_quote }}</span>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="api_cost" label="API Cost" align="right">
<template slot-scope="scope">
<el-popover
placement="bottom"
title="Edit API cost:"
width="130"
v-model="scope.row.api_cost_edit"
@show="tmp_value = scope.row.api_cost">
<el-form
@submit.prevent="updateApiCost(scope.row, tmp_value)"
inline
size="mini">
<el-input-number
type="text"
v-model="tmp_value"
:precision="2"
size="mini"
:controls="false"
class="pull-left"
style="width: 105px">
</el-input-number>
<el-button
type="primary"
native-type="submit"
icon="el-icon-check"
size="mini"
@click="updateApiCost(scope.row, tmp_value)">
</el-button>
</el-form>
<span slot="reference" @click="scope.row.api_cost_edit = true">{{ scope.row.api_cost }}</span>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="customer_cost" label="Customer Cost" align="right">
<template slot-scope="scope">{{ scope.row.customer_cost }}</template>
</el-table-column>
<el-table-column prop="gpm" label="GPM" align="right">
<template slot-scope="scope">{{ scope.row.gpm }}%</template>
</el-table-column>
<el-table-column prop="total_approved" label="Total Approved" align="right">
<template slot-scope="scope">{{ scope.row.total_approved }}</template>
</el-table-column>
<el-table-column prop="total_approved_api" label="Total Approved API" align="right">
<template slot-scope="scope">{{ scope.row.total_approved_api }}</template>
</el-table-column>
<el-table-column prop="total_rejected" label="Total Rejected" align="right">
<template slot-scope="scope">{{ scope.row.total_rejected }}</template>
</el-table-column>
<el-table-column prop="margin_approved" label="Margin on Approved" align="right">
<template slot-scope="scope">{{ scope.row.margin_approved }}</template>
</el-table-column>
<el-table-column prop="total_pending" label="Total Pending" align="right">
<template slot-scope="scope">{{ scope.row.total_pending }}</template>
</el-table-column>
<el-table-column label="Actions" align="center" width="100" fixed="right">
<template slot-scope="scope">
<el-button
type="primary"
size="mini"
icon="el-icon-edit"
@click="editQuote(scope.row.id)">
</el-button>
<el-button
type="danger"
size="mini"
icon="el-icon-delete"
@click.prevent.stop="deleteQuote(scope.row.id, $event)">
</el-button>
</template>
</el-table-column>
<template slot="empty">
<p>
You don't have any saved quotes yet.<br>
</p>
</template>
</el-table>
<div class="pagination">
<el-pagination
background
small
layout="prev, pager, next"
@current-change="changePage"
:page-size="per_page"
:current-page="current_page"
:total="total">
</el-pagination>
</div>
</el-card>
</div>
</template>
<script>
export default {
data () {
return {
tmp_value: '',
loading: false,
per_page: null,
current_page: null,
total: null,
quotes: ,
statuses:
}
},
methods: {
editQuote (quoteId) {
this.$router.push({
name: 'quote-edit',
params: { quoteId: quoteId }
})
},
viewQuote (quoteId) {
this.$router.push({
name: 'quote-view',
params: { quoteId: quoteId }
})
},
tableRowHighlight ({row, rowIndex}) {
if (row.status == 'APPROVED') {
return 'bg-success'
} else if (row.status == 'REJECTED') {
return 'bg-danger'
} else {
return ''
}
},
fetchQuotes () {
this.loading = true
this.$http
.get('/quotes', {
params: { page: this.current_page }
})
.then(res => {
this.loading = false
this.statuses = res.data.statuses
this.quotes = res.data.quotes.data
console.log(this.quotes)
this.current_page = res.data.quotes.current_page
this.per_page = res.data.quotes.per_page
this.total = res.data.quotes.total
})
.catch(err => {
this.loading = false
console.log(err)
})
},
changePage (page) {
this.current_page = page
this.fetchQuotes()
},
exportQuotes () {
window.open('/quotes/export', '_blank');
},
updateApiCost (quote, value) {
this.$http
.post('/quotes/' + quote.id + '/inline', {api_cost: value})
.then(res => {
quote.api_cost_edit = false
this.fetchQuotes()
this.$message({
message: 'API cost has been successfuly updated.',
type: 'success'
})
})
.catch(err => {
this.showErrorAlert(err.response.data.message)
})
},
updateRefNumber (quote, value) {
this.$http
.post('/quotes/' + quote.id + '/inline', {ref_number: value})
.then(res => {
quote.ref_number_edit = false
this.fetchQuotes()
this.$message({
message: 'Reference # has been successfuly updated.',
type: 'success'
})
})
.catch(err => {
this.showErrorAlert(err.response.data.message)
})
},
updateStatus (quote, value) {
this.$http
.post('/quotes/' + quote.id + '/inline', {status: value})
.then(res => {
quote.status_edit = false
this.fetchQuotes()
this.$message({
message: 'Status has been successfuly updated.',
type: 'success'
})
})
.catch(err => {
this.showErrorAlert(err.response.data.message)
})
},
updateDaysToQuote (quote, value) {
this.$http
.post('/quotes/' + quote.id + '/inline', {days_to_quote: value})
.then(res => {
quote.days_to_quote_edit = false
this.fetchQuotes()
this.$message({
message: 'Days to quote have been successfuly updated.',
type: 'success'
})
})
.catch(err => {
this.showErrorAlert(err.response.data.message)
})
},
deleteQuote (quoteId) {
this.$confirm('Are you sure you want to delete this quote?', 'Warning', {
confirmButtonText: 'OK',
cancelButtonText: 'Cancel',
type: 'warning'
})
.then(() => {
this.$http
.delete('/quotes/' + quoteId)
.then(res => {
this.fetchQuotes()
this.$message({
type: 'success',
message: res.data.message
})
})
.catch(err => {
this.showErrorAlert(err.response.data.message)
})
})
.catch(err => {
console.log(err);
})
},
showErrorAlert (message) {
message = '<b>' + message + '</b><br>Please contact with administrator to fix this issue.'
this.$alert(message, 'Error', {
dangerouslyUseHTMLString: true,
confirmButtonText: 'OK',
type: 'error',
center: true
})
}
},
mounted () {
this.fetchQuotes()
}
}
</script>
<style lang="scss" scoped>
.pagination {
float: right;
margin: 20px 0
}
</style>
Hope you guys will help me find a solution.
Thanks!
javascript performance vue.js
1
"Hope you guys will help me find a solution" Hard to do without seeing any code.
– Daniel
Nov 20 '18 at 16:16
Sorry i forgot about a code @Daniel here is my component code pastebin.com/J4uAmnYc
– Szymon Sus
Nov 20 '18 at 16:42
add a comment |
I have big performance problem with my vue app.
I have table with ~50 rows its has a slot-scope="scope" attribute
When i try to make some event on selected row for example open Element UI select element whole page freezes for a long time.
I checked in chrome webdev performance tab and it look like site is doing much function calls:
browser performance test
Its working fast if i have only few rows in a table.
Here is my component code:
<template>
<div>
<el-card>
<div slot="header">
Quotes
<el-button
type="primary"
size="small"
@click="exportQuotes"
icon="el-icon-download"
class="pull-right card-header-item">
Export
</el-button>
<el-button
type="success"
size="small"
@click="$router.push({name: 'quote-create'})"
icon="el-icon-plus"
class="pull-right card-header-item">
Create new quote
</el-button>
</div>
<el-table
:data="quotes"
size="small"
style="width: 100%"
:row-class-name="tableRowHighlight"
v-loading="loading">
<el-table-column prop="ref_number" label="Ref #" width="107">
<template slot-scope="scope">
<el-popover
placement="bottom"
title="Edit Ref #:"
width="150"
v-model="scope.row.ref_number_edit"
@show="tmp_value = scope.row.ref_number">
<el-form
@submit.prevent="updateRefNumber(scope.row, tmp_value)"
inline
size="mini">
<el-input
type="text"
v-model="tmp_value"
size="mini"
class="pull-left"
style="width: 100px;margin-right:5px">
</el-input>
<el-button
type="primary"
native-type="submit"
icon="el-icon-check"
size="mini"
@click="updateRefNumber(scope.row, tmp_value)">
</el-button>
</el-form>
<span slot="reference" @click="scope.row.ref_number_edit = true">{{ scope.row.ref_number }}</span>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="created_date" label="Date"></el-table-column>
<el-table-column prop="work_type" label="Work type"></el-table-column>
<el-table-column prop="address_state" label="State" width="40"></el-table-column>
<el-table-column prop="customer_name" label="Customer"></el-table-column>
<el-table-column prop="address_name" label="Site"></el-table-column>
<el-table-column prop="po" label="PO #"></el-table-column>
<el-table-column prop="description" label="Description"></el-table-column>
<el-table-column prop="scope" label="Scope"></el-table-column>
<el-table-column prop="av" label="A/V" align="center" width="40"></el-table-column>
<el-table-column prop="si" label="S/I" align="center"></el-table-column>
<el-table-column prop="service_provider_name" label="Service Provider"></el-table-column>
<el-table-column prop="status" label="Status">
<template slot-scope="scope">
<el-popover
placement="bottom"
title="Edit status:"
width="230"
v-model="scope.row.status_edit"
@show="tmp_value = scope.row.status">
<el-form
@submit.prevent="updateStatus(scope.row, tmp_value)"
inline
size="mini">
<el-select
v-model="tmp_value"
size="mini"
style="width: 180px;margin-right:5px">
<el-option
v-for="(label, key) in statuses"
:key="key"
:label="label"
:value="key">
</el-option>
</el-select>
<el-button
type="primary"
native-type="submit"
icon="el-icon-check"
size="mini"
@click="updateStatus(scope.row, tmp_value)">
</el-button>
</el-form>
<span slot="reference" @click="scope.row.status_edit = true">{{ scope.row.status }}</span>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="days_to_quote" label="Days to Quote" align="center">
<template slot-scope="scope">
<el-popover
placement="bottom"
title="Edit days to quote:"
width="150"
v-model="scope.row.days_to_quote_edit"
@show="tmp_value = scope.row.days_to_quote">
<el-form
@submit.prevent="updateDaysToQuote(scope.row, tmp_value)"
inline
size="mini">
<el-input-number
type="text"
v-model="tmp_value"
size="mini"
class="pull-left"
style="width: 100px;margin-right:5px">
</el-input-number>
<el-button
type="primary"
native-type="submit"
icon="el-icon-check"
size="mini"
@click="updateDaysToQuote(scope.row, tmp_value)">
</el-button>
</el-form>
<span slot="reference" @click="scope.row.days_to_quote_edit = true">{{ scope.row.days_to_quote }}</span>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="api_cost" label="API Cost" align="right">
<template slot-scope="scope">
<el-popover
placement="bottom"
title="Edit API cost:"
width="130"
v-model="scope.row.api_cost_edit"
@show="tmp_value = scope.row.api_cost">
<el-form
@submit.prevent="updateApiCost(scope.row, tmp_value)"
inline
size="mini">
<el-input-number
type="text"
v-model="tmp_value"
:precision="2"
size="mini"
:controls="false"
class="pull-left"
style="width: 105px">
</el-input-number>
<el-button
type="primary"
native-type="submit"
icon="el-icon-check"
size="mini"
@click="updateApiCost(scope.row, tmp_value)">
</el-button>
</el-form>
<span slot="reference" @click="scope.row.api_cost_edit = true">{{ scope.row.api_cost }}</span>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="customer_cost" label="Customer Cost" align="right">
<template slot-scope="scope">{{ scope.row.customer_cost }}</template>
</el-table-column>
<el-table-column prop="gpm" label="GPM" align="right">
<template slot-scope="scope">{{ scope.row.gpm }}%</template>
</el-table-column>
<el-table-column prop="total_approved" label="Total Approved" align="right">
<template slot-scope="scope">{{ scope.row.total_approved }}</template>
</el-table-column>
<el-table-column prop="total_approved_api" label="Total Approved API" align="right">
<template slot-scope="scope">{{ scope.row.total_approved_api }}</template>
</el-table-column>
<el-table-column prop="total_rejected" label="Total Rejected" align="right">
<template slot-scope="scope">{{ scope.row.total_rejected }}</template>
</el-table-column>
<el-table-column prop="margin_approved" label="Margin on Approved" align="right">
<template slot-scope="scope">{{ scope.row.margin_approved }}</template>
</el-table-column>
<el-table-column prop="total_pending" label="Total Pending" align="right">
<template slot-scope="scope">{{ scope.row.total_pending }}</template>
</el-table-column>
<el-table-column label="Actions" align="center" width="100" fixed="right">
<template slot-scope="scope">
<el-button
type="primary"
size="mini"
icon="el-icon-edit"
@click="editQuote(scope.row.id)">
</el-button>
<el-button
type="danger"
size="mini"
icon="el-icon-delete"
@click.prevent.stop="deleteQuote(scope.row.id, $event)">
</el-button>
</template>
</el-table-column>
<template slot="empty">
<p>
You don't have any saved quotes yet.<br>
</p>
</template>
</el-table>
<div class="pagination">
<el-pagination
background
small
layout="prev, pager, next"
@current-change="changePage"
:page-size="per_page"
:current-page="current_page"
:total="total">
</el-pagination>
</div>
</el-card>
</div>
</template>
<script>
export default {
data () {
return {
tmp_value: '',
loading: false,
per_page: null,
current_page: null,
total: null,
quotes: ,
statuses:
}
},
methods: {
editQuote (quoteId) {
this.$router.push({
name: 'quote-edit',
params: { quoteId: quoteId }
})
},
viewQuote (quoteId) {
this.$router.push({
name: 'quote-view',
params: { quoteId: quoteId }
})
},
tableRowHighlight ({row, rowIndex}) {
if (row.status == 'APPROVED') {
return 'bg-success'
} else if (row.status == 'REJECTED') {
return 'bg-danger'
} else {
return ''
}
},
fetchQuotes () {
this.loading = true
this.$http
.get('/quotes', {
params: { page: this.current_page }
})
.then(res => {
this.loading = false
this.statuses = res.data.statuses
this.quotes = res.data.quotes.data
console.log(this.quotes)
this.current_page = res.data.quotes.current_page
this.per_page = res.data.quotes.per_page
this.total = res.data.quotes.total
})
.catch(err => {
this.loading = false
console.log(err)
})
},
changePage (page) {
this.current_page = page
this.fetchQuotes()
},
exportQuotes () {
window.open('/quotes/export', '_blank');
},
updateApiCost (quote, value) {
this.$http
.post('/quotes/' + quote.id + '/inline', {api_cost: value})
.then(res => {
quote.api_cost_edit = false
this.fetchQuotes()
this.$message({
message: 'API cost has been successfuly updated.',
type: 'success'
})
})
.catch(err => {
this.showErrorAlert(err.response.data.message)
})
},
updateRefNumber (quote, value) {
this.$http
.post('/quotes/' + quote.id + '/inline', {ref_number: value})
.then(res => {
quote.ref_number_edit = false
this.fetchQuotes()
this.$message({
message: 'Reference # has been successfuly updated.',
type: 'success'
})
})
.catch(err => {
this.showErrorAlert(err.response.data.message)
})
},
updateStatus (quote, value) {
this.$http
.post('/quotes/' + quote.id + '/inline', {status: value})
.then(res => {
quote.status_edit = false
this.fetchQuotes()
this.$message({
message: 'Status has been successfuly updated.',
type: 'success'
})
})
.catch(err => {
this.showErrorAlert(err.response.data.message)
})
},
updateDaysToQuote (quote, value) {
this.$http
.post('/quotes/' + quote.id + '/inline', {days_to_quote: value})
.then(res => {
quote.days_to_quote_edit = false
this.fetchQuotes()
this.$message({
message: 'Days to quote have been successfuly updated.',
type: 'success'
})
})
.catch(err => {
this.showErrorAlert(err.response.data.message)
})
},
deleteQuote (quoteId) {
this.$confirm('Are you sure you want to delete this quote?', 'Warning', {
confirmButtonText: 'OK',
cancelButtonText: 'Cancel',
type: 'warning'
})
.then(() => {
this.$http
.delete('/quotes/' + quoteId)
.then(res => {
this.fetchQuotes()
this.$message({
type: 'success',
message: res.data.message
})
})
.catch(err => {
this.showErrorAlert(err.response.data.message)
})
})
.catch(err => {
console.log(err);
})
},
showErrorAlert (message) {
message = '<b>' + message + '</b><br>Please contact with administrator to fix this issue.'
this.$alert(message, 'Error', {
dangerouslyUseHTMLString: true,
confirmButtonText: 'OK',
type: 'error',
center: true
})
}
},
mounted () {
this.fetchQuotes()
}
}
</script>
<style lang="scss" scoped>
.pagination {
float: right;
margin: 20px 0
}
</style>
Hope you guys will help me find a solution.
Thanks!
javascript performance vue.js
I have big performance problem with my vue app.
I have table with ~50 rows its has a slot-scope="scope" attribute
When i try to make some event on selected row for example open Element UI select element whole page freezes for a long time.
I checked in chrome webdev performance tab and it look like site is doing much function calls:
browser performance test
Its working fast if i have only few rows in a table.
Here is my component code:
<template>
<div>
<el-card>
<div slot="header">
Quotes
<el-button
type="primary"
size="small"
@click="exportQuotes"
icon="el-icon-download"
class="pull-right card-header-item">
Export
</el-button>
<el-button
type="success"
size="small"
@click="$router.push({name: 'quote-create'})"
icon="el-icon-plus"
class="pull-right card-header-item">
Create new quote
</el-button>
</div>
<el-table
:data="quotes"
size="small"
style="width: 100%"
:row-class-name="tableRowHighlight"
v-loading="loading">
<el-table-column prop="ref_number" label="Ref #" width="107">
<template slot-scope="scope">
<el-popover
placement="bottom"
title="Edit Ref #:"
width="150"
v-model="scope.row.ref_number_edit"
@show="tmp_value = scope.row.ref_number">
<el-form
@submit.prevent="updateRefNumber(scope.row, tmp_value)"
inline
size="mini">
<el-input
type="text"
v-model="tmp_value"
size="mini"
class="pull-left"
style="width: 100px;margin-right:5px">
</el-input>
<el-button
type="primary"
native-type="submit"
icon="el-icon-check"
size="mini"
@click="updateRefNumber(scope.row, tmp_value)">
</el-button>
</el-form>
<span slot="reference" @click="scope.row.ref_number_edit = true">{{ scope.row.ref_number }}</span>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="created_date" label="Date"></el-table-column>
<el-table-column prop="work_type" label="Work type"></el-table-column>
<el-table-column prop="address_state" label="State" width="40"></el-table-column>
<el-table-column prop="customer_name" label="Customer"></el-table-column>
<el-table-column prop="address_name" label="Site"></el-table-column>
<el-table-column prop="po" label="PO #"></el-table-column>
<el-table-column prop="description" label="Description"></el-table-column>
<el-table-column prop="scope" label="Scope"></el-table-column>
<el-table-column prop="av" label="A/V" align="center" width="40"></el-table-column>
<el-table-column prop="si" label="S/I" align="center"></el-table-column>
<el-table-column prop="service_provider_name" label="Service Provider"></el-table-column>
<el-table-column prop="status" label="Status">
<template slot-scope="scope">
<el-popover
placement="bottom"
title="Edit status:"
width="230"
v-model="scope.row.status_edit"
@show="tmp_value = scope.row.status">
<el-form
@submit.prevent="updateStatus(scope.row, tmp_value)"
inline
size="mini">
<el-select
v-model="tmp_value"
size="mini"
style="width: 180px;margin-right:5px">
<el-option
v-for="(label, key) in statuses"
:key="key"
:label="label"
:value="key">
</el-option>
</el-select>
<el-button
type="primary"
native-type="submit"
icon="el-icon-check"
size="mini"
@click="updateStatus(scope.row, tmp_value)">
</el-button>
</el-form>
<span slot="reference" @click="scope.row.status_edit = true">{{ scope.row.status }}</span>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="days_to_quote" label="Days to Quote" align="center">
<template slot-scope="scope">
<el-popover
placement="bottom"
title="Edit days to quote:"
width="150"
v-model="scope.row.days_to_quote_edit"
@show="tmp_value = scope.row.days_to_quote">
<el-form
@submit.prevent="updateDaysToQuote(scope.row, tmp_value)"
inline
size="mini">
<el-input-number
type="text"
v-model="tmp_value"
size="mini"
class="pull-left"
style="width: 100px;margin-right:5px">
</el-input-number>
<el-button
type="primary"
native-type="submit"
icon="el-icon-check"
size="mini"
@click="updateDaysToQuote(scope.row, tmp_value)">
</el-button>
</el-form>
<span slot="reference" @click="scope.row.days_to_quote_edit = true">{{ scope.row.days_to_quote }}</span>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="api_cost" label="API Cost" align="right">
<template slot-scope="scope">
<el-popover
placement="bottom"
title="Edit API cost:"
width="130"
v-model="scope.row.api_cost_edit"
@show="tmp_value = scope.row.api_cost">
<el-form
@submit.prevent="updateApiCost(scope.row, tmp_value)"
inline
size="mini">
<el-input-number
type="text"
v-model="tmp_value"
:precision="2"
size="mini"
:controls="false"
class="pull-left"
style="width: 105px">
</el-input-number>
<el-button
type="primary"
native-type="submit"
icon="el-icon-check"
size="mini"
@click="updateApiCost(scope.row, tmp_value)">
</el-button>
</el-form>
<span slot="reference" @click="scope.row.api_cost_edit = true">{{ scope.row.api_cost }}</span>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="customer_cost" label="Customer Cost" align="right">
<template slot-scope="scope">{{ scope.row.customer_cost }}</template>
</el-table-column>
<el-table-column prop="gpm" label="GPM" align="right">
<template slot-scope="scope">{{ scope.row.gpm }}%</template>
</el-table-column>
<el-table-column prop="total_approved" label="Total Approved" align="right">
<template slot-scope="scope">{{ scope.row.total_approved }}</template>
</el-table-column>
<el-table-column prop="total_approved_api" label="Total Approved API" align="right">
<template slot-scope="scope">{{ scope.row.total_approved_api }}</template>
</el-table-column>
<el-table-column prop="total_rejected" label="Total Rejected" align="right">
<template slot-scope="scope">{{ scope.row.total_rejected }}</template>
</el-table-column>
<el-table-column prop="margin_approved" label="Margin on Approved" align="right">
<template slot-scope="scope">{{ scope.row.margin_approved }}</template>
</el-table-column>
<el-table-column prop="total_pending" label="Total Pending" align="right">
<template slot-scope="scope">{{ scope.row.total_pending }}</template>
</el-table-column>
<el-table-column label="Actions" align="center" width="100" fixed="right">
<template slot-scope="scope">
<el-button
type="primary"
size="mini"
icon="el-icon-edit"
@click="editQuote(scope.row.id)">
</el-button>
<el-button
type="danger"
size="mini"
icon="el-icon-delete"
@click.prevent.stop="deleteQuote(scope.row.id, $event)">
</el-button>
</template>
</el-table-column>
<template slot="empty">
<p>
You don't have any saved quotes yet.<br>
</p>
</template>
</el-table>
<div class="pagination">
<el-pagination
background
small
layout="prev, pager, next"
@current-change="changePage"
:page-size="per_page"
:current-page="current_page"
:total="total">
</el-pagination>
</div>
</el-card>
</div>
</template>
<script>
export default {
data () {
return {
tmp_value: '',
loading: false,
per_page: null,
current_page: null,
total: null,
quotes: ,
statuses:
}
},
methods: {
editQuote (quoteId) {
this.$router.push({
name: 'quote-edit',
params: { quoteId: quoteId }
})
},
viewQuote (quoteId) {
this.$router.push({
name: 'quote-view',
params: { quoteId: quoteId }
})
},
tableRowHighlight ({row, rowIndex}) {
if (row.status == 'APPROVED') {
return 'bg-success'
} else if (row.status == 'REJECTED') {
return 'bg-danger'
} else {
return ''
}
},
fetchQuotes () {
this.loading = true
this.$http
.get('/quotes', {
params: { page: this.current_page }
})
.then(res => {
this.loading = false
this.statuses = res.data.statuses
this.quotes = res.data.quotes.data
console.log(this.quotes)
this.current_page = res.data.quotes.current_page
this.per_page = res.data.quotes.per_page
this.total = res.data.quotes.total
})
.catch(err => {
this.loading = false
console.log(err)
})
},
changePage (page) {
this.current_page = page
this.fetchQuotes()
},
exportQuotes () {
window.open('/quotes/export', '_blank');
},
updateApiCost (quote, value) {
this.$http
.post('/quotes/' + quote.id + '/inline', {api_cost: value})
.then(res => {
quote.api_cost_edit = false
this.fetchQuotes()
this.$message({
message: 'API cost has been successfuly updated.',
type: 'success'
})
})
.catch(err => {
this.showErrorAlert(err.response.data.message)
})
},
updateRefNumber (quote, value) {
this.$http
.post('/quotes/' + quote.id + '/inline', {ref_number: value})
.then(res => {
quote.ref_number_edit = false
this.fetchQuotes()
this.$message({
message: 'Reference # has been successfuly updated.',
type: 'success'
})
})
.catch(err => {
this.showErrorAlert(err.response.data.message)
})
},
updateStatus (quote, value) {
this.$http
.post('/quotes/' + quote.id + '/inline', {status: value})
.then(res => {
quote.status_edit = false
this.fetchQuotes()
this.$message({
message: 'Status has been successfuly updated.',
type: 'success'
})
})
.catch(err => {
this.showErrorAlert(err.response.data.message)
})
},
updateDaysToQuote (quote, value) {
this.$http
.post('/quotes/' + quote.id + '/inline', {days_to_quote: value})
.then(res => {
quote.days_to_quote_edit = false
this.fetchQuotes()
this.$message({
message: 'Days to quote have been successfuly updated.',
type: 'success'
})
})
.catch(err => {
this.showErrorAlert(err.response.data.message)
})
},
deleteQuote (quoteId) {
this.$confirm('Are you sure you want to delete this quote?', 'Warning', {
confirmButtonText: 'OK',
cancelButtonText: 'Cancel',
type: 'warning'
})
.then(() => {
this.$http
.delete('/quotes/' + quoteId)
.then(res => {
this.fetchQuotes()
this.$message({
type: 'success',
message: res.data.message
})
})
.catch(err => {
this.showErrorAlert(err.response.data.message)
})
})
.catch(err => {
console.log(err);
})
},
showErrorAlert (message) {
message = '<b>' + message + '</b><br>Please contact with administrator to fix this issue.'
this.$alert(message, 'Error', {
dangerouslyUseHTMLString: true,
confirmButtonText: 'OK',
type: 'error',
center: true
})
}
},
mounted () {
this.fetchQuotes()
}
}
</script>
<style lang="scss" scoped>
.pagination {
float: right;
margin: 20px 0
}
</style>
Hope you guys will help me find a solution.
Thanks!
javascript performance vue.js
javascript performance vue.js
edited Nov 20 '18 at 16:49
Szymon Sus
asked Nov 20 '18 at 16:02
Szymon SusSzymon Sus
11
11
1
"Hope you guys will help me find a solution" Hard to do without seeing any code.
– Daniel
Nov 20 '18 at 16:16
Sorry i forgot about a code @Daniel here is my component code pastebin.com/J4uAmnYc
– Szymon Sus
Nov 20 '18 at 16:42
add a comment |
1
"Hope you guys will help me find a solution" Hard to do without seeing any code.
– Daniel
Nov 20 '18 at 16:16
Sorry i forgot about a code @Daniel here is my component code pastebin.com/J4uAmnYc
– Szymon Sus
Nov 20 '18 at 16:42
1
1
"Hope you guys will help me find a solution" Hard to do without seeing any code.
– Daniel
Nov 20 '18 at 16:16
"Hope you guys will help me find a solution" Hard to do without seeing any code.
– Daniel
Nov 20 '18 at 16:16
Sorry i forgot about a code @Daniel here is my component code pastebin.com/J4uAmnYc
– Szymon Sus
Nov 20 '18 at 16:42
Sorry i forgot about a code @Daniel here is my component code pastebin.com/J4uAmnYc
– Szymon Sus
Nov 20 '18 at 16:42
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53396935%2fvue-event-bad-performance%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53396935%2fvue-event-bad-performance%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
"Hope you guys will help me find a solution" Hard to do without seeing any code.
– Daniel
Nov 20 '18 at 16:16
Sorry i forgot about a code @Daniel here is my component code pastebin.com/J4uAmnYc
– Szymon Sus
Nov 20 '18 at 16:42