-
Notifications
You must be signed in to change notification settings - Fork 424
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
Fix for CSS Rendering Issue at large row counts #1044
Comments
This seems slightly related to issue #297 cc @6pac So in your code, you seem to completely replace the With this change however, this will most probably break all Cypress E2E tests because a few of these tests rely on the
That's the default behavior of GitHub and any other repos using git, no one in the world has access to push directly to a repo. You need to fork the repo and then push to your fork. After pushing to your fork, it will then ask you if you want to create a Pull Request to push to the original repo (here). So it's not a 1 step push, but rather a 3 steps push (unless you're a contributor/maintainer of this repo which are only 6pac and myself). This Video explains how to contribute to an open source project: |
Hey there, Great, thanks for looking into this so quickly. Please find responses below:
However, with regards to the bugfix, in terms of motivational sentiment I remember coming across documentation or possibly a github issue when first using Slickgrid about a year back, and it said that '2 billion rows are supported'. This made me very excited, as it was a big promise. I'm praying that can pull through, and at 100m so far and counting!.
|
Yes some people use it with extremely large dataset, I did see someone using that much data but I would never go with that much size myself (it's not recommended especially for sorting/grouping/...). I already mentioned why the Cypress tests will fail, I'm often using the I don't really want to use compare tools to find out what really changed, it would be helpful if you could use the - hello world
+ Hello World! I'm not too sure that I want to proceed considering that this is most likely a Breaking Change (avoiding breaking changes would be ideal). |
Look I'm just trying to help and be responsive, by contributing what I believe is a code fix to a genuine bug that I encountered when using the library. Above, I've run the tests in response to the comments. Please find the requested diff details in the attached .diff zipFile changes-diff.zip. That's completely understandable if it breaks a lot of tests and creates a lot of work. I thought I'd take the time to raise it, so others could benefit from the fix. Thanks -
- }
+ let rowDivR: HTMLElement | undefined;
+ divArrayL.push(rowDiv);
+ if (this.hasFrozenColumns()) {
+ rowDivR = rowDiv.cloneNode(true) as HTMLElement;
+ divArrayR.push(rowDivR);
}
- // Do not render cells outside of the viewport.
- if (this.columnPosRight[Math.min(ii - 1, i + (colspan as number) - 1)] > range.leftPx) {
- if (!m.alwaysRenderColumn && this.columnPosLeft[i] > range.rightPx) {
- // All columns to the right are outside the range.
- break;
+ let colspan: number | string;
+ let m: C;
+ for (let i = 0, ii = this.columns.length; i < ii; i++) {
+ m = this.columns[i];
+ if (!m || m.hidden) { continue; }
+
+ colspan = 1;
+ if (metadata?.columns) {
+ const columnData = metadata.columns[m.id] || metadata.columns[i];
+ colspan = columnData?.colspan || 1;
+ if (colspan === '*') {
+ colspan = ii - i;
+ }
}
- if (this.hasFrozenColumns() && (i > this._options.frozenColumn!)) {
- this.appendCellHtml(rowDivR!, row, i, (colspan as number), d);
- } else {
+ // Do not render cells outside of the viewport.
+ if (this.columnPosRight[Math.min(ii - 1, i + (colspan as number) - 1)] > range.leftPx) {
+ if (!m.alwaysRenderColumn && this.columnPosLeft[i] > range.rightPx) {
+ // All columns to the right are outside the range.
+ break;
+ }
+
+ if (this.hasFrozenColumns() && (i > this._options.frozenColumn!)) {
+ this.appendCellHtml(rowDivR!, row, i, (colspan as number), d);
+ } else {
+ this.appendCellHtml(rowDiv, row, i, (colspan as number), d);
+ }
+ } else if (m.alwaysRenderColumn || (this.hasFrozenColumns() && i <= this._options.frozenColumn!)) {
this.appendCellHtml(rowDiv, row, i, (colspan as number), d);
}
- } else if (m.alwaysRenderColumn || (this.hasFrozenColumns() && i <= this._options.frozenColumn!)) {
- this.appendCellHtml(rowDiv, row, i, (colspan as number), d);
- }
- if ((colspan as number) > 1) {
- i += ((colspan as number) - 1);
+ if ((colspan as number) > 1) {
+ i += ((colspan as number) - 1);
+ }
}
- }
}
protected appendCellHtml(divRow: HTMLElement, row: number, cell: number, colspan: number, item: TData) { |
Yeah sure I'm open to progressive comments and discussions, what I meant to say is that I just think that we have to consider the potential side effect in doing this kind of changes because that could impact end users which is something that I always try to avoid (even if it fixes a bug, it might still be a Breaking Change because of the behavior change). Taking a look at your new code, it's more than I expected, have you tested frozen grids and all? The Cypress tests would eventually for sure all have to pass (probably by just changing For example with the Cypress test shown below, it ask for SlickGrid/cypress/e2e/example-autotooltips.cy.ts Lines 39 to 41 in 87b8c6a
So in the end, I didn't mean that I will refuse the PR, but I meant to say is that if it's really the only way to go, then that would potentially (probably) require a I wonder why a |
Sure, no problem, I appreciate that. Thanks. Ok, so with regards to translate vs top, I’d been reading a book on front end which suggested that translate gets put on the GPU and accelerates paint times, compared to top which (generally) has longer paint times. The video at this link gets to the crux at 7:48 https://www.paulirish.com/2012/why-moving-elements-with-translate-is-better-than-posabs-topleft/ , and makes a convincing argument using browser tools to measure paint times. Part of me is wondering whether this is still the case in 2024 (?), but it’s interesting for sure. With regards to the versioning, I understand your concerns. For a personal project, I’m at the point where I need to make a call on Slickgrid, and it’s been very promising in most areas. However a related area that’s causing a few issues is the repainting times, affecting the frame rate after fast scrolling. It’s still very fast data though not 45-60 FPS fast enough that casual users might expect from a spreadsheet-like tool, in that when holding down scroll (medium speed - not the slow arrow scroll, or moving the bar, but the scroll bar space between) the data and grid doesn’t repaint in time for it to look like the data is being scrolled through. It does manage to get 30% of the data in time though (which has the effect of looking like the data is chasing the grid). I should note that this is compounded by the way data is brought in for my specific use case and, but that has already been heavily optimised and therefore I believe any achievable optimisations on the library code could still have potential to benefit the general library. A related UX drawback I’ve experienced is the white flashing after scrolling which as I understand from one of your stack overflow posts is part of the virtual scrolling, but Ive wondered if there is still maybe some opportunity here? Perhaps not? But it’s still a different UX to say Excel/google sheets, and I felt concerned that a user might get disoriented. Not for jumping from say row 1000 to 30,000, but for scrolling between adjacent numbers (at high speed) I feel it would be awesome if it could be a bit smoother. Why am I raising this? Well if it’s is ok with you I’d like to have an go at diving deeper on the performance side to see if I can profile it, review the internals in more detail and potentially recommend further adjustments? Can’t promise it will bear any fruit, as I know you guys have worked with this for a long time, but if I were to break any ground (rather than tests 😅) and bundle a few related changes up, try pass the tests, then would you be happy to take a look at it ? I would have no issue if it sat on the back burner until it made sense to bundle as part of a broader release, or otherwise I can always just run my own patch which I’ve done for a couple of small things, which would be fine. Anyway, keen to have a crack and see if it’s possible to speed up the fast-scroll rendering, if this ok? Note - would expect up to a 4-8 week turnaround with other commitments, getting familiar with the library and some of the front end optimisations, depending on how difficult it is. Just to help set expectations. Thanks |
Note I should have mentioned if it’s a matter of porting tests I’m happy to check that out at the same time. |
Edit: Also noting that the above includes tweaking the library debounce setting from 50ms to 5ms, which helped the data appear partially on the grid during scroll. |
From my point of view, the issues you raise are very valid and I'd definitely support working on them. I'll let @ghiscoding speak for himself, but I suspect he'll say the same thing. |
There's a throttle in place which makes the virtual scroll wait before rendering the next batch. It's currently set to 50ms, you can try to decrease it. I think it was added by Ben a long time ago (it doesn't seem to exist in the original SlickGrid repo though). You have a large dataset so you are the best person who could give it a try with maybe 0 and see what happens (there's more info in old PR #810). Line 290 in 87b8c6a
I actually always wondered why that was put in place, so perhaps you could try to disable it completely, something like this maybe. So if you comment out the following line (and where it's being used, which is the Line 663 in 87b8c6a
Line 4918 in 87b8c6a
Line 5105 in 87b8c6a
there's also a grid option for how many rows to keep in the buffer when scrolling, which in other words mean how many row do we want to cache and make ready before the scroll happens. I'm not sure if it has any impacts or not but maybe try to increase it a bit? Line 283 in 87b8c6a
it would be part of it, but the question is more about "Do we really want to do a Breaking Change version with just this change? or can we do a bug fix that will not introduce a Breaking Change". Because in my head, I'm really consider the Doing some tests on a large dataset with the area that I mentioned above might be where the perf can be improved. I always wondered what side effect it could have to go without this code. I think there's probably a good (better) number to come up with that will make it look more fluid while not making worst either. I mean without the render throttle, it might make it look worst because the browser can't keep up, but again we won't know until someone is performing local tests of that. Browser are getting better every year so the throttle we needed 5 years ago might not be the same or as worth it today (it's also probably a good idea to test with more than 1 browser). So anyway, doing more tests and thinking about what else we could include in a Breaking Change version. I mean, if there are other breaking changes, now would be the good time |
not aware of ever having added the throttle, but if you have evidence, then I suppose it was me! Way back when this was happening, there was much less standardisation between browsers so it could well have been a cross-browser compromise. I think in the modern context we would be much more confident in the stability of a more optimal solution. |
haha yeah sorry it's not about pointing fingers, but more about the reason why it was put in place. I suspect that might have been copied from another fork too, there was a bunch of different forks that existed when the original got unsupported, so who knows where and why this code was put in place is hard to remember ... anyway, you can see similar discussions we had about this a while ago in this comment and the commit where you added this throttling is 93f043f |
So I did. I'm pretty sure I didn't write that code though - it must have been either patched in from another repo or contributed in an issue. So in summary, I don't know exactly why it was added. It does definitely make sense to have some throttling for long scrolls (that was probably my logic at the time), but there appears to be some room for improvement. |
Great. Thanks for your comments too @6pac. Well this sounds like a great place to start @ghiscoding - I’ll run those preliminary tests over the weekend, and post back with some benchmark comparisons on the parameters listed. If I learn anything else when diving I’ll include it. If there’s anything else specific like that just let me know . Cheers. |
ohhh wait a second, I just found how to push this into a new version without making a Breaking Change. We could simply add this into a grid option keep const rowDiv = Utils.createDomElement('div', {
className: `ui-widget-content ${rowCss}`,
role: 'row',
- style: { transform: `translateY(${topValue}px)` } // Using transform instead of top
});
+ if (options.topStyleRenderType === 'transform') {
+ rowDiv.style.transform = `translateY(${topValue}px)`;
+ } else {
+ // else default to `top`
+ rowDiv.style.top = `${topValue}px`;
+ } and voila! Perf improvements is now doable on your side and it won't break users who are still expecting Also for the other portion of code that I reference above ( EDIT I also see this comment in the article you referenced, which was very instructive. I think we are already using an integer for the top value but if not then please make sure it is (with |
@pbower might be woth checking this out too: https://www.thecandidstartup.org/2024/04/29/modern-react-virtual-scroll-grid-9.html |
Awesome, thanks for that. Just reaching out with an update - I did have some good success on the weekend both from a profiling and then action-ing perspective. I made a few key updates across :
These changes focused on batching DOM updates. However, I then a roadblock when I went to run the tests, and unfortunately knocked out a few of the key event listeners in the process. So I will go back and QA it properly next weekend when I get some time and do that before sharing back the code and comparisons, otherwise it's kind of cheating I think. Thanks |
Wow that's a good article. Will definitely review that in detail. |
Really curious that repo there - I ran the infinigrid examples - 1 follower / star repo (i.e., like I was the first one to visit it), casually with a 3 trillion row grid sitting there. Seems like he's on a mission. |
Yep. From what I can tell, former rockstar programmer gets tired of the stress, makes a well compensated exit and has a lot of time on his hands. My dream. |
@pbower we didn't hear from your side, so I went ahead and done couple of small PRs related to this issue
Lines 5113 to 5118 in dc08ab8
This is all available in v5.12.0 |
Hey, sorry it looks I never came back to you on this. Thanks heaps for that, it's much appreciated. |
Describe the bug
Hi @ghiscoding ,
Hope you're doing well.
Wondering if you have a moment to take a quick look at a bug / suggested fix?
Problem:
I recently encountered a CSS rendering issue at large counts:
See correct styles here for comparison:
Solution:
I found that it relates to this line of code in appendRowHTML for slick.grid.ts:
The following fix resolves the issue, and the repo tests still seem ok:
If this all looks ok to you, wondering if a special access is required to push a branch with the fix ? As I tried to but it said access denied.
Thanks,
Pete
Reproduction
Grid with approx 10m rows with grid line styles . - > close to 10m it will encounter rendering issues.
Which Framework are you using?
React
Environment Info
Validations
The text was updated successfully, but these errors were encountered: