Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Repeatable group performance for lots of fields #171

Open
engram-design opened this issue Jul 10, 2020 · 7 comments
Open

Repeatable group performance for lots of fields #171

engram-design opened this issue Jul 10, 2020 · 7 comments
Labels
performance Improve the speed and perofrmance.
Projects
Milestone

Comments

@engram-design
Copy link

Not really a new feature, but also not a bug! I'm having some performance issues with a repeatable field, and I've put together an example Codepen to illustrate it:

https://codepen.io/crawf/pen/qBbKEBJ

I've put a tiny delay on a loaded property so that you can see the form load and render, then see a visible delay of a few seconds until the list renders 50 x 4 input components.

Note that its intentionally large to illustrate my point. I'm using a schema, but just to test that's not a factor, here's a pen with normal components: https://codepen.io/crawf/pen/BajVNJx with much the same result.

In contrast to this same example with plain inputs - obviously a whole lot less overhead, so it might not be a fair comparison - https://codepen.io/crawf/pen/VwedLbm

Wondering if there's anything that can be done, or if it's just the reality of the situation?

@engram-design engram-design added the feature request New feature or request label Jul 10, 2020
@justin-schroeder
Copy link
Member

Thanks for the good report. This is something I was aware of, but haven't spent the time to take a crack at the problem. The crux of the issue is reference types in Vue (of which arrays are, and groups are modeled to an array) generally cause Vue to re-evaluate all of it's computed props and watchers, there are some clever ways around this though like property comparison, which we use in a few places in Vue Formulate for performance reasons, but this logic has not yet been applied to groups (partly because it seemed a bit like an edge case to have this many items) — but its 100% something we need to try and fix.

The TLDR on that is that editing one field in a group causes all inputs in the group (group_inputs*n) to re-evaluate. If you’re interested in tackling the problem feel free to take a crack at it 👍

@justin-schroeder justin-schroeder added performance Improve the speed and perofrmance. and removed feature request New feature or request labels Jul 10, 2020
@engram-design
Copy link
Author

@justin-schroeder I figured it was low on the list, its hardly an issue for 90% of people. We just have a rather large questionnaire type form, which is more or less the same as the codepen, with 4-5 fields per row.

I'll do my best to dive in and see what I can figure out! I know items get a __id private property set, is is a good idea to rely on that?

@justin-schroeder
Copy link
Member

Yeah, since array values don't have their own keys, we assign a Symbol since it's a reference type to each array item in a group. It shouldn't ever change so it's the best way to reference individual ones.

However, I think the issue is in the way the group handles mutations. Each group "row" is basically it's own mini form with a registry and that logic needs to be fine-tuned to not cause the parent model to have a new reference when it's updated (unless we're adding/removing a row).

@justin-schroeder justin-schroeder added this to 2.x.x in Roadmap Jul 11, 2020
@engram-design
Copy link
Author

@justin-schroeder I've spent some time trying to get my head about the internals of the registry, and its certainly something going on there with the computed properties. Removing them seems to make it significantly quicker, but obviously there's the behaviour lost.

It's probably a bit too much for me to handle at the moment, and my lack of knowledge/skill to be of any useful help. For the moment, I'm using regular inputs in the inner fields, which probably isn't a bad idea anyway. It's just a pain to deal with validation, as it has to be done at the group level (which I have a custom input for).

I'll see how things progress!

@justin-schroeder
Copy link
Member

There are some significant architecture changes that would be required to significantly improve the performance of large groups that would require breaking changes to the API contracts already in place. For now I'd consider groups a great tool for small/medium size lists and not appropriate for large lists. In version 3, since we have the opportunity to implement breaking changes, we'll tackle those underlying changes to try and make groups high performance even at large scale. For now i'm making this a 3.x task.

@justin-schroeder justin-schroeder moved this from 2.5.0 to 3.0.0 in Roadmap Jan 13, 2021
@justin-schroeder justin-schroeder modified the milestones: 2.5.0, 3.0.0 Jan 13, 2021
@JackEdwardLyons
Copy link

Hi @justin-schroeder I really love using Vue Formulate and don't want to switch. I too have this problem with repeatable fields and have tried adding debounce but there are issues when pre-populating the form where the values inside repeaters sometimes don't populate.

Before getting to the Vue 3 release, is there a workaround for Vue 2 that I can implement to just get by?
@engram-design have you found a solution?

Thanks again

@engram-design
Copy link
Author

@JackEdwardLyons I actually can't quite recall how I solved this! I think I ended up using plain input elements in the rows, as Formulate couldn't handle things.

The code in question was for a table field. You can have a look at the code here - https://github.com/verbb/formie/tree/craft-3/src/web/assets/forms/src/js/components/formulate/table. It was for a Craft CMS plugin, so it wouldn't be the easiest to spin up again on your end to see how it all works, but there might be some useful bits in there.

The end result was something like this:
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance Improve the speed and perofrmance.
Projects
Roadmap
FormKit
Development

No branches or pull requests

3 participants