I am using a later version of the gridpro-generator from the repo you mention and I wanted to test the response of a much loaded GridPro using many rows and many columns with different components for direct editing, we are warned about this by Vaadin.
So I have made some tests using multiple levels of one-to-many relations to get an idea of how it performs and the grid actually handles very well with many rows, at least on my dev pc.
Then comes the loading issue and you are right, we must avoid blocking the UI and when loading 10000 rows it becomes worse than noticeable, so I wanted to improve the code of the gridpro-generator for at better UX and to make a general solution.
The test code is in a local repo since I have a PostgreSQL database running to make it realistic and the gridpro-generator has some changes to it.
In here I was just looking for a simple UI/UX update to the grid and I donāt want to steal the thread.
Sure pagination is called for in many cases, but I wanted to stress the code and make the progress bar very obvious.
Yes, you need a pro subscription for GridPro.
Sure, I will move it to a public repo, just give me a little time.
I have updated the repo at
It now has a āLoad and Performance testā menu that contains some code for testing performance on large sets of rows. It uses a H2 memory db and starts by generating the schema and the dummy rows for Companies. Further dummy data can be generated and especially it is possible to add 10000 items to an employee in a one-to-many relation.
I think your post could be moved to the Vaadin Flow section better.
Iām having trouble generating the licency version to use the GridPro
This is a pretty neat example too lazy-component but you have to adapt it to you, since you first do a load on line 200 of the TenantCompanyView class, then when you invoke the Gridās setItems to fill it is another point to keep in mind.
progressBar.setIndeterminate(true);
progressBar.setWidthFull();
progressBar.setVisible(false);
genItems10000Button.addClickListener(evt -> {
Faker faker = new Faker();
Random rand = new Random();
ApplicationUser applicationUser = ServiceAccessPoint.getServiceAccessPointInstance().getTenantDepartmentEmployeeRepository().findById(applicatioUserIdField.getValue()).orElse(null);
if (applicationUser != null) {
var singleThread = Executors.newVirtualThreadPerTaskExecutor();
CompletableFuture.supplyAsync(() -> {
System.out.println("Generating items ...");
this.execute(() -> {
Notification.show("Generating items ...");
progressBar.setVisible(true);
});
final List<Item> list = new CopyOnWriteArrayList<>();
for (int i = 0; i < 10000; i++) {
list.add(createItem(faker, applicationUser));
}
return list;
}, singleThread)
.whenCompleteAsync((data, throwable) -> {
this.execute(() -> {
data.forEach(item -> ServiceAccessPoint.getServiceAccessPointInstance().getItemRepository().save(item));
Notification.show("Finished generating items {size}: " + data.size());
System.out.println("Finished generating items");
progressBar.setVisible(false);
});
}, singleThread);
} else {
StandardNotifications.showTempWarningNotification("No user found with id: " + applicatioUserIdField.getValue());
}
});
}
private void execute(Command command) {
super.getUI().ifPresent(ui -> ui.access(command));
}
As I said, I have not been able to test it, but it fits and thatās itā¦