Jump to content
Search Community

Updating a table

NickWoodward test
Moderator Tag

Recommended Posts

Hello! Sooo, I'm trying to work out how to best write a function to update data in my table.

From what I know, my best option (from a performance perspective), would be to create a Document Fragment or template string (say of the whole table or the tbody), and then insert it into the DOM in one go (minimising repaints/reflows).

But I feel like this limits, or at least slows what I can do from an animation perspective. For example, if I animate the rows out like this:

- animate current rows out

- remove the existing tbody or table

- insert the document fragment/html string containing the new tbody or table (with rows set to opacity: 0)

- animate the new rows in


^ means that I can't start the process of animating the new rows in until I've animated and removed the old rows. Which makes the animation feel a bit slow (all the data is already local so no need to wait for it to be retrieved)

Just wondering what approach people who've animated tables before would take?

Thanks!

PS: Also: Success! I came across my usual stumbling blocks (selecting elements before they're on screen, and immediate render) and fixed them straight away. Old dogs new trick my *%$£, it's only taken me a year :D

See the Pen qBKqOjJ?editors=1011 by nwoodward (@nwoodward) on CodePen

Link to comment
Share on other sites

Hi,

 

I would create a template for each table row, set the row's opacity to 0 and then, once the new data is in place, create a stagger animation. So basically:

  • Set up the event trigger (filter, API response, button click, etc.) to fade out the current data (animation one)
  • Once animation one is complete just remove the rows, no need IMHO to remove the table body, using another method (removeRows)
  • In the removeRows method add the new data or call another method to do that (addRows)
  • Once the new rows are added create the stagger animation using just a .to() instance. Setting opacity in your CSS won't cause any major issues when running the GSAP stagger instance.

The setup you have right now looks good enough for me, I would just not remove the table body and split things up in different methods in order to make it easier to maintain and follow, that's it.

 

Let us know if you have more questions.

 

Happy Tweening!

Link to comment
Share on other sites

Hi Rodrigo, thanks for the quick reply :)

Good to know that it looks roughly right! (I know I'll come across issues with rapid clicking, but Carl did a lesson on image sliders I need to go over again anyway!)

 

2 hours ago, Rodrigo said:

Once animation one is complete just remove the rows, no need IMHO to remove the table body, using another method (removeRows)


Ah, yeah, I did this so that there's only 1 insertion into the DOM, rather than 6 (or however many rows there are). I could well be wrong but I thought that improved performance by reducing repaints/reflows (although I think I also read that browsers now days also queue insertions if it can see there are multiple elements added in close proximity). I kind of stopped reading though because it seemed to be a massive rabbit hole!
 

  • Like 2
Link to comment
Share on other sites

13 minutes ago, NickWoodward said:

I know I'll come across issues with rapid clicking

You could try debouncing your event handler:

https://www.freecodecamp.org/news/javascript-debounce-example/

14 minutes ago, NickWoodward said:

I could well be wrong but I thought that improved performance by reducing repaints/reflows (although I think I also read that browsers now days also queue insertions if it can see there are multiple elements added in close proximity).

Mhh... yeah you got me there, I couldn't tell you about that, but you can use a performance audit in dev tools to find out and do a stress test, like 100 rows in one sitting. Although you can always minimize that using pagination, which is something most backend frameworks and ORMs have integrated out of the box these days. Even if you work with React or Vue, you can use React Query or Vue Query to minimize the effects and cache the results as well. I've used both and they're great (that's presuming that you're using either of those frameworks). It'd be nice if you could share that article in order to take a peek, it's always good to tumble down the rabbit hole :D

 

Happy Tweening!

  • Like 1
Link to comment
Share on other sites

Yeah, I'm probably fine tbh - I'd just come from watching a course where they attempted some unnecessary DOM update function (which compared every child element). Obviously pretty slow, so have probably been overthinking it.
 

23 minutes ago, Rodrigo said:

It'd be nice if you could share that article in order to take a peek, it's always good to tumble down the rabbit hole


Yeah, think I've found a couple, but it was a few days back!

On what triggers a reflow

 

This site seems particularly interesting:
image.thumb.png.718eeff7434dbdf6c7fe29af64de96a2.png


Another from the same site

Layout thrashing/innerText vs nodeValue vs textContent

Page 328 (chapter 12) of Secrets of the JavaScript Ninja (2nd ed) also seems very good. It's got a great section on a map to make sure that all DOM insertions are wrapped in their needed semantic elements


... yeah, it was a long rabbit hole. And I'm still not sure I really know :D

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

Thank you so much for sharing those resources!

 

I'll bookmark this thread in order to point other users to it so they can benefit from all this knowledge 🥳

 

Thanks to generous users like you this community grows every day and becomes even better 💚

 

Happy Tweening!

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...