Vaadin 14. CallbackDataProvider. When service is slow and answer time is long then Grid connected to CallbackDataProvider is freezes with all UI. Some example:
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.data.provider.CallbackDataProvider;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.router.RouteAlias;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.*;
public class GridWithSortableColumnsView extends VerticalLayout {
public GridWithSortableColumnsView() {
addClassName("dialogwithgrid-view");
setSizeFull();
// prepare Data
List<GridRow> gridRows = new LinkedList<>();
for (int i = 0; i < 10000; i++) {
gridRows.add(new GridRow(i, RandomStringUtils.randomAlphanumeric(10)));
}
CallbackDataProvider<GridRow, Void> dataProvider = new CallbackDataProvider<>(
query -> {
// Slow service answer is here
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Notification.show("Offset=" + query.getOffset() + " Limit=" + query.getLimit());
return gridRows.stream()
.sorted((o1, o2) -> StringUtils.compare(o1.getCol05(), o2.getCol05()))
.skip(query.getOffset())
.limit(query.getLimit());
},
query -> gridRows.size());
Grid<GridRow> grid = new Grid<>();
grid.setPageSize(10);
grid.setSizeFull();
grid.addColumn(GridRow::getId).setHeader("Id");
grid.addColumn(GridRow::getCol05).setHeader("col05");
grid.setDataProvider(dataProvider);
add(grid);
}
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@AllArgsConstructor
@Getter
@Setter
public static class GridRow {
@EqualsAndHashCode.Include
private int id;
private String col05;
}
}
Session locked and all UI components freezes while scrolling this Grid. How it can be more faster and async? I think about caching inside own DataProvider extends CallbackDataProvider, but it will filled after the Grid receive empty data on first request and may be used only after some time with refreshing DataProvider again. It is not useful for me. In my real project fetched data changes frequently and has amount of items, up to 100000 items for one Grid, so i need to use CallbackDataProvider with limited request size.