javascript - 如何修复 vue.js/axios 应用程序中的内存泄漏?

标签 javascript vue.js

我有一个页面,它使用内联 vue.js 脚本显示表中的行列表,它在页面加载时获取行列表,但也会在收到推送事件时再次获取表。

我有一个模式窗口,可以打开并允许用户向表中添加新人员。当用户按下提交(在表单上)时,模式会发布一个 ajax 请求(使用 axios)来提交记录。这会向 Pusher 发送一个 App\Events\NewQueueMember 事件,我的 vue 应用程序也会监听该事件,当发生这种情况时,会调用 updateData 方法来刷新表。

我遇到的问题是,当提交表单时,页面在大约 5 秒内没有响应,然后才能再次在页面上滚动。查看 Chrome 任务管理器,我可以看到该选项卡的 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 脚本 block

<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 脚本,以反射(reflect)我在 addPerson 下的 then() 函数中进行的附加方法调用。

最佳答案

在 Chrome 开发工具中,打开“性能”选项卡,点击记录,重复导致速度变慢的问题,然后深入研究调用堆栈。 Vue 可能会让跟踪变得更加困惑,因为它编译了代码。在这种情况下,chrome“Vue 开发工具”可能会有所帮助。

仅通过查看代码,我还会向 updateData() 函数添加两个不同的计数器和记录器 - 记录最初调用它的次数,然后记录 axios 返回时的情况。如果函数导致问题时返回的数据不多,则推送器在返回之前可能会调用它太多次。您还可能会在开发工具的网络选项卡中看到这一点。

关于javascript - 如何修复 vue.js/axios 应用程序中的内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64056039/

相关文章:

javascript - 这个声明有什么作用? console.log.bind(控制台)

javascript - 提交时隐藏输入 (VUE)

javascript - $emit 内部异步方法 - Vue2

javascript - Vuejs中的单独数组推送

javascript - VueJS 动态属性名称不更新值

javascript - AngularJs - "deferred"或 "batched"指令

javascript - 如何添加:key in v-for with multiple divs

node.js - 部署Nuxt App后,baseURL是否仍为localhost?

javascript - 通过 css 悬停时的菜单项样式

javascript - BINANCE API - 如何使用用户数据流获取账户信息