Details
-
Type: New Feature
-
Status: Closed
-
Priority: Major
-
Resolution: Fixed
-
Affects Version/s: None
-
Fix Version/s: 4.1
-
Component/s: ACE-Components
-
Labels:None
-
Environment:ICEfaces 3.x, ace:dataTable
-
Support Case References:Support Case #12726 - https://icesoft.my.salesforce.com/5007000000adNJU
-
Affects:Documentation (User Guide, Ref. Guide, etc.), Sample App./Tutorial
Description
This JIRA is to re-introduce support for a liveScroll functionality in a robust manner that will support its use in combination with all other ace:dataTable features.
The primary justification for a liveScroll feature is to provide "infinite" scalability to ace:dataTables that may be bound to very large datasets (e.g. 50K rows or much more).
To achieve this, it is necessary to dynamically "page" rows to the client browser as the user moves through the dataTable contents via the vertical scrollbar. Not only do rows need to be dynamically loaded or pre-loaded for the user, but rows must eventually also be dynamically removed from the browser DOM in order to prevent the eventual negative performance implications of an very large DOM in the browser, and the memory consumption that goes along with it.
-
- group.PNG
- 13 kB
-
- LiveScrolling.PNG
- 48 kB
Issue Links
- blocks
-
ICE-7476 DataTable: Live scrolling incompatible with lazy loading
- Closed
Activity
- All
- Comments
- History
- Activity
- Remote Attachments
- Subversion
Is it planned for 4.0 Final?
Committed initial version of robust live scrolling functionality at revision 45892.
Committed initial version of live scrolling test to QA's ace:dataTable test app at revision 42852.
The current functionality loads a number of rows when reaching the bottom of the scollbar. The rows correspond to the next page in the sequence as well as ${liveScrollBufferPages} before and after the main page. In other words, upon reaching the end of the vertical scroll bar, the next page is loaded as well as the ${liveScrollBufferPages} pages following it, and ${liveScrollBufferPages} pages are removed from the top. This is all done via the regular JSF updates and not custom updates. The size of the pages is determined by the 'rows' attribute.
In the test page just committed, the paginator is enabled as well to show that the two features work together seamlessly. The liveScroll feature can also work without the paginator. The only requirement at the moment is that the 'scroll' attribute is enabled as well and 'rows' is greater than 0.
Once the dataTable test app is deployed, the test can be accessed through the following URL:
http://localhost:8080/dataTable/views/liveScrollTest.jsf
r45901: committed improvement for smooth scrolling
r45907: added live scrolling functionality for going up (exclusively up)
r45908: fix to remove top margin when reaching the top and to remove bottom margin when reaching the bottom
r45912: committed improvement to make both live scrolling functionalities (downwards and upwards) work together.
r45915: replaced approach of adding margins to the top and bottom of the body table for directly moving the scrollbar handle to an appropriate position to account for the newly-added rows; added usability improvements like moving the scrollbar one pixel from the top to enable upwards scrolling right away and adding filler space to enable the scrollbar when the height of the rows is less than the height of the scrollable container.
Scrolling down seems to be working fairly well on OS X, Windows, and iOS devices. One issue that I've seen is that if you are viewing 3 pages at a time, and there are only 5 pages, when you scroll down to view the next 3 pages, there are only 2, and there seems to one "page" of blank content loaded where it should just end at the last available row.
Scrolling up is when things get wonky quickly. Typically after scrolling down a few pages and then back up, the scroll bar will dance around a bit, sometimes no rows will be rendered, etc. Easy to reproduce.
I also added liveScroll as per the following parameters to various dataTable showcase demos and noted the following issues:
rows="5" scrollable="true" liveScroll="true" scrollHeight="100"
- cellEditor - clicking the checkmark to enter editing mode fails after the first liveScroll pagination is triggered.
- columnGroup - row expansion stops working after the first liveScroll pagination is triggered.
FYI: I've updated the dataTable/views/liveScrollTest.xhtml page to increase the scrollHeight so it is easier to see the scrolling behaviour in response to clicks inside the scrollbar.
r45939: fix for exception when trying to scroll up while on the first page.
r45947: fix to make the component iterate over the buffer rows as well, in order to execute requests for row/cell editing and row expansions.
r45956: refactored fix to iterate over buffer rows to make it more efficient; added a delay in between livescroll requests in order to avoid multiple, repeated requests with short intervals; fixed issues when liveScrollBufferPages=0; fixed issue with flickering between pages when scrolling up; added fix to avoid processing an upwards livescroll request when being on the first page already.
Note that the delay fix will only be noticeable on IE and FF, since in those browsers it's possible to keep pressed the down arrow button of the scrollbar and continue triggering the scroll event in the client, while in Chrome no new scroll event is triggered.
Note that the delay fix will only be noticeable on IE and FF, since in those browsers it's possible to keep pressed the down arrow button of the scrollbar and continue triggering the scroll event in the client, while in Chrome no new scroll event is triggered.
Actually, I'm finding that there is still an issue with the frequency of the auto scroll down/up on all browsers. If you drag the scrollbar slider to the bottom and hold it there it will trigger a single pgdn and stop. However, if you keep dragging and move the mouse back and forth at the bottom, it will rapid-fire many pgdns in a row. We will need to trap these events and delay 750 millis between them to slow things down, otherwise you can inadvertently jump ahead many pages very quickly without realizing what is happening.
Liana reports:
/liveScrollTest.jsf
IF4 trunk r45959 - When scrolling down on the last page in the dataTable the scrolling does not stop at row 999. Instead the page scrolls back up to row 970 then down to row 999, repeatedly, (slightly different behaviour with IE and FF, versus Chrome). In all browsers the last 20 rows in the table can not be displayed because of the scroll bar movement to the top of the page.
When using liveScrollBufferPages="0", the issue does not occur in FF or Chrome but still does with IE11.To reproduce:
use /liveScrollTest.jsf
Use the paginator to get to page 100.
Scroll down to view row 999.
Release scroll, page moves back to top and displays row 970 to 978.
r45964: fix to avoid processing downwards live scroll when the last row is already showing.
I had noticed the issue reported by Liana, and this fixes that issue.
I'm still working on some usability issues when using low values for buffer pages, rows per page and scrollHeight. The live scrolling functionality simply works best when these values are normal or larger, but there are some cases that need to be covered like when the total height of all the rows displayed is less than the scroll height of the container.
r45974: fix to prevent flickering when live scrolling up and the scrollHeight is higher than the height of a single page; changed the way the first page is rendered to include twice the number of buffer pages under it, so to keep the number of pages rendered at a time constant and to avoid having whitespace below the rows when the height of the first page plus the height of the buffer page(s) below it is less than that of the scrolling container.
r45978: increased delays in processing scroll events in the client and in sending live scrolling requests.
There are two different delays at play. One of them is the delay to process the 'scroll' event handler in the client side, which takes care of various scrolling matters besides live scrolling. The other delay is for sending live scrolling requests. So, the first delay has to be short enough, so that non-continuous live scrolling requests feel responsive, and the second delay has to be long enough to prevent several live scrolling requests in a short amount of time. However, if this second delay is too long, it prevents altogether being able to hold the scrollbar buttons or handle to continuously scroll along the table. So, I modified these delays from 200 ms each to 450 ms for the first one and 300 ms for the second one, which seem to be reasonable values for all use cases.
Note: this time of continuous scrolling is easier to test when there are 0 buffer pages and few rows per page, whose combined heights is slightly greater than the scroll height of the table.
Tested with ICEfaces 4 trunk r45978.
1.) When using the liveScroll attribute in a dataTable that uses grouping no data content cells are loaded. This issue occurs no matter what value the liveScrollBufferPage is set to. To reproduce, add liveScroll="true" liveScrollBufferPages="1" to the dataTable in the showcase ace:dataTable > Grouping demo. See screen shot group.png
2.) When using liveScroll attribute in a dataTable that uses row or panel expansion there is a noticeable performance issue while scrolling. Scroll action is not smooth throughout the length of the scroll bar.
Added additional liveScroll scenario QA test apps to:
http://dev.icesoft.com/svn/repo/qa/trunk/Regression-Icefaces4/Sparkle/Nightly/dataTable.
These apps can be found in the Unscripted Tests section.
r46003: fix to preserve the behaviour of displaying all rows when rows="0" when liveScroll="true" as well.
This fix solves the issue #1 above. It wasn't exclusive to the grouping demo, but it happened whenever the rows attribute wasn't specified. Note that for liveScroll to work, a specific rows attribute must be set, as described in the TLD documentation.
r46007: fix to include the heights of panel expansion, row expansion and conditional rows when calculating the position of the scrollbar handle.
This solves the smoothness issue (#2) above.
I couldn't see the performance issue mentioned. Is there a specific combination of attributes, browsers and operating systems where it's more visible?
Verified Issues 1 and 2, ICEfaces 4 trunk r46007. IE 11, FF 34, Chrome 45.
As for the performance issue, this occurs when the rows attribute is set to a higher number such as 10. As an example I added the following to the ace:dataTable > Panel Expansion demo page - rows="10" liveScroll="true" scrollable="true". Does not seem to be an issue in Chrome but choppy scrolling was noticed when testing with IE and FF.
Tested with ICEfaces 4 trunk r46073. An issue has been found that when the last page in the table has a single row, navigating to that page will succeed but will then be redirected back a page or 2. The QA /liveScroll1.jsf test case has been set up to demonstrate this issue. Note liveScrollBufferPages="0".
http://dev.icesoft.com/svn/repo/qa/trunk/Regression-Icefaces4/Sparkle/Nightly/dataTable/web/views
To reproduce:
Load the views/liveScroll1.jsf demo in any browser
Use the last page link on the paginator.
You will be directed to the last page which has only 1 row of data.
You may immediately be redirected back a page or 2.
If not, choose a lower page on the paginator, then the last page again. The page will be moved back.
r46108: fix to add the filler space before scrolling down programmatically, so it's actually possible to scroll down 1 pixel and prevent moving to the previous page, since in the case when a page has few rows there's not enough room to do the programmatic scrolling for preventing moving immediately to the previous page just after loading a page.
This fixes the issue in the comment above.
As for the performance issue with panel expansion and livescrolling, the scrolling is not so bad. It's just not speedy, but not frustratingly slow. It only seems to be noticeable when using the arrow buttons and not when dragging the handle. The reason it's slower is because of all the calculations that need to be done for livescrolling and because of the increased complexity of having more nodes in the table. It depends on the efficiency of the browser how fast these calculations are made. Trying to optimize this use case would require making big changes to the code we already have and it would take a substantial amount of time, while risking causing more regressions. Since the benefit wouldn't be very noticeable, we'll just leave things as they are.
Tested with ICEfaces 4 trunk r46108. The "last page single row" issue is verified with FF 34 and Chrome 45, and IE 9, (could not test with IE 8 due to ICE-10817) but still occurs when using IE 10 and 11. This can be demonstrated with the /liveScroll1.jsf page at http://dev.icesoft.com/svn/repo/qa/trunk/Regression-Icefaces4/Sparkle/Nightly/dataTable/web/views/
r46116: fix for last page single row issue on IE
Verified IE issue ICEfaces 4 trunk r46116. Tomcat 7, IE 11, 10.
46140: modified previous fix for last page single row issue on IE, since it was adding extra space to regular pages; the fix is now based on a timeout function.
As for not being able to hold the arrow buttons in the scrollbar to continuously trigger livescroll requests on Chrome, it seems to be a browser limitation. I tested earlier versions of the livescroll functionality, and it was never possible to hold the arrow buttons and continue scrolling on Chrome. After all, every livescroll request updates the body table, and it's up to the browser to end the client event that triggered the request or to keep it going, since it's new markup. There's also no way to access the scrollbar itself from javascript.
Verified ICEfaces 4 trunk 46143. Tomcat 7, FF 34, Chrome 46, IE 11, 10, 9.
r46315: dataTable - Live Scrolling demo was added to showcase.
Tentatively scheduled for 3.4.