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/
Related
I'm using a library called ParticlesJS for part of the background of my website - this library dynamically generates a canvas element sized according to its parent, and fills it with animated particle effects, creating a neat effect. With that said, I have run into some practical issues when trying to use it as the background:
If the canvas element is the same size as the content, the visuals become pixelated and distorted if the height changes, such as with the addition of new content. Reloading the library is not a solution to this as it creates a visually distracting effect.
If the canvas element is an arbitrary extreme height and not sized according to the content (with the overflow simply hidden), the performance of the website suffers, as the library consumes excessive CPU power.
If the canvas element is simply given a fixed position in CSS, performance is good and it sticks, but it looks out of place as everything behind it moves during scrolling.
After some consideration, it seems like the best way to make it work is to give it a modest size (like 200% page height), and then make it repeat infinitely during scrolling - performance would be acceptable, and there wouldn't be any distortion. However, I can't find any way to do this - I'm aware that there's a background-repeat property in CSS, but that seems to only work for images.
Is there any way to do what I'm trying to accomplish? Both CSS and JS based answers are welcome.
After some trial and error, it looks like the only means of accomplishing what I'm trying to do is as follows:
Create 3 or so background divs, each the size of the view port, and stack them vertically
Record user scrolling activity, and set a trigger for when a user has scrolled a height equal to the height of the view port
when the trigger is hit, place the div that just left the view port at the end of the list, and insert an empty spacer div where it used to be
If done correctly, this creates an effect where the user is apparently scrolling through an infinite background, when it's really just the same 3 or so divs being shuffled over and over. Going in reverse is the same principle.
Not sure how to make this work with in a system that also has scroll position restoration, but it could probably be done by waiting for page loads and then dynamically inserting enough spacers to move the background divs to the appropriate position in the view port.
The downside to using animated effects that rely on viewport dimensions is that the user may resize the browser and wreck your animation so you have no choice but to catch any viewport resizing in which case you may have to reload everything or recalculate!
You can't have the cake and the cherry on top unfortunately, so you'll either have to abandon the idea of "impressive effects" because they are impractical or take action...
document.body.onresize=function(){Adjustments();};
function Adjustments(){
var W=Container.offsetWidth, H=Container.offsetHeight;
// You've now got the new resolution so go for your life!
}
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).
I have a grid of div boxes that I will be animating. They will be moving across the screen after a user drags one of the boxes (to re-align into a grid).
Currently I am using JQuery to change the css left and top positions of all of the divs and running this on an interval.
It is laggy if there are more than 50 boxes. How do I make this less laggy? Is there an animation library that is better for this, or do I just need to limit it to 50 boxes?
Image of layout:
You have a few options to optimize the performance.
Newer browsers have requestAnimationFrame that lets the browser take care of the animation timing in order to optimize Javascript animations. Rather than using times to perform the animation, which is what jQuery framework uses, you repeatedly a callback to requestAnimationFrame. The browser will call your function with a progress variable for the animation, and you render the current stage of your animation based on the progress variable. requestAnimationFrame for smarting animating talks about this in depth. Google Closure is the only framework I am aware of that uses requestAnimationFrame however, and it's rather heavyweight.
CSS animations. jQuery offers CSS animation, so do many other frameworks. CSS animations give you hardware acceleration, so the animation is much faster. Unfortunately, CSS animations are relatively new and not yet well supported, so you'll probably end up falling back to Javascript animation on older browsers, depending on the library you use.
Optimize your Javascript. Instead of animation each and every box in the grid, encapsulate each row in a div and animate the entire div instead. That should speed the animation up by a bit. I'm sure there are other ways you can optimize based on your current implementation.
Honestly, I don't know of any library that will make this work more efficiently for you, though there are many libraries out there that are faster than jQuery. The issue isn't just the jQuery, its the fact that you have 50 elements that are all moving/draggable, thus requiring a lot of the browser's resources.
If you can post your code there may be a few things that we could suggest to speed it up slightly.
The two biggest things problems that I can think of are if you added those boxes programmatically and added the handler for each as you added the element to the page, and if you don't store your selectors in variables. Aside from that I would have to see the code.
Have a look at:
jQuery isotope
It has options to allow you to use css3 animations if available or use jQuery / JS animations.
Handy for grid like animation and arrangements.
Some brave soul has managed to add drag and drop to isotope too. http://tyler-designs.com/masonry-ui/ (a bit clunky but works)
There are several ways of increasing the performance. One would be to reduce the amount of DOM elements required for each box. Another is to not animate (and render) boxes outside of the current viewport. Give all boxes that are outside of the viewable area "display: none;" and exclude them before starting a new animation. If you want to go even further you can start to recycle boxes instead of showing and hiding them when the user is scrolling through the page.
This way you will always get the same performance no matter how many boxes you have (above the amount that you can fit in the viewport).
This technique is called UI virtualization. There are several projects that use it like: http://github.com/mleibman/SlickGrid/wiki. It's really useful when you need to render a lot of elements (hundreds, thousands, millions). But it takes quite some work to get it right. And I don't know about any generic working components that are easy to plug in. I tried to find an article that explains it. This is the only thing I could come up with for now, it's for Silverlight though: http://www.silverlightshow.net/items/Virtualization-in-Silverlight-4-RC.aspx
Also try this this plugin for jQuery. Use the regular 'animate' method and it will try to use (hardware accelerated) CSS animations where possible: http://playground.benbarnett.net/jquery-animate-enhanced/
Need your help.
I created a static semi-opaque banner which stays at the top of a website. When a user scrolls the website the entire container objects goes underneath the banner. I want all the objects (images, text..etc) getting blury effect as it goes underneath the banner.
Thanks
The only way you're going to be able to do this is by getting fancy with some CSS and javascript. CSS doesn't support blur directly, but you can emulate it with text-shadow. Images can also be blurred with a little jquery/css/javascript magic, but will be problematic because you can't partially blur an image (what happens when only part of the image is under the banner?). It could probably be done by layering your images and keeping track of their position on screen, but all of this seems like a lot of work for a very small return.
So, assuming you've decided to give all of this a shot, you're going to have to use javascript to determine which parts of the page have passed under the banner and apply the style to those parts. The difficulty of this task will scale with the complexity of your page layout. In a best case scenario, your banner and content container are both 100% the width of the html body. At this point, it would be fairly trivial to write some kind of scanner that traverses the dom every time you page scroll to find elements that the blur should be applied to. However, best-case-scenario is rarely the case at hand, at which point I'd recommend abandoning the effort to pursue something with a greater ROI.
This isn't possible with CSS nor jQuery. You might be able to do something with IE's filters, however that's IE only (of course), and will invalidate your CSS.
Currently, there is no way to do this, although something might come along in CSS 4 or something.
The Chrome nightly builds support some filters, however there isn't an alpha blur filter (yet, at least).
I'm creating a photo gallery website, and there are pages for browsing the photos, with a listing of thumbnails (yes just a regular photo site). The problem is that, I want thumbnails to fill up the available space (I know how to get that one). Actually, what I want to achieve is very similar to this: imagine you have a big number of (more than the screen area allows) thumbnails, and you have set overflow-y to hidden. The thumbs just fill up the space and it goes, off the screen. This would be what I wanted to have if the thumbs in the bottom didn't go off the screen. I need something more, let's say, "dynamic". I've got jQuery, but haven't been able to model the desired effect in my mind.
You should load the images dynamically as needed to improve performance. See the "Reduce the Number of DOM Elements" section in the Yahoo! Best Practices for Speeding Up Your Web Site. Use jQuery to check the size of the div in which you are rendering the images. Load just enough images to fill the div and then load more images on the fly as needed (on window resize or scroll). It is not clear to me exactly what you want to achieve so I can't be more specific than that.
Ok found the way into it anyway. I just load a big number of thumbs, set the overflow-y of the thumbs container to hidden, and by Javascript (actually jQuery), when I resize the window check if the thumbs top + height exceeds window's height. if it does, I simply hide that thumb, if it doesn't I simply show it. It works great!