Scrollbar 'representation' - javascript

I have a scrolling tbody in my html page. For certain reasons (mainly performance reasons) I only show 25 rows in that div instead of the 1.000 or 10.000 rows that exist in the underlying data variable / DB.
Right now I do something much alike to what DataTables.net does; I rotate the contents of those 25 rows on scroll event. Works fine.
One thing that annoys me though is that for instance you have 1000 rows, 25 showing: the scrollbar moves just like always but only takes in to account the 25 rows (because it only sees those, duh ;-) ).
DataTables' solution though show a scrollbar that moves down according to those 1000 rows so it moves a lot slower and dragging it all the way down really goes to record 1000 instead of 25.
Does anyone know how to maybe influence the 'presentation' of the scrollbar in a way that DataTables are able to? (I've googled a lot but no dice)
I use html5, Javascript / jQuery and PHP.

You can set the length of the scrolling container depending on the total number of rows, then dynamically load the visible rows into view, when the user stops scrolling.
This means that you need to know the exact height of one row, and you'll have to manually position the rows in the container. Sorting the rows might be an interesting problem then.
To make that all a little easier, it might perform well enough if you add only the 1.000 rows, without the data, then dynamically load the data.

Related

Is it possible to manipulate the scrollbar thumb height regardless of the content?

so this one's a bit tricky. For context, I'm working on a table using https://www.ag-grid.com/react-data-grid/ and I can know in advance the size of the sample I will have to show.
Anyhow, I need to be able to show the user the whole sample of records just using the scrollbar. What I mean by this, is that I don't want to load 100k records, but rather calculate the corresponding height of the scrollbar thumb, based on said number of records, so that if I have 5 records, there should be no scrolling, but if I have 100k records, then the scrollbar thumb should be quite small.
I was able to achieve this behavior by pre-loading N records to the table, however this isn't desirable because of the performance impact of loading an 100k array. Another alternative would be to resize the table knowing the size of 1 row, and multiplying it by 100k.
So to sum it up: is there a way to manipulate the scrollbar thumb size ignoring the table content? Maybe doing something funky with the shadow dom, or resizing the table size.

Render problems with very large virtual tables

I am using this tablescript to display a virtual table but for some reason after a specific point problems occur.
On Google Chrome after the top value (The position value where the row is displayed in the parent div) of 1.677715e+07px (16777150px) is exceed the rows are missing its border-bottom for some reason. This happens on the newest version of Chrome (v69). On version 68 the rows at this top value and more arent rendert at all.
They are still there, you can see them via the inspect tool on the browser.
Does the number 16777150 has something to do with JavaScript or Google Chrome?
On Edge browser something different happens. If the parent div of the virtual table exceed the height of 10737418px, the rendered height of this div will be only as big as its content height So if the last row is ending at top 900px, the table will be 900px height too. If you scoll further down and the new row is rendert, the div will get bigger too. But in the inspector you can see the right height value in this element and it doesnt change at all.
To post this link I need this code..
Here is the Code exampel.
If you want it to test it yourself, the .js and .css are in the github of this tablescript in the example folder.
Maybe this hase something to do with the browsers or JavaScript so I ask this question here.
I dont know how your table is being displayed.
But it's not a good practice to display this much entries at once. Try to use pagination.
Have a look at https://datatables.net/ and try to dynamically load table entries (like pick it up from database or something like this)
You had mentioned that tablescript also do the same thing and i see that after many records it display so long empty space without data.
But here, I want to confirm with you that if you use the pagination and display 20 rows at a time then it should work without any issue.
Then why you want to display large number of records?
If you have any issue with 20 rows then try to let us know about that.
We will try to find the solution for it.
Regards
Deepak

Trigger after browser painting / rendering

I'm using VUEJS to load and display a table tag on the screen.
This table is quite huge: around 1000 rows and 10 columns and might have to grow in the future (for the future we might have to deal with 8000 records)
Because of some UX requirements we need to have each cell width of the table header to be calculated based on table body size.
Basically we use 2 tables, one for the header, one for the body (so we can keep the header on top while scrolling down on the table), and thus each cell width has to be calculated based on each other.
if (headercell.width() > bodycell.width()) bodycell.width(headercell.width)
else header.width(bodycell.width)
This works fine, only issue is that the cell width is only available when the entire rendering/painting (not sure about the right term) is finished.
With a big table like this, I have to work with a timer which is not clean.
Any idea how I could catch when the rendering/painting process is finished so I can call that function?
Thanks

Mitigation techniques for Internet Explorer DOM insertion speed

I have a menu with custom drop downs that can contain thousands of items. This is the worse case scenario and most of the time it's in the hundreds or less and it's all super fast.
I've delayed the insertion of the elements (li) to when the menu is opened but this causes a perceptible delay for a couple seconds when it's clicked to when it's opened.
I build a string of all the list items in javascript and add it using a single innerHtml assignment. It's the innerHtml assignment that takes all the time. I've also tried using a fragment and appending to that as well as using a fragment and appending each item separately all to no avail. Insertion times are below:
Text Li/InnerHTML Li/Inner/Fragment CreateLI/Fragment
Chrome 13ms 40ms 48ms 138ms
IE9 22ms 2402ms 2364ms 7934ms
IE11 19ms 1952ms 2330ms 4208ms
First column is inserting all the content but just as text and new lines inside pre tags in a single innerHTML call. Unfortunately li's are needed for styling and events ect.
Second column is adding all the content but each wrapped in li tags in a single innerHTML call.
Third column as above but using a fragment and then appending that.
Forth column as above but each li is added as a separate create and append to the fragment.
Unfortunately IE (We are moving to IE11 around xmas) is the target browser - corporate intranet :-(
One thing I've tried to mitigate this is to just insert the first, say 50 items. So opening the menu is fast but on scroll, I have to load subsequent items again in batches of 50 up to the scroll point. IE isn't fast enough so most of the time you are seeing nothing and when dragging the scroll bar it keeps locking, jumping forward, locking ect because the innerHTML calls block the whole browser when you're trying to scroll.
Another technique I've tried is to insert the first 50 items, and then load the remaining in 50 chunks with intervals of say 50ms to not block everything. Unfortunately this leads to an even worse experience because the page responsiveness stutters like it does when scrolling in the previous example, but here you don't even have to be scrolling, it always does it until all the items are added.
I'm out of idea's now. How can I make IE work faster?
Half-assed answer first: The maximum (for you) is 8 seconds long. You could do a modal overlay that shows a loading animated gif that counts from 0% to 100% over an eight second period. I can link you to some code that does that animation in an HTML5 canvas if you want. This is not a great solution, but it would give your users something to look at while the page is taking so long to load.
Arguably better answer: Do what you suggested to yourself - load the first 50 and then load the next X on scroll or every X milliseconds (I like the former better) and just edit your CSS and other code to make sure the page doesn't do weird stuff style wise like you seem to be experiencing in your tests.
Best answer: You say that it's a custom menu, but it is a menu. As such, you should cache it instead of loading it fresh every time. You create the cache text file every time the menu is changed in the database. Loading a text file into the page will take almost no time and every programming language you work with can do it. The way this works is you make a function that builds a .txt file containing the pure HTML of the menu and then call that function every time the menu update function is run (after the database is updated, naturally).

Looking for ideas to quickly flow content

I'm writing some code that wraps various content into columns of text (and images, videos, etc). The code works fine, but due to the algorithm I'm using it's rather slow, specifically this general logic:
add something (text for this example) to a column
check to see if column.scrollHeight > column.offsetHeight (this requires a DOM reflow)
if yes, start to binary split the text until it's shorter
Basically my issue is that I'm adding an unknown amount of text to a column, so after each chunk of text I check the column's scroll height which requires the browser to actively reflow the DOM in order to give me the correct scrollHeight. So I have 50-100 or more reflows in order to properly lay everything out.
Any general ideas on how to avoid most of these?
You could render the content multiple times. Since the first time would cache it, this should be fairly fast. The reason for the multiple rendering would be as follows.
Render the original content in a hidden area
Check to see what the column width is compared to content
Overlay the content over the column, but beneath the page. This
will cut off part of the content that is overflowing. You can accomplish with
z-indexing or with overflow: hidden;
Based on what the check from step 2 was, overlay a copy of the content with
the calculated offset in the next column in the same fashion, hiding the
extra content.
Keep track of the rendered content versus total content so you can tell how many
columns you need to do this to if there are multiple columns.
Maybe this is the same thing Travis J is suggesting, but I'm not sure, I don't quite understand his solution.
You could render everything first, on a single column, then loop through the elements top-down to know when to split, based on your desired column height versus each element's offsetTop plus height. When you find an element to break at, cache its position and go on. At the end you should have an array with the list of elements to break at, so you can actually split the content in columns.
Does this make any sense to you?

Categories