What is preferred and less in total weight - CSS3 Gradients/Box Shadow or Sprites? - html

I am constructing a mobile web app with a requirement of offline use. I am beginning to worry about total weight in code/files.
What is your experience with CSS3 (gradients/box shadow) vs. sprites, is one preferred but heavier? I am going to do some benchmarking but wanted to gather some information before I began.
Thank you in advance.

CSS3 properties are almost always preferred. They don't require an extra HTTP request, and are easier to edit in your text editor, as well as play around with in Firebug/Web Inspector.
However, if you start combining many of these properties together, they can hog down a system pretty much, since they are being computed on the device. So don't overdo it - if you need real fancy stuff, you might be better off using a sprite.

Related

Fast and responsive interactive charts/graphs: SVG, Canvas, other?

I am trying to choose the right technology to use for updating a project that basically renders thousands of points in a zoomable, pannable graph. The current implementation, using Protovis, is underperformant. Check it out here:
http://www.planethunters.org/classify
There are about 2000 points when fully zoomed out. Try using the handles on the bottom to zoom in a bit, and drag it to pan around. You will see that it is quite choppy and your CPU usage probably goes up to 100% on one core unless you have a really fast computer. Each change to the focus area calls a redraw to protovis which is pretty darn slow and is worse with more points drawn.
I would like to make some updates to the interface as well as change the underlying visualization technology to be more responsive with animation and interaction. From the following article, it seems like the choice is between another SVG-based library, or a canvas-based one:
http://www.sitepoint.com/how-to-choose-between-canvas-and-svg/
d3.js, which grew out of Protovis, is SVG-based and is supposed to be better at rendering animations. However, I'm dubious as to how much better and what its performance ceiling is. For that reason, I'm also considering a more complete overhaul using a canvas-based library like KineticJS. However, before I get too far into using one approach or another, I'd like to hear from someone who has done a similar web application with this much data and get their opinion.
The most important thing is performance, with a secondary focus on ease of adding other interaction features and programming the animation. There will probably be no more than 2000 points at once, with those small error bars on each one. Zooming in, out, and panning around need to be smooth. If the most recent SVG libraries are decent at this, then perhaps the ease of using d3 will outweigh the increased setup for KineticJS, etc. But if there is a huge performance advantage to using a canvas, especially for people with slower computers, then I would definitely prefer to go that way.
Example of app made by the NYTimes that uses SVG, but still animates acceptably smoothly:
http://www.nytimes.com/interactive/2012/05/17/business/dealbook/how-the-facebook-offering-compares.html . If I can get that performance and not have to write my own canvas drawing code, I would probably go for SVG.
I noticed that some users have used a hybrid of d3.js manipulation combined with canvas rendering. However, I can't find much documentation about this online or get in contact with the OP of that post. If anyone has any experience doing this kind of DOM-to-Canvas (demo, code) implementation, I would like to hear from you as well. It seems to be a good hybrid of being able to manipulate data and having custom control over how to render it (and therefore performance), but I'm wondering if having to load everything into the DOM is still going to slow things down.
I know that there are some existing questions that are similar to this one, but none of them exactly ask the same thing. Thanks for your help.
Follow-up: the implementation I ended up using is at https://github.com/zooniverse/LightCurves
Fortunately, drawing 2000 circles is a pretty easy example to test. So here are four possible implementations, two each of Canvas and SVG:
Canvas geometric zooming
Canvas semantic zooming
SVG geometric zooming
SVG semantic zooming
These examples use D3's zoom behavior to implement zooming and panning. Aside from whether the circles are rendered in Canvas or SVG, the other major distinction is whether you use geometric or semantic zooming.
Geometric zooming means you apply a single transform to the entire viewport: when you zoom in, circles become bigger. Semantic zooming in contrast means you apply transforms to each circle individually: when you zoom in, the circles remain the same size but they spread out. Planethunters.org currently uses semantic zooming, but it might be useful to consider other cases.
Geometric zooming simplifies the implementation: you apply a translate and scale once, and then all the circles are re-rendered. The SVG implementation is particularly simple, updating a single "transform" attribute. The performance of both geometric zooming examples feels more than adequate. For semantic zooming, you'll notice that D3 is significantly faster than Protovis. This is because it's doing a lot less work for each zoom event. (The Protovis version has to recalculate all attributes on all elements.) The Canvas-based semantic zooming is a bit more zippy than SVG, but SVG semantic zooming still feels responsive.
Yet there is no magic bullet for performance, and these four possible approaches don't begin to cover the full space of possibilities. For example, you could combine geometric and semantic zooming, using the geometric approach for panning (updating the "transform" attribute) and only redrawing individual circles while zooming. You could probably even combine one or more of these techniques with CSS3 transforms to add some hardware acceleration (as in the hierarchical edge bundling example), although that can be tricky to implement and may introduce visual artifacts.
Still, my personal preference is to keep as much in SVG as possible, and use Canvas only for the "inner loop" when rendering is the bottleneck. SVG has so many conveniences for development—such as CSS, data-joins and the element inspector—that it is often premature optimization to start with Canvas. Combining Canvas with SVG, as in the Facebook IPO visualization you linked, is a flexible way to retain most of these conveniences while still eking out the best performance. I also used this technique in Cubism.js, where the special case of time-series visualization lends itself well to bitmap caching.
As these examples show, you can use D3 with Canvas, even though parts of D3 are SVG-specific. See also this force-directed graph and this collision detection example.
I think that in your case the decision between canvas and svg is not like a decision between »riding a Horse« or driving a »Porsche«. For me it is more like the decision about the cars color.
Let me explain:
Assuming that, based on the framework the operations
draw a star,
add a star and
remove a star
take linear time. So, if your decision of the framework was good it is a bit faster, otherwise a bit slower.
If you go on assuming that the framework is just fast, than it becomes totally obvious that the lack of performance is caused be the high amount of stars and handling them is something none of the frameworks can do for you, at least I do not know about this.
What I want to say is that the base of the problem leads to a basic problem of computational geometry, namely: range searching and another one of computer graphics: level of detail.
To solve your performance problem you need to implement a good preprocessor which is able to find very fast which stars to display and is perhaps able to cluster stars which are close together, depending on the zoom. The only thing that keeps your view vivid and fast is keeping the number of stars to draw as low possible.
As you stated, that the most important thing is performance, than I would tend to use canvas, because it works without DOM operations. It also offers the opportunity to use webGL, what increases graphic performance a lot.
BTW: did you check paper.js? It uses canvas, but emulates vector graphics.
PS: In this Book you can find a very detailed discussion about graphics on the web, the technologies, pros and cons of canvas, SVG and DHTML.
I recently worked on a near-realtime dashboard (refresh every 5 seconds) and chose to use charts that render using canvas.
We tried Highcharts(SVG based JavaScript Charting library) and CanvasJS(Canvas based JavaScript Charting library). Although Highcharts is a fantastic charting API and offers way more features we decided to use CanvasJS.
We needed to display at least 15 minutes of data per chart (with option to pick range of max two hours).
So for 15 minutes: 900 points(data point per second) x2(line and bar combination chart) x4 charts = 7200 points total.
Using chrome profiler, with CanvasJS the memory never went above 30MB while with Highcharts memory usage exceeded 600MB.
Also with refresh time of 5 seconds CanvasJS rendering was allot more responsive then Highcharts.
We used one timer (setInterval 5 seconds) to make 4 REST API calls to pull the data from back end server which connected to Elasticsearch. Each chart updated as data is received by JQuery.post().
That said for offline reports I would go with Highcharts since its more flexible API.
There's also Zing charts which claims to use either SVG or Canvas but haven't looked at them.
Canvas should be considered when performance is really critical. SVG for flexibility. Not that canvas frameworks aren't flexible, but it takes allot more work for canvas framework to get the same functionality as an svg framework.
Might also look into Meteor Charts, which is built on top of the uber fast KineticJS framework: http://meteorcharts.com/
I also found when we print to PDF a page with SVG graphics, the resulting PDF still contains a vector-based image, while if you print a page with Canvas graphics, the image in the resulting PDF file is rasterized.

Is it better to use background images or CSS3 gradient? (Phonegap)

Suppose I am using a DIV element for which I can either add a background image or can replicate the same style creating a CSS3 gradient. Now, for Phonegap applications (where all the image files reside in the device itself), which option is better to go for.
I am asking this because I saw somewhere that the gradients takes some computation time where using image may create a loading time issue. But for Phonegap apps, the image load time issue may not be there. So, maybe just using the image be a better option here?
According to an article on the Webkit Wiki, images perform better:
Sometimes it's tempting to use webkit's drawing features, like -webkit-gradient, when it's not actually necessary - maintaining images and dealing with Photoshop and drawing tools can be a hassle. However, using CSS for those tasks moves that hassle from the designer's computer to the target's CPU. Gradients, shadows, and other decorations in CSS should be used only when necessary (e.g. when the shape is dynamic based on the content) - otherwise, static images are always faster. On very low-end platforms, it's even advised to use static images for some of the text if possible.
Source: https://trac.webkit.org/wiki/QtWebKitGraphics#Usestaticimages
Of course, you have to balance that CPU time with the extra time it would take to load the image from the server. Also, for Internet Explorer, filters are extremely slow, especially if you have many on one page.

For a Time Machine-like effect, which of CSS3 Animations, SVG or Canvas will perform best?

For our website, we are developing a "component" that would display images in a similar fashion to Time Machine on Mac OS X. So it will be many images on top of each other, positioned slightly differently and with a smooth animation as you scroll forward and backward.
We have a spike implementation with CSS3 animations but it's not very smooth in Firefox and IE9 is not supported at all (though we may live with it if the other options are even worse).
We are considering implementation in SVG or Canvas but don't have much experience with it so I thought we'd ask first. So:
Requirements:
It must be fast. The animation must be smooth and that is a hard requirement.
It should be supported in as many browsers as possible.
Required browsers are Chrome 20+, Firefox 14+ and IE10+.
We would very much like to have support for IE9 too but can live without it if absolutely necessary.
Opera is nice to have but not necessary.
Options and our current experience / opinion on them:
CSS3 - seems like the "appropriate" technology for the task but unfortunately the implementation doesn't work so well. Maybe we have inefficiencies in our prototype code but the support seems quite different between different browsers at the moment.
SVG - at least it's vector graphics / DOM elements but we don't have any experience with it.
Canvas - we hope that it should perform well as it is used even for games but we can't quite imagine how would all the pixel redrawing work. Maybe we should use some libraries like processingjs?
Flash or other plugins - I happen to know Flash quite well and I know that the Time Machine-like effect would be quite an easy task there but we'd rather stay away from plugins at the moment.
Thanks for advice.
If the size of the component does not have to be very large, but can be limited to say around 800x600 pixels, then it sounds like Canvas should be up to the job.
If you only draw (scaled) bitmaps to the Canvas then performance is very good in my experience, even on iPad2. Performance only really starts to suffer at higher resolutions (1920x1080 and above), so if you use it for a fullscreen feature you need to watch out! Also, fancy features such as drop shadow etc. can slow down performance considerably as well.
Canvas has very few quirks between browsers, so it will almost certainly be less painful than using CSS3 or SVG in terms of getting it to work as expected across a wide range of browsers.
I would recommend whipping together a quick and dirty prototype with Canvas to see if it will meet your first requirement regarding performance.
If you decide to go with Canvas, I would definitely recommend using a library. Since you know Flash quite well you might want to take a look at EaselJS. It has a display list inspired by Flash, and the performance cost of using it is negligible in most cases. You also get basic events for interactivity. Also, if you go with EaselJS, it would be quite simple to port the code to Flash later if you decide to.
Are you looking for something like this? It uses SMIL animation so you'd have to integrate something like fakesmile to get IE support.

Most efficient way to cater for different web devices?

Folks voting to close as not constructive, read the whole thing please. Specific questions at the end. Looking for real world examples and approaches.
Context
With numerous devices like smart-phones, tablets being used increasingly to access the web its important to plan, design (responsively) and develop (esp. your front end) to give the devices a fast and tailored user experience.
There's some amazing sites being built. Have a look at mediaqueri.es (resize your browser)
We see approaches such as
big screen first, then target smaller devices.
mobile first then media queries to spice things up for bigger screens.
device detection with different techniques (including server side)
and serving completely different markup and content to devices.
Question(s)
What are you folks doing out there today? Why did you choose your approach and most importantly if it isn't the most efficient approach to tackle this, then what is?
Things I'm looking for:
Is it a pure CSS / JS / HTML approach, or server side, or a combination - why?
Each device gets only the resources (images etc.) that it needs so it performs well
Maintenance of the site is easier, i.e. adding / changing features is not a huge pain
Some code samples are always useful
lets leave out old shitty browsers like ie7 and below
I think what you are looking for is Responsive Web Design.
See:
http://www.alistapart.com/articles/responsive-web-design/
http://coding.smashingmagazine.com/2011/01/12/guidelines-for-responsive-web-design/
Responsive Web Design (using CSS) does not necessarily address performance issues but is a good starting point. Keeping in mind that premature optimization is the root of all evil, you can profile your users and bandwidth and determine where you need to optimize once you have a working design in place.
For a discussion of some of the downsides, e.g., image resizing in the browser (you can work around this with CSS and/or AJAX, though), see:
http://www.webdesignshock.com/responsive-design-problems/
You will want to use a framework like PhoneGap. HTML evolves slowly but every day, about 10 new devices with new bugs "features" hit the market and you innocent app - there simply is no way for a small group of people to handle the necessary work.
As for different devices, there are two trouble areas:
Screen sizes
Render bugs
For screen sizes, there are pretty cool solutions today. For example, some frameworks add the CSS style "640x400" or "480x800" to the body element. That makes it dead simple to style elements depending on the screen size. Or you can use JavaScript pull in the matching style sheets.
For render bugs, you'll need workarounds. As I said above, this is nothing a single person or a small group can handle. Every few months, there is a new version of Android with a new render engine and new "features". You fix problems for one of them and break ten others at the same time. Select a framework which plays well with many devices and which is open to changes (read: avoid anything proprietary).
That way, you get solutions for the common problems and you can fix small issues yourself.
I would definately recomment RedFilters Answer (+1).
I just wanted to add some libraries which you might find interesting relating to this topic. They involve Browser feature detection & conditional resource loading.
check them out:
http://www.modernizr.com/
http://yepnopejs.com/

How much more efficient is one big image rather than many small images. Facebook style

So I was looking at the facebook HTML with firebug, and I chanced upon this image
and came to the conclusion that facebook uses this large image (with tricky image positioning code) rather than many small ones for its graphical elements. Is this more efficient than storing many small images?
Can anybody give any clues as to why facebook would do this.
These are called CSS sprites, and yes, they're more efficient - the user only has to download one file, which reduces the number of HTTP requests to load the page. See this page for more info.
The problem with the pro-performance viewpoint is that it always seems to present the "Why" (performance), often without the "How", and never "Why Not".
CSS Sprites do have a positive impact on performance, for reasons that other posters here have gone into in detail. However, they do have a downside: maintainability; removing, changing, and particularly resizing images becomes more difficult - mostly because of the alterations that need to be made to the background-position-riddled stylesheet along with every change to the size of a sprite, or to the shape of the map.
I think it's a minority view, but I firmly believe that maintainability concerns should outweigh performance concerns in the vast majority of cases. If the performance is necessary, then go ahead, but be aware of the cost.
That said, the performance impact is massive - particularly when you're using rollovers and want to avoid that effect you get when you mouseover an image then the browser goes away to request the rollover. It's appropriate to refactor your images into a sprite map once your requirements have settled down - particularly if your site is going to be under heavy traffic (and certainly the big examples people have been pulling out - facebook, amazon, yahoo - all fit that profile).
There are a few cases where you can use them with basically no cost. Any time you're slicing an image, using a single image and background-position tags is probably cheaper. Any time you've got a standard set of icons - especially if they're of uniform size and unlikely to change. Plus, of course, any time when the performance really matters, and you've got the budget to cover the maintenance.
If at all possible, use a tool and document your use of it so that whoever has to maintain your sprites knows about it. http://csssprites.org/ is the only tool I've looked into in any detail, but http://spriteme.org/ looks seriously awesome.
The technique is dubbed "css sprites".
See:
What are the advantages of using CSS
Sprites in web applications?
Performance of css sprites
How do CSS sprites speed up a web
site?
Since other users have answered this already, here's how to do it, and another way is here.
Opening connections is more costly than simply continuing a transfer. Similarly, the browser only needs to cache one file instead of hundreds.
yet another resource: http://www.smashingmagazine.com/2009/04/27/the-mystery-of-css-sprites-techniques-tools-and-tutorials/
One of the major benefits of CSS sprites is that it add virtually 0 server overhead and is all calculated client side. A huge gain for no server side performance hit.
Simple answer, you only have to 'fetch' one image file and it is 'cut' for different views, if you used multiple images that would be multiple files you would need to download, which simply would equate into additional time to download everything.
Cutting up the large image into 'sprites' makes one HTTP request and provides a no flicker approach as well to 'onmouseover' elements (if you reuse the same large image for a mouse over effect).
Css Sprites tecnique is a method for reducing the number of image requests using background position.
Best Practices for Speeding Up Your Web Site
CSS Sprites: Image Slicing’s Kiss of Death
Google also does it - I've written a blog post on it here: http://www.stevefenton.co.uk/Content/Blog/Date/200905/Blog/Google-Uses-Image-Sprites/
But the essence of it is that you make a single http request for one big image, rather than 20 small http requests.
If you watch a http request, they spend more time waiting to start downloading than actually downloading, so it's much faster to do it in one hit - chunky, not chatty!