Our application at work uses the ExtJS (Sencha) framework for the UI. The problem I have with the framework is the amount of HTML that is output by the framework.
I have noticed that the areas of the system that are reported as being slow by users have a ton of CSS calculation calls. I measured this in Google's Speedtracer and some pages take 8seconds to load. 80% of the time is dedicated purely to CSS calculations. Before trying to alter the way the framework works, is there anyway to delay CSS calculation of a page, or are these calculations done when the objects are rendered?
I have been searching for ways to do this, and maybe my "google-fu" is terrible, but I haven't found anything concrete on how to achieve something like this.
EDIT: After speaking a colleague, he pointed me in the direction of calling .suspendEvents() on the grid before loading any data and .resumeEvents() afterwards, this alone has saved 300ms of loading time :O This is reducing the number .getStyle calls detected by Firebug. I am yet to test this difference with Google SpeedTracer
It's hard to say what's causing your performance problem without knowing exactly what your app is doing. CSS will have some impact but not much, it's more likely that some JavaScript in your app is causing excessive reflows while the page is rendering.
Summary of stubornella's article (the second link)
Reflow is the process by which elements in a web page get laid out according to the style rules. A reflow is computationally expensive but it is usually possible to draw a static HTML page in a single reflow as long as the rendering of any later elements doesn't effect elements that have already been drawn. Things which are likely to lead to multiple reflows and some work arounds:
Dynamically adding CSS classes to elements - change classes as low in the dom tree as possible to limit the impact
Adding multiple DOM elements - create an invisible structure and add it in a single operation instead
Adding multiple inline styles to visible elements - better to create a class with all the styles, then apply the class
Applying animations to relatively positioned elements - better to animate position: fixed or position: absolute elements as they won't impact anything else
Fine grained animations - moving an element 3px at a time may be more smooth than moving it 1px at a time because you avoid two reflows
Tables are one of the few cases where the rendering of an element later in the DOM can change how an earlier element should be rendered - if you must use tables, use table-layout: fixed
We have also been struggling with the overhead of using extJS - although the framework is very comprehensive, the performance hit (especially with IE6) has been a big limitation. Here are some of the steps we took to optimize the framework:
Streamline the library to only include the packages that are used on your site. This means customizing the jsb2 file and rolling your own extJS deployment.
In our performance testing we've identified the CSS to be the biggest offender. A benefit of using a custom build of extJS is the reduction of unused CSS selectors. To further optimize the CSS, we used Google's Page Speed to identify the CSS selectors that are inefficient to refactor/remove them. Pay particular attention to:
Pseudo :hover selector
Universal * key with descendant selectors
The resulting ext "lite" should yield significant performance gains, particularly in IE6. Although the Secha team are making continuous performance improvements with every release, the overhead of loading the entire framework is too expensive to ignore.
Hope this helps...
Smartoptimizer is really awesome, have you tried any of those types of gzip code compression type tools?
https://github.com/farhadi/SmartOptimizer
Related
The Question:
An invaluable article on the issue - mentioned by JackPattishallJr.
How can CSS have a significantly negative affect on page paint time in a specific area of a web page?
For example:
I didn't know CSS took effect based on the user's location in the page. Does this behavior determine that it does?
Is there conflicting or unusual CSS positioning, animation, etc. that might cause poor performance?
How is CSS styling directly and consistently linked to page performance? Specifically, page paint time.
Update: I've edited the question and examples based on two tests I just did:
Without javascript enabled in my browser, the poor performance issue (surprisingly) is consistent.
After removing the styling of the problematic area, the issue is resolved (But not quite, because now my page is ugly).
Issue with Page Paint Time
I've noticed that my webpage was performing poorly (laggy) at one specific area on the page.
To study the issue, I enabled show paint rectangles and enable continuous page repainting in order to get some readings on the page repaint rate.
Here's a Youtube video that I took to demonstrate the issue.
Here's a healthy reading, in the area of my page that is responsive and smooth:
Here's an unhealthy reading (in the problematic area), where the page's responsiveness is slow and the scrolling is very laggy:
The page performs perfectly, with healthy repainting rates at the top (where the most activity is going on, actually), and performs terribly (nearly stops) at a lower area of the page. It returns to perfect performance when I scroll away from the problematic area.
Update: I completely disabled Javascript and got the same performance issue and readings as before.
Thanks to JackPattishallJr.'s extremely helpful comments, the solution is almost comically simple, so I have recorded a video of the real-time fix for my my issue.
Watch as the removal of a single character of CSS changes everything, instantly.
Lesson learned. Never use a 2000 pixel box shadow. Ever. EVER.
How can CSS have a significantly negative affect on page paint time in
a specific area of a web page?
CSS styling has a very advanced, direct relationship with page paint times, and this article by HTML5Rocks explains and demonstrates it well.
Basically, different style features (and certain combinations of them) have very serious effects on page render weight. This behavior can be observed clearly via the use of chrome's continuous page repainting feature.
If anyone can provide a more elaborative, insightful answer, please do.
Update: I've posted a bounty to promote an answer that will explain this issue in more detail. While the article explains things pretty well, it may not exist tomorrow, so a fully detailed answer is always much better (and often is of greater quality than source articles). And I have neither the time nor understanding necessary.
I didn't know CSS took effect based on the user's location in the page. Does this behavior determine that it does?
It absolutely does because the browser doesn't want to render everything on a page at once. Therefore the spots of the page (if any) that require more to process will be slower than spots that take less to process.
Is there conflicting or unusual CSS positioning, animation, etc. that might cause poor performance?
Since this is a very broad question I'll answer it more broadly than I usually would. Here's an article on what happens during an animation which covers in fair detail what is happening behind the scenes. In essence it says there is a main thread and compositor thread; you want to stay on the compositor side for most of the time. This is precisely the reason why certain properties can "animate cheaply" without the browser having to do too much.
Other reasons that I can think of that would cause more poor performance than usual is if an element's animation or transformation can affect the layout or state of other elements that are not a part of the animation or transformation. It's important to prevent elements being animated or transformed from affecting other elements, especially their layouts, as this forces them back onto the main thread.
How is CSS styling directly and consistently linked to page performance? Specifically, page paint time.
CSS is related to page performance in a several ways. The first is in how much time it takes for the compiler to read the CSS and to apply it to the elements necessary. Writing efficient selectors is important if you're dealing with large stylesheets in particular. You want to cut corners wherever possible.
The second place CSS effects performance is how elements are positioned. If you position 1,000 elements in the same position, it will naturally perform worse than if you have 1 in the same location, regardless of how many can be seen or affect the layout. This is not wholly related to CSS, but CSS positioning is what determines where the elements are, thus how many are affecting performance at once. Changing the layout of elements puts it back into the main thread, which forces more thought on the processor's part in addition to repainting.
The third that you specify in your question is paint time. The article you linked goes into it well, explaining that box-shadow stinks for paint time. There are lot's of reports of this because it exists. This is the essence of your specific problem; the main cause. You should avoid them, especially in bulk, whenver you can. Using gradients instead will likely improve the paint times because they're less expensive.
The fourth is that CSS determines whether or not an animation or transition is rendered using the CPU or the GPU. Although we don't have the feature yet, Sara Soueidan in her article on the will-change property delves fairly deeply into this. In summary, the CPU (Central Processing Unit) is the brains of the computer and takes longer to render things while the GPU (Graphics Processing Unit) is faster at rendering things, but can't "think" as much. At the moment we do tricks like translate3d(0, 0, 0); or translateZ(0px) to force the browser to render it with GPU, but in the future we will have the will-change property.
As Sara says in the article, don't make the GPU handle everything, as the browser is processing it as best as it can, and "some of the stronger optimizations that are likely to be tied to will-change end up using a lot of a machine’s resources, and when overused like this can cause the page to slow down or even crash."
In summary, CSS can significantly negative effect a page's paint time in a specific area of a web page by increasing paint times, changing the way elements are laid out, forcing too many elements to be processed in the CPU or GPU, and how long it takes the compiler to interpret and apply the CSS.
BoltClock was spot on when he commented,
box shadows typically are one of the most expensive to render in most any browser. There is almost no reason to have such a large spread - you might as well use a gradient or something ;)
If your page or part of your page is running slowly, it's best to look into it further to find out what, if anything, is being repainted
Since you have already addressed rasterizing, here's some more information on css performance.
1) Selectors
Here is a talk about some issues Github had with CSS, specifically with selectors and how they can impact page performance: http://vimeo.com/54990931
Slide version here: https://speakerdeck.com/jonrohan/githubs-css-performance
If you aren't careful, css preprocessors can generate some very long selectors, such as this one taken from Bootstrap's dist css:
.table > thead > tr > th,
.table > tbody > tr > th,
.table > tfoot > tr > th,
.table > thead > tr > td,
.table > tbody > tr > td,
.table > tfoot > tr > td {
padding: 8px;
line-height: 1.42857143;
vertical-align: top;
border-top: 1px solid #ddd;
}
2) Multiple instances of SVG XML
Recently I tried using SVG XML to draw and fill up 'star rating' widgets. This worked fine until I placed about 20 instances in page, and then some of them would randomly disappear and/or flicker on mouseover.
3) Using background-image inside a drop-down menu. The image isn't downloaded until the popup is clicked, which creates a noticeably slow load time for users on slow connections. Although the total time is exactly the same wherever you put the image, users noticed it more when the download time was after clicking. So I'm being careful about icons in dropdowns.
Use of gradient images is very common among developers for styling a page. Gradient images are used in many places from styling the navigation bar to styling the background. Technique like repeating a small image in either direction is also common.
One more way to style and give this effect is by using multiple div's one below another with different color, the latter being a little lighter than the former. In the most simple scenario doing so would include only a small script. So, no problem of writing a lot of markup, just some simple code.
The only concern that remains is speed and performance.
Speed
The script, more precisely the function would be much shorter in size than a image. So, in matters of speed the latter method seems more good.
Performance
Today's browsers are very powerful, so the difference between displaying an image and executing a function is negligible.
Css management
Obviously, problems like positioning would be another concern but we do struggle with such problems in every day life. The problem is no greater than overlapping two div's and setting their z-index. The whole gradient div's can lie inside one parent div.
So having addressed the issues of performance and speed isn't using Gradient div's a much better approach than using images?
It's an alternate approach, yes. But not a good one. You get zero points for:
Maintainability
Scalability
SEO
Separation of presentation from content
Furthermore, to say that we needn't worry about performance since today's browsers are more powerful is a gross assumption.
Actually, I think the second option you describe (creating multiple divs with atering colour) is downright terrible.
You're altering markup for the sake of styling. That's a no-go.
It's a common thing among users to disable JavaScript. What happens then?
As you said yourself, positioning mayhem.
When it comes to performance, I would be more cautious than to state it's no longer an issue. Especially with the dawn of mobile browsers in mind.
Such styling would be harder to understand and maintain. Particularly when your team changes someday.
Also, there are two other ways to implement gradients.
CSS gradients - limited to simple variants and requiring a lot of CSS to provide decent cross-browser capabilities. You can try this generator get a taste of these: http://www.colorzilla.com/gradient-editor/
SVG backgrounds. These allow you to create just any gradient you wish. You can use an svg file in your CSS just like any other image. However, some browsers don't support this feature. Here's a table showing when it's an option
Using images is the most reliable option, while combining SVG with normal images (for these browsers that don't support SVG) seems the most flexible approach.
How many div tags in one HTML document would one need before it affects performance? In this case, the tags are not nested and the content within each is minimal (background color/image).
This question is a follow-up on a previous question;
Drawing lines with clickable points using JavaScript
Here I settled on doing this using HTML and CSS.
The <div> tags will have a width of at least 4 pixels, and a total width of 400-800 pixels, thereby 100-200 div tags.
On top of that, there will be five or six of these graphs/timelines stacked on top of each other. The number of div tags is then up in 500-1200.
Again, bearing that there is little content in each, how would this affect the performance?
_L
Test and find out. This will vary too much by rendering engine to answer generally.
While tag count surely has an impact when rendering html you will have to benchmark to see whether or not the time is acceptable or not.
Where I would be concerned is javascript functions that you may have that try to traverse the DOM. Looking through all those elements could be a costly operation on the client. Though once again, proper benchmarking can not be substituted.
The actual displayed size of the div has no noticeable affect on performance. Most of your performance is going to be lost in the transfer of the data to the browser and the rendering of all the elements. It should be a relatively linear decrease in performance luckily, and not something that cascades quickly.
The actual limit doesn't really exist in concrete terms, its more of an issue of the power of the person's computer and browser and connection. Needless to say, you can get pretty big without causing major problems.
The answer depends on a lot of things. Every single div tag has some tiny impact on performance. The tipping point for where performance starts to rapidly degrade will depend on the browser and computer viewing the page.
It also matters what CSS rules you have affecting those styles. Relatively speaking, some CSS selectors are fast to execute and some are slow to execute. If you have some slow CSS selectors defined, your tipping point will come much earlier that if you use no CSS or use only fast CSS selectors. Google's PageSpeed addon can give you insight as to whether you're using slow CSS selectors.
Also, if you're doing things like animating them as a particle system, your tipping point will come even faster.
If its anything like <font> tags, the answer is seemingly millions! Check out: http://www.fujinonbinos.com/ (do a View Source - seriously!)
Seriously, though, keeping things to a minimum is always good practice both for readability (code maintenance) and speed. However, this is unlikely to make a serious impact unless its ridiculous. Even the above example isn't that slow!
Having asked this question How to reach CSS zen?, I now understand that the issues I have are mostly related to positioning. I've found some articles telling that CSS is not always good enough as a layout system.
http://echochamber.me/viewtopic.php?f=11&t=40154
http://www.flownet.com/ron/css-rant.html
http://blog.workaround.org/2009/03/17/dont-abuse-css-for-page-layout/
Do you as CSS designers limit yourselves upfront to designs that CSS can handle? Should I avoid things that seems perfectly easy are in fact difficult to do with CSS?
Of course you limit yourself. As a designer, you should always think about the medium you're working with. If I were designing a magazine ad, I wouldn't be thinking about animations or video. There are certain rules you must adhere to, and it doesn't make sense to ignore that.
But of course, rules were always meant to be broken.
Why?
If you are "designing", why would you limit yourself based on a the limitation of one technology? When you design your site, you should always try to achieve the most usuable interface for the user.
If you do limit yourself, then you are just asking for the site to not be used, and then what's the point of creating it?
I don't limit myself upfront to any designs that CSS can handle (within reason of course), just figure out your design and there will be someway that you can get it looking right using CSS, but it might involve a lot of hair pulling, especially if IE6 is involved!
When implementing a web design (assuming I've got an image/drawing of what the site will look like) I always follow these steps:
I look at the design and determine what components it has. Examples are navigation areas, headers, content areas, and so on.
I implement (X)HTML that can represent the content areas without really taking the design into account (there are certain things such as content order that I use the design to determine.)
I start making the CSS and images needed for the site to look the same way it did in the original design document. Depending on the complexity of the design, I might come up short of elements to use for styling the page, and may end up adding elements that don't really make sense for the content. I try to avoid it as much as possible, though, and I try to create the elements in a way that isn't obtrusive to the content.
As you can see, I never limit the design to the capabilities of CSS. CSS comes last. Now, depending on the complexity of the design, it might not look exactly like it did in the original design document, but the goal is always to make it as identical as possible, while still maintaining clean HTML so that the design can easily be updated in the future.
Most layouts I find can be done with CSS. There are a very few exceptions (normally to do with verically centering text).
For me the main factor which limits my designs is a reluctance to use huge background images. If an effect can't be done by combining/repeating a few tiny bg images I tend to reject or tweak it. Eg a diagonal gradient on a box with curved corners which could be any height might fall into this category using CSS2.1
Almost every painter limits themselves to paint on canvas, almost every sculptor makes 3D shapes from stone or clay or metal...
But there's also the few who dream new dreams and create new things. Some flop, some shine.
Should you limit yourself based on what CSS can do with layouts? Not completely. I say dream big.
Once you've got your dream design, either figure out how to create it, find a technology other than CSS that can do it, or go start inventing!
You can do absolutely almost anything using CSS 2.1 as far as layout. Its a complete pain in the ass that has no reason to ever exist, but you can do rounded corners (using background images), gradient backgrounds (more background images) and all kinds of other bloated crap you don't need all together and still not completely destroy the semantics of your HTML.
Doing all that garbage and still attempting to be standards compliant reduces usability, because its the designers who need round corners and other frivolous crap and not the users. Usability tests have confirmed this. Sites that are bloated to accommodate presentation and usability at the cost of semantics and efficient fail in usability tests compared to their competition. I work for a website that gets several million visitors a day and I have seen the results of our usability tests.
CSS provides a very good way to create an overall design that easily can be changed by small changes in one CSS file, and instantly applies the design changes to all your pages. Of course there are things that are tricky to do with CSS, and in those cases you might want to do it in other ways, but even if your layout is mainly based on CSS, doesn't mean that you can't do some special parts using other technology! You can mix!
So you don't limit yourself when you go for CSS. You just make use of a powerful technology that can be used in perfect harmony along with others!
I have just finished building a heavyweight long sales page, with a lot of elements and varying styles on the page.The CSS has ended up being over specific with its selectors, and there are numerous rounded boxes, background images etc. In short, the CSS is a bit of a mess. (only myself to blame!)
Can anyone suggest a method of going through this stylesheet methodically, in an effort to combine my duplicate properties etc? I doubt there are any tools to do this for me, but I'm wondering how others deal with this situation?
Thanks.
There are in fact some CSS Refactoring tools, which were covered on SO pretty well.
I can't vouch for them, though, since I always refactor by hand. My technique is to separate existing styles into:
Layout
Typography
Colors (Look & Feel)
Hacks
That's usually a quick copy & paste job. From there, similarities and redundancies are a lot more apparent, so combining and simplifying gets much easier.
With that done, having a TOC at the top of the page makes your sections easy to find, and generally easier to search.
Combine CSS to their shorthand properties if possible.
Take advantage of unique dom ids to apply styles to the children of that element.
You can use multiple CSS classes on the same element, for example class="somestyle some-other-style". Using this you can take duplicated CSS styles and define them in one.
Use the * selector to apply styles to all the children.
If its all in one big CSS file, split the code into sections where the styles are relevent to the pages across your site, i.e /* MEMBERS PAGE */
Run the style through an online compressor to reduce code size. Some even combine elements automatically for you, further adding less complexity.
That should get you started. It's hard to add further, it really depends on how your html code and structure is set out. If you could provide an idea we could assist further.