-2
\$\begingroup\$

My problem is this causes more lag as time goes on. I use this commonly to chat with my friends, and I need it the site to update in real-time whenever a message gets edited/deleted/added. Any solutions?

function update(){
    var i = 0;
    var leadsRef = firebase.database().ref(room);
    leadsRef.on('value', function(snapshot) {
        var old_room = room;
        snapshot.forEach(function(childSnapshot) {
            var childData = childSnapshot.val();
            if(i === 0){
                document.getElementById("comments").innerHTML = "";
            }
            document.getElementById("comments").innerHTML += encode(childData.datee);
            document.getElementById("comments").innerHTML += "      ";
            document.getElementById("comments").innerHTML += encode(childData.namee);
            document.getElementById("comments").innerHTML += ": ";
            document.getElementById("comments").innerHTML += encode(childData.contentss);
            document.getElementById("comments").innerHTML += "<br>";
            i += 1
        }); i = 0; return 0;
    });
}
window.setInterval(update, 100);

The full code can be found here.

\$\endgroup\$
  • 2
    \$\begingroup\$ What do you mean by "I need it to be real-time."? \$\endgroup\$ – guest271314 Jan 3 at 17:59
  • \$\begingroup\$ @guest271314 As in the site should update in real-time when somebody types in a message \$\endgroup\$ – MilkyWay90 Jan 3 at 18:02
  • 1
    \$\begingroup\$ @MilkyWay90 That would be a practical first step. You could ask on SO, though you would still be in the position of clearly not knowing what your own code is doing, nor precisely what the expected result is. \$\endgroup\$ – guest271314 Jan 3 at 18:31
  • 1
    \$\begingroup\$ @MilkyWay90 Any and all code relevant to the problem should be embedded in the question, linking off-site is not permitted, as described in the help-center: codereview.stackexchange.com/help/on-topic. Additionally, you should fully understand what the code does, and it sounds like you may not, though I'm going to give you the benefit of the doubt and assume you do. \$\endgroup\$ – 410_Gone Jan 3 at 18:31
  • 2
    \$\begingroup\$ Additionally, the root of your problem is the += and constant reloading of all messages, you need to find a way to track what the "last" message was and only load "new" messages, that will be the first step towards success. \$\endgroup\$ – 410_Gone Jan 3 at 18:34
1
\$\begingroup\$

1. Leaking

Between:

window.setInterval(update, 100);

And:

leadsRef.on('value', function(snapshot) {...}

You are adding a new copy of the event handler every 100ms. which just stacks the handle so it runs (time elapsed since page load)/100ms times every time data hits the pipe.

Setting your on('value') handler should fire every time firebase get new data. It's a watcher you've got here not a getter.

2. Redundant Look ups

document.getElementById("comments")

This can be held in a variable and reused rather than finding the element for every stub of text.

3. innerHTML

Setting innerHTML from user input is considered bad practice, use innerText instead. Also build you full string(if possible) and and update all at once, this limits the browser having to re-render the page

4. Data / Output Structure

Each message is an individual item and should be treated as such, showing all the messages into a single p element muddies the distinction and make addressing an individual item difficult if desired

Other/Misc

You should be able to replace the provided code with somthing like this (warning untested, also assumes comments is a div not a p as in the linked code):

firebase.database().ref(room).on('value', function (snapshot) {
    var comments = [];
    var commentParent = document.getElementById("comments")
    snapshot.forEach(function (childSnapshot) {
        var childData = childSnapshot.val();
        var commentElm = document.createElement("div");
        commentElm.setAttribute("class", "comment")
        commentElm.innerText = encode(childData.datee) + "      " + encode(childData.namee) + ": " + encode(childData.contentss);
        comments.push(commentElm)
    });
    commentParent.innerHTML=''
    commentParent.append(...comments)
    return 0;
});

Also there is an additional bug with room handling, when changing rooms the handler should be removed and recreated for the new room.

And your linked code pollutes all over the global space >.> not as important since it's not a shared lib but it still rubs me the wrong way.

jsfiddle: https://jsfiddle.net/plloi/fc37pmqa/

\$\endgroup\$
  • \$\begingroup\$ Keeps on outputting "[object HTMLDivElement]," \$\endgroup\$ – MilkyWay90 Jan 3 at 19:49
  • \$\begingroup\$ Missed a spread operator, updated \$\endgroup\$ – Shaun H Jan 3 at 19:53
  • \$\begingroup\$ Okay, let me test it \$\endgroup\$ – MilkyWay90 Jan 3 at 19:53
  • \$\begingroup\$ Okay, that issue is resolved, but now it keeps on outputting the entire script every second \$\endgroup\$ – MilkyWay90 Jan 3 at 19:56
  • \$\begingroup\$ Like if it said "MW90: hi", it would keep on outputting "MW90: hi" every second. Wait, that just can be fixed by setting document.getElementById("comments") to [] \$\endgroup\$ – MilkyWay90 Jan 3 at 19:56

Not the answer you're looking for? Browse other questions tagged or ask your own question.