Hi All,
I am experiencing issues with the lazy load behavior in a Table widget. When scrolling down, the table should fetch more data and adjust the scroll position, but it is currently failing or lagging.
My OnAfterFetch logic currently includes a loop to manage checkbox selections and calls two additional Aggregates. I suspect this heavy logic is blocking the UI thread and breaking the lazy load. Does anyone have a recommended pattern for handling complex OnAfterFetch logic without breaking table virtualization and there is no outsystems forge component to handle the lazyload any suggestion on this?
Thanks,Prasath P
Can u share your logic flow, because your current question is quite vague.
Hello,
Here is what I understood: you have an aggregate with hundreds of records, and it can’t handle loading all of them at once. Because of that, you implemented lazy loading, for example loading 20 records at a time while scrolling, with a spinner that loads the next batch. On top of that, you have two additional aggregates that are fetched when a checkbox is selected from the records in the first aggregate.
I’d say if this were a mobile app, lazy loading would already be implemented and handled by the InfiniteScroll action, so this scenario is most likely a web app.
In my opinion, if I were you, I would consider using pagination, which is already built and well-optimized for web applications. As you mentioned, there is a lot of backend overhead here due to two main things: the load of the first aggregate and the fact that selecting a checkbox triggers two more aggregates. With this setup, you will almost certainly experience some latency, and if the load increases, you might even run into timeouts.
Another point to consider, if it’s possible based on the relationships between your tables, is to incorporate those two additional aggregates into the first one. You could do this using joins (based on the checkbox selection or a related foreign key), combining everything into a single aggregate. This approach would reduce multiple server-side calls and generally perform better.
If none of the above matches your scenario, you could share the OML as Huy mentioned of course only if you’re okay with sharing it.
@Prasath P : The lag is likely due to chained refreshes of screen aggregates in OnAfterFetch. Screen Aggregates load asynchronously the first time, but subsequent refreshes run sequentially, increasing total load time. You can reduce this by refreshing aggregates in parallel using JavaScript:https://phoenix-dx.com/refresh-aggregates-parallel-javascript-outsystems/
Lazy load issues in OutSystems tables are usually caused by heavy logic in OnAfterFetch. In Reactive Web Apps, OnAfterFetch runs on the UI thread and is tightly coupled with table virtualization. When we add loops, checkbox recalculation for all rows, or call additional Aggregates from OnAfterFetch, the UI thread gets blocked. As a result, the table cannot stabilize the scroll position, which leads to lag, repeated fetches, or broken lazy loading behavior.
The recommended pattern is to keep OnAfterFetch extremely lightweight—only update pagination flags or offsets and avoid any server calls or full-list processing. Checkbox selection logic should be handled independently using an ID-based selection list or map, so selection state is calculated per row instead of recalculated for the entire dataset on every fetch.
If additional data is required, it should either be included in the main Aggregate upfront or fetched separately after the UI has stabilized (for example, via a short-delay Timer). Heavy business logic and post-processing should always be moved to the server side or deferred outside of OnAfterFetch. This approach preserves table virtualization, prevents UI blocking, and ensures smooth lazy loading.Hope this helps
Unfortunately, no forge for this lazy loading table yet.
I have worked on the infinitive scroll on web before. I need to use JavaScript to handle the scroll to end to fire the event.
In this case, you should use local variable to hold the data:
because it is just to append more and more data to the existing list, no need the logic to reinitialize the checkbox.
Hope this help.