-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\$
17
  • 2
    \$\begingroup\$ What do you mean by "I need it to be real-time."? \$\endgroup\$ Commented Jan 3, 2019 at 17:59
  • \$\begingroup\$ @guest271314 As in the site should update in real-time when somebody types in a message \$\endgroup\$ Commented Jan 3, 2019 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\$ Commented Jan 3, 2019 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\$ Commented Jan 3, 2019 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\$ Commented Jan 3, 2019 at 18:34

1 Answer 1

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\$
6
  • \$\begingroup\$ Keeps on outputting "[object HTMLDivElement]," \$\endgroup\$ Commented Jan 3, 2019 at 19:49
  • \$\begingroup\$ Missed a spread operator, updated \$\endgroup\$ Commented Jan 3, 2019 at 19:53
  • \$\begingroup\$ Okay, let me test it \$\endgroup\$ Commented Jan 3, 2019 at 19:53
  • \$\begingroup\$ Okay, that issue is resolved, but now it keeps on outputting the entire script every second \$\endgroup\$ Commented Jan 3, 2019 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\$ Commented Jan 3, 2019 at 19:56

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.