【发布时间】:2021-01-11 07:30:07
【问题描述】:
我有一个页面,它使用内联 vue.js 脚本显示表中的行列表,它会在页面加载时获取行列表,但也会在收到推送事件时再次获取表。
我有一个模式窗口,它打开并允许用户将新人添加到表中。当用户按下提交(在表单上)时,模式会发布一个 ajax 请求(使用 axios)来提交记录。这会向 Pusher 发送一个 App\Events\NewQueueMember 事件,我的 vue 应用程序也会监听该事件,当发生这种情况时,将调用 updateData 方法来刷新表。
我遇到的问题是提交表单时,页面在大约 5 秒钟内有些无响应,然后才能再次在页面上滚动。查看 Chromes 任务管理器,我可以看到选项卡的 RAM 使用量翻了一番,CPU 使用率也相当高。
我相信这是某种内存泄漏,但我不确定如何解决,希望得到一些指导。
这是驻留在我的模式中的表单。
@csrf 顾客姓名 名称将在内部显示给客户<div class="form-group">
<label for="add-person-mobile">Mobile Number</label>
<input type="phone" class="form-control" name="phone_number" id="add-person-mobile"
v-model="addPersonForm.phone_number">
<small id="emailHelp" class="form-text text-muted">Please ensure number starts with +44 </small>
</div>
<div class="form-group">
<label for="add-person-party-size">Party Size</label>
<input type="number" class="form-control" name="party_size" id="add-person-party-size"
v-model="addPersonForm.party_size">
</div>
这是同一页面内的站点的 vue.js 脚本块
<script>
Vue.use(VueTimeago, {
name: 'Timeago',
})
let vm = new Vue({
el: '#app',
data() {
return {
live_count: null,
queue: null,
loading: true,
errored: false,
buttons: {
add_to_queue_label: 'Add to Queue',
add_to_queue_disabled: false
},
addPersonForm: {
name: '',
phone_number: '',
party_size: ''
}
}
},
mounted() {
axios
.get(`/business/queue-live-feed`)
.then(response => {
console.log('got response data')
console.log(response.data)
this.queue = response.data.queue
this.live_count = response.data.live_count
})
.catch(error => {
console.log(error)
this.errored = true
})
.finally(() => this.loading = false);
},
methods: {
updateData: function () {
axios.get(`/business/queue-live-feed`)
.then(response => {
this.queue = response.data.queue
this.live_count = response.data.live_count
})
.catch(error => {
console.log(error)
this.errored = true
});
},
addPerson: function (event) {
console.log('calling resource...');
this.buttons.add_to_queue_disabled = true;
this.buttons.add_to_queue_label = "Adding...";
axios.post(`/business/queue/add2`, this.$data.addPersonForm)
.then(response => {
console.log('got a response!');
console.log(response.data);
// this.updateData(); <- when I comment this line, the unresponsiveness lasts around 5-10 seconds.
})
.catch(error => {
console.log('some error happened :(')
this.buttons.add_to_queue_disabled = true;
this.buttons.add_to_queue_label = "Retry";
// $('#manual-add-people').modal('hide');
// console.log(error)
})
.finally(() => {
console.log('finished method');
this.buttons.add_to_queue_disabled = false;
this.buttons.add_to_queue_label = "Add to Queue";
$('#manual-add-people').modal('hide');
});
this.addPersonForm = {};
},
}
})
// PUSHER CODE
Pusher.logToConsole = true;
const pusher = new Pusher('{{ env('PUSHER_APP_KEY') }}', {
cluster: '{{ env('PUSHER_APP_CLUSTER') }}',
authEndpoint: '/broadcasting/auth',
auth: {
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}',
}
}
});
pusher.subscribe(`private-queue.business.{{ $business_id }}`)
.bind('App\\Events\\NewQueueMember', (data) => {
vm.updateData()
})
.bind('App\\Events\\QueueMemberKicked', (data) => {
vm.updateData()
})
.bind('App\\Events\\QueueMemberLeft', (data) => {
vm.updateData()
})
.bind('App\\Events\\QueueMemberNoShow', (data) => {
vm.updateData()
})
;
</script>
有问题的方法是提交表单时调用的addPerson。
如果我将其切换为空数组,我认为该问题与我对 this.$data.addPersonForm 的使用有关。
编辑:
这是从我的/business/queue/add2 端点返回的示例响应。
{guest_id: 55, queue_lane_id: 1, party_size: 2, short_id: "RIS0MRk0",…}
business: {id: 2, name: "Acme Ltd", business_type_id: 2, is_active: 1,…}
business_id: 2
created_at: "2020-09-27T23:53:11.000000Z"
customer: null
guest: {id: 55, name: "AJAX Test 29", phone_number: "+1234567890", business_id: 2,…}
guest_id: 55
id: 79
party_size: 2
queue_entry_time: "2020-09-28 00:53:11"
queue_lane_id: 1
short_id: "RIS0MRk0"
updated_at: "2020-09-27T23:53:11.000000Z"
这只是一个 JSON blob,其中包含他们刚刚创建的记录的详细信息,也不是很大。
我还更新了上面的 Vue 脚本,以反映我在 addPerson 下的 then() 函数中进行的附加方法调用。
【问题讨论】:
-
您是如何得出使用
this.$data.addPersonForm导致问题的结论的?您是否尝试使用模拟数据并检查页面是否仍然无响应?另外,如果您可以共享代码和框以查看有帮助的问题。 -
当我将该变量更改为空列表时,内存使用量不会激增。我很喜欢,今晚会更新问题。
-
你为什么用
this.$data.addPersonForm而不是this.addPersonForm?你能把调试器断点(或只是console.log)调用updateData吗?也许它被多次调用,并且 debounce-ish 方法可能会有所帮助 -
@DipenShah 我已经更新了帖子以包含更多信息,如果您需要更多信息,请告诉我。明天我将尝试在 codepen 上创建一个模型页面,因为它全部在本地构建,很难在线显示页面。
updateData方法或多或少与 mount 方法相同,所以我不确定它为什么会导致问题。 -
@DipenShah 请参阅上面的评论。我不认为它的推送事件订阅会导致问题,因为我尝试简单地注释掉所有订阅者事件以调用
updateData方法。似乎泄漏的大部分过程来自updateData。当我不在addPerson中调用此方法时,虽然仍然需要大约 2 秒的响应时间,但它比在.then函数中使用updateData()时页面无响应超过 5 秒的时间要短得多。
标签: javascript vue.js