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).
Related
I need to implement infinite scrolling in a react app, while my data is huge and the use might keep on scrolling and scrolling for a long time.
All the infinite scrolling solutions that I've found only handle adding the data to the table whole scrolling. But I need to also remove data from the DOM to prevent the app from slowing due to tens of thousands of rows being potentially loaded after some time on the app (think social media feed).
I also don't want to keep all the data in the memory and I need to clean old data while scrolling (up and down).
So basically what I need to do:
Load the first 100 rows (1 page) to the page
When the user scrolls down and getting near the bottom, load next page and add to the bottom
When the page has a large amount of pages (lets say 5 page, or 500 rows) start to remove old pages from the top when the user keeps scrolling down
If the user start scrolling up, we need to reverse the functionality - Request the pages we removed again and add them to their place in the top
Does anyone know of such a solution?
Any recommendations on how to tackle this if I need to build from scratch?
Thanks!
1. Use react-infinite-scroll-component.
Follow instructions in documentation.
You can see basic example here. Here initially array have 20 elements and fetchMoreData function concatinate 20 more elements to it.
Basically you are concatinating, next elements in in array and adding them over, this is the concept of infinite-scroll.
For furthur references, link1, link2.
Or
2. You can implement you custom scrolling as well, like this
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.
I am creating a web-site that drives content for a large 2D area off a CMS, so I have a system that runs on a timer, examines the part of the area that is currently on-screen, and loads content that is close enough to the view area that it might soon come into view.
This all seems to work quite nicely, apart from one small glitch.
Some of my content is SVG elements created procedurally via JS (the load mechanism feeds data from the CMS into JS functions, which create the using document.createElementNS and insert it into a div in the correct absolute position).
This content appears fine if is on-screen at the time it is loaded (this happens when the page is initially loaded).
And it also appears if it loaded while an animation is moving the visible area (animation is used to follow paths across the 2D space).
HOWEVER, if I am manually moving the visible area (which I have implemented via click+drag) then the SVG elements are added to the document tree, but when they come into view they do not render.
If I do something to "nudge" the renderer, such as hiding an unrelated element via DevTools, or resizing the window slightly, then they appear.
I am thinking this may be a bug in Chrome? e.g. where it has initially decided the elements need not be drawn and does not reprocess correctly when that needs reconsideration? Or maybe I am missing something, I am only semi-experienced in manipulating HTML documents via JS (but after a quick look I do not see the same behaviour in firefox...)
I am moving the visible area by changing the (left, top) of a parent element (I do not want to use scrolling for that as the size of the 2D space is not defined in advance...)
Otherwise, is there some way I could trick the browser into recalculating what should be drawn? I was wondering about having a small transparent element on screen that I show and hide on a timer, although a workaround that prevents the problem in the first place would be preferable...
Thanks for any advice!
Ian
p.s. I cannot instantly produce demo code for this as the code-base is moderately large, but I will spend time to make a simpler example if that proves necessary...
I have a complicated page that is built 99% dynamically via JavaScript. It has hundreds of event handlers attached to various fields and at some point I'm done with that incarnation of the page and want to refresh it leaving only the original 1% and adding the 99% again from scratch.
I'd like to ask the DOM to stop updating the screen when I remove a single element that is at the apex of the 99% of the page. That element ( a div ) has thousands of things hanging from it. Is it possible to issue some call to stop all screen updates and then via another call to repaint the entire screen and continue on as normal?
On a similar note, I periodically need to add one or more columns to an existing massive table. I can't reasonably use a single fragment to do this, so that's out. I'd again like to ask the DOM to ignore changes till I tell it to repaint the screen. While my code is adding columns, I don't want any flicker or other visual clues that this is going on, and I don't want to put up some dummy page. I want what's already there to stay there till the whole thing can be replaced and only then ask the DOM to repaint the page. Is this possible ? If so, how?
I am making a portfolio website and have a horizontal slider which will slide between each piece of work. Let's assume that there are 100 works and they are all graphically intensive and/or flash objects.
Let's also assume that there will be a maximum of 4 works on screen at any one time.
They are all in one large div which I manipulate with jQuery to modify the left property to move the div.
On a high end machine it works nice and smooth but on for example a netbook, it's really choppy... or even on a slower browser.
What I plan on doing is working out which works will be visible as they transition and show only them. I hope this will give a performance increase. However, I plan on setting the visibility property to hidden so the elements dimensions are still there. But, I am wondering would it be better performance wise to set the display to none and create a placeholder element instead of just hiding the work?
What other ways could I increase performance on slower machines/browsers?
You will not gain any feelable performance increase from just making display:none;. The content will still be loaded.
Instead you could try to look at some ajax. An idea would be to preload 8 items even though you only show 4. Then at the users click on the "next"-button, the screen slides to the next 4 already loaded items and at the same time the next 4 items in the row will begin to load.
http://yensdesign.com/2008/12/how-to-load-content-via-ajax-in-jquery/