Vue event bad performance












0















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!










share|improve this question




















  • 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


















0















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!










share|improve this question




















  • 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
















0












0








0








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!










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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
















  • 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














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
});


}
});














draft saved

draft discarded


















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
















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

How to pass form data using jquery Ajax to insert data in database?

National Museum of Racing and Hall of Fame

Accessing nested JavaScript objects with string key