Tips for solving memory leaks in my vue.js / axios application?

I am facing an issue with a single page that displays rows from a table using inline vue.js script. The page fetches the list of rows on load and also fetches the table again when pusher events are received.

Additionally, there is a modal window that allows users to add new people to the table. When the user submits the form in the modal, an ajax request is made (using axios) to submit the record. This triggers an App\Events\NewQueueMember event to Pusher which my vue app listens for, and upon receiving this event, the updateData method is called to refresh the table.

The problem arises when the form is submitted, causing the page to become unresponsive for around 5 seconds before normal scrolling functions resume. In Chrome's Task manager, I noticed a significant increase in RAM usage and CPU consumption during this period.

I suspect there might be a memory leak issue, but I'm unsure how to tackle it. Any guidance would be greatly appreciated.

This is the form within the modal:

@csrf Customer Name Name will be displayed internally and to the customer
<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>

This is the vue.js script block on the same page:

<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);
                    })
                    .catch(error => {
                        console.error('error occurred :(')
                    })
                    .finally(() => {
                        console.log('method completed');
                        this.buttons.add_to_queue_disabled = false;
                        this.buttons.add_to_queue_label = "Add to Queue";
                    });

                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>

The problematic method is addPerson, triggered upon form submission. Upon switching this.$data.addPersonForm to an empty array, the unresponsiveness duration decreases significantly.

EDIT: This is a sample response obtained from my /business/queue/add2 endpoint:

{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"

The JSON response contains details of the created record and is not excessively large.

The above Vue script has been updated to reflect the additional method call within the then() function under addPerson.

Answer №1

To investigate the performance issue in your code, navigate to the "performance" tab within Chrome dev tools. Start recording, replicate the problem causing slow performance, and analyze the call stack for insights. Keep in mind that tracing Vue code may be a bit trickier due to compilation processes. Consider leveraging the "Vue dev tools" extension for assistance.

In addition, consider implementing two separate counters and loggers within the updateData() function. Monitor how many times the function is initially called and track when axios returns data. If you notice minimal data being fetched while the function is impacting performance, it's possible that the function is being invoked excessively before receiving results. Review the network activity within the dev tools' network tab for further investigation.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Creating dynamic captions in an Angular grid is an essential feature for enhancing the

Is there a way in Angular to dynamically update the grid titles based on an array of elements in the model? How can I display them as captions? For instance, imagine we are currently in week 202010. I would like to automatically generate the next five wee ...

What could be causing my AngularJs routing and animation to bypass the second redirection?

Recently started working with Angular and experimenting with routing and animations to manage my page transitions. I followed a helpful guide that helped me set everything up. I encountered a few issues: When trying to link back to the landing page (home ...

What could be causing the appearance of a mysterious grey box hovering in the upper left portion of my image and why is the code only adjusting the size of the grey box instead of the entire

I've been working on embedding some JavaScript into my Showit website to create a drag-and-drop feature that displays a collage/mood board effect. Everything is functioning correctly, but I'm running into issues with resizing the images. There&a ...

ThymeLeaf fails to display the elements of a List

I am struggling with a complex HTML structure in my project. The HTML code includes a mix of Bootstrap classes and Thymeleaf attributes. Additionally, there is a JavaScript function that interacts with radio buttons to show or hide elements based on user i ...

What are the reasons for the slower runtime of node.js compared to the Google Chrome console

It's interesting to note that both Chrome and node.js operate on the same V8 javascript engine. Here is my take on it: Chrome, despite running internal executions, also handles additional UI tasks which could potentially slow it down On the other ha ...

JSON Novice - persistently storing data in JSON during browser refreshes

My AJAX poll was set up following a guide found here: http://www.w3schools.com/php/php_ajax_poll.asp Instead of storing the poll entries from an HTML radio button in an array within a text file as demonstrated in the tutorial, I wanted to save them in a J ...

Find the elements of <a> tags specifically without the attribute href

Currently, I am extracting the class of all <a> elements in an HTML document of a webpage using VB.net from a WinForm: Dim htmlLinks As HtmlElementCollection = WebBrowser1.Document.GetElementsByTagName("a") For Each link As HtmlElement In htmlLi ...

JavaScript: Incorporating an operator into a specific object (instead of the entire class)

Are you familiar with how to include an operator in an object (rather than the entire class)? When it comes to a method, I know you can achieve that by: my_object.new_function = function(){return 1}; Then invoking my_object.new_function() will output ...

What could be the reason behind the absence of this.props.onLayout in my React Native component?

In my React Native app, I have the below class implemented with Typescript: class Component1 extends React.Component<IntroProps, {}> { constructor(props){ super(props) console.log(props.onLayout) } ... } The documentation for the View ...

Code needed to efficiently include a d3 module through webpack

Having some trouble importing and using a d3 module in my webpack project. The function I need from the module is declared like so: https://github.com/d3/d3-plugins/blob/master/hive/hive.js d3.hive.link = function() { I attempted to follow this guide to ...

Bidirectional Data Binding Using Meteor and React

When using Meteor, the getMeteorData() method is preferred over getInitialState(). But how can we achieve binding, especially with regards to a user's surname in their profile? ... getMeteorData() { return { u = Meteor.user() } }, componentRen ...

Sorting dates in Vue JS can be achieved effortlessly by utilizing components and Computed Properties

I attempted to arrange the dates using computed properties but encountered issues. However, when I utilized methods and removed the slice method, the sorting worked as expected. I also tried splitting the date without success. The root cause of the problem ...

Utilizing Conditional Styling for an Array of Objects within a Textarea in Angular 6

My array contains objects structured as follows: list =[ { name:"name1", value:true } { name:"name2", value:false } { name:"name3", value:true } { name:"name4", value:false ...

`Weaving mesh into place with three.js`

I'm struggling to grasp how to position my cubes on the canvas. I can't quite figure out how positioning actually works. I'm trying to find a way to determine if my mesh reaches the limits of the canvas. But what exactly is the unit of posit ...

Rails 3.2 - form mistakenly submitted repeatedly

I am working on a project involving the Box model, which includes many box_videos. I have created an edit form to allow users to add box_videos to the box after it has been created: <%= form_tag "/box_videos", { method: :post, id: "new_box_videos", rem ...

What is the best way to delete information from a database with the help of Redux

Lately, I've been grappling with the task of integrating redux into my project. Successfully posting data to the database using redux and then retrieving it in react was a win, but now I find myself struggling with how to handle deleting data through ...

NodeJs: Transforming strings into UUID v4 efficiently

Suppose I have the following string: const input = '83e54feeeb444c7484b3c7a81b5ba2fd'; I want to transform it into a UUID v4 format as shown below: 83e54fee-eb44-4c74-84b3-c7a81b5ba2fd My current approach involves using a custom function: funct ...

"Inserting" a fresh key-value pair into a JavaScript Object

I know that with arrays, only array elements can be added using the .push() method. My goal is to achieve a similar functionality for objects. I am familiar with both dot and bracket notation, so this is not a basic question for me. However, I need to do ...

React-Bootstrap Popup encounters overlay failure

While using the Tooltip without an OverlayTrigger, I encountered the following error: webpack-internal:///133:33 Warning: Failed prop type: The prop overlay is marked as required in Tooltip, but its value is undefined. The code snippet causing the issu ...

Unable to make changes while state transition is in progress

I want to update the state value based on the result of a promise method. To have optimistic updates, I set the state value before an asynchronous operation. If the operation fails, the state is reset. componentWillMount(){ this.setState({notify: this ...