I've inherited a css file (10k lines), which I think is responsible for an insane cycle of style invalidation, recalculation, redraw. I figured this out by removing the css file from the page, which results into the disappearance of the cycle.
The file was created over time by several people, and no one is left with a full knowledge of the css content...
From the profiling attached, there's no Network activity, or JS event that could pinpoint at another root cause (such as DOM changes using JS).
In your view, what would be the best approach to find what triggers the view changes? There's no animation on the page, but I can't guarantee that there isn't one spinning on its own using an old css directive that nobody uses anymore...
The repaint causes fairly high cpu usage.
thanks!
It might not be the best solution, but I'd remove the bottom half of the css code and check if the problem still exists.
If it is solved, you now know it is in the bottom half, if it still exists the problem is in the top half.
Keep halving the code which should contain the problem, and in about 9 iterations you can have it narrowed down to about 20 lines.
Related
I've been using latest Kendo grid for ASP.NET MVC.
Data table specs are like this,
columns --> 25 to 35.
rows --> anywhere between 1500 to 5000.
client side paging --> 20 rows
Issue is, when I'm doing the scrolling, IE 11 takes upto 1s to display data depending on screen resolution and grid content height. Which causes the UI glitch.
When I ran IE UI Responsiveness from Dev Tools, I got the below results.
I get that whenever user does scrolling, browsers have to render the rows and it takes a bit time. But IE 11 takes it to a whole new level. The moment it has to process 3-4 more rows, it starts acting jumpy and glitchy.
I did the testing in Chrome (& opera), Firefox. In which performace was very decent.
I tried to refractor CSS to reduce styling, but there's very little bit change I could afford.
Please let me know what is the next step? Should I keep calm and blame IE?
The grid works fine on its own in IE11, my team uses it.
It could be you've added some code that's being executed excessively.
The UI responsiveness tool isn't very useful. Try using the profiler in IE's Dev tools. Open the page with the problematic grid in it, hit the green arrow of the profiler to start recording, scroll the grid a bit and then hit stop in the profiler.
Sort the results by Count, Inclusive time and Exclusive time and see what stands out. After each sort look at the top ~50 entries for code you wrote.
When sorting by Count, you might find a piece of code that while is pretty short, it runs hundreds of thousands of times in a loop for no reason because of a simple mistake.
Sorting by time can show you pieces of code that are very demanding and perhaps could be moved to other places.
For instance, it could be you're running some logic on the view like formatting a date. If you see such a function in the profiler, it would be better to move this logic to the data fetching phase before the view is rendered.
There's an issue with a file named angular-material.css which causes a slow scroll like you describe. I've seen several places, like this one, that state removing the file or several lines in it solved the problem.
Are you using angular in your project? If you do, see if you have this file and try to remove it.
Because this question crossed 1000 views, I'm obliged to answer on how I fixed my issue.
Turns out, rendering of IE is slow when it comes to bigger screen of HD/FHD resolutions. So, the solution I followed was to promote the grid to new layer by adding the following to grid's CSS class.
.promote-new-layer{
transform: rotate(0deg);
will-change: transform;
}
will-change might not work in all the browsers. Hence the fallback would be to use transform:rotate(0deg).
Please ensure while doing so, you are not promoting unnecessary nodes.
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.
I am a self-taught web designer with a staggering 3 sites or so under my belt. I just finished the first page of a website for a client who is a friend and therefore a lot more patient than a "real" client would be.
I love the way the sites looks, it is fairly consistent in the spectrum of popular browsers, and overall I was quite proud of it until I realize a major problem that to be honest is about two steps away from making me drop my dream of becoming a web designer.
When using Chrome, Safari, or older versions of Explorer the website's layout falls apart if someone has their zoom set to anything other than 100%.
It is frustrating me to the point of near depression. I used a div to surround the whole body, and the pages layout, which in this case is a MENU is done almost entirely with ULs (unordered lists) positioned absolutely.
The site is made up in such a way that all the parts connect (almost like a puzzle) and if some parts are out of line, it is dreadfully obvious.
I heard the zooming rounds up figures and could call for a couple of low alpha pixels here and there, but in my case some block elements are literally 25-50 pixels out of place.
http://www.stevemarcella.com
No need to get your dreams crushed just yet :> There is always hope.
First thing you should do is check all of the errors, which according to validator are 536 errors on the homepage.
I suggest you run the validator and correct errors one by one. It could solve your problems. First error I noticed is that you have a div element outside of body. You should keep everything inside the body tags.
This is outside of body.
<div class="wrapAroundBody" id="IdWrappingWholeBody">
Hope it helps.
Is there a way, without javascript, to load a small image for a background before the real image is downloaded? Without javascript because I know how to do it with it.
I can't test if the following CSS3 would work because it works too quick:
body {
background-image:url('hugefile.jpg'), url('tinypreload.jpg');
}
If the tinypreload.jpg is only, say 20k, and the hugefile.jpg is 300k -- would this accomplish the task? I assume that both downloads would start at the same time instead of being consecutive.
Update
Timing the results using Firefox's profiling revealed that it's not practical / not worth it to load a smaller background first. Main reason is the connection time. For tiny pictures it's the same time to connect as it is to download the content. For images where this becomes worth it -- the file size is not recommended for mobile.
If you still want to achieve this effect - combine all your "necessary" images into 1 file and display them as cropped background with correct offset. Load your high-res images through javascript, and update the content afterward.
You could exploit css load order and overrides to achieve this result.
Try loading the small image from your main css file and then put a <style></style> tag at the bottom of the html page. The inline style will override the main style but will load last because of it's position in the code.
The difference would be milliseconds though, so it may be too quick. It's also hacky and would result in invalid, but working code. Worth a shot though.
If you're trying to fix a mobile problem then have a look at this article on context specific images as that might be a more effective way to go.
This article on CSS3 multiple backgrounds may also help, as you may be able to exploit the stacking order to achieve the result you're after
It would be useful to know what problem you are trying to solve beyond load order, as it's hard to give advice on this one.
As I said in my comment you can use the 'net' tab in firebug for firefox (called timeline in chrome) to see the actual load order on your page - you can even filter it (on firefox) for CSS only or images only - this will enable you to test.
IF i want to load any image quickly should i use as a css background not in ? I think difference only will show in low speed internet connection.
I saw many articles related to css only preloading they all are using images in css background.
http://perishablepress.com/press/2008/04/15/pure-css-better-image-preloading-without-javascript/
http://perishablepress.com/press/2007/07/22/css-throwdown-preload-images-without-javascript/
http://divitodesign.com/css/create-an-image-pre-loader-with-css-only/
It's all about the order in which things happen. Browsers are at liberty to begin processing things as soon as possible, so, in the average page with the css defined in the head, it is able to start requesting and recieving images from the css before it would be able to do so from the body of the document.
So in short, the answer is yes.
But... bear in mind that it doesn't actually load the images any faster. All you are doing is changing the load order, not the absolute speed. The images will still take the same amount of time to load. If you move everything out of the body and into css in the head, you are still left with priority decisions as to which ones to load first. So you come full circle. You can't make everything faser than everything else.
This is clearly browser-specific. Besides, there is no logical reason it should be the case, and wouldn't quite make a difference even on low-speed connections. Even if there was a 200 ms delay between the starting load time of an image on a page and of an image in a CSS rule, the end user would never notice it.
If you have to do a web page for low-speed connections, the solution isn't really to "optimize" that way.