Nader K. Rad
Nader K. Rad

Reputation: 59

Inline only the critical CSS, or the whole 15kb of CSS, when the first page view is the most important one?

I was wondering if it’s a good idea to split my CSS into two parts, an inline critical one and a deferred external one.

My whole CSS is 15kb (minified). The critical CSS that the online “Critical Path CSS Generator” analyzer gives me is 1kb, but when I check my code, I really believe that 5kb of the CSS is needed to render all the above the fold content on a 1920x1080 screen. So, my first concern is, is it worth splitting the CSS when one-thirds of it is needed as critical CSS, or shall I just inline the whole CSS, given that it’s not so large (15kb)?

On the other hand, what I’m focused on here is one part of our whole website, where encourages users to take an action, and the action is to go to another part of the website, which has another CMS. So, for this part that I’m talking about, the number of page views for each user is not so high: about 70% of people open only one page here, and 92% open less than 4 pages. Therefore, having an external CSS that is cached may be less important in our situation I guess. Finally, I have the feeling that the first page view is the most important one; if we can increase its speed a little bit, even if it decreases the speed of next pages, it would be worth it. However, I don’t know if having inline CSS instead of external really makes a difference in speed when HTTP/2 is used.

So, what would you suggest? Is it better to split my CSS and inline only the critical part, or simply inline the whole file? Thanks for the help.

Upvotes: 2

Views: 676

Answers (1)

Barry Pollard
Barry Pollard

Reputation: 45940

The general rule is send as little as you need - why send unnecessary data and waste download time and bandwidth? So if you can inline just your critical css for 1kb then do that, if you need 5kb then go with that. The main reason to include the full 15kb would be to avoid the complexity of figuring out the critical or necessary css, but you seem to have figured out this problem.

Some also argue about keeping the critical data for the first paint (including the inlined css and the HTML) in the first 14kb of the page - this is due to the way TCP works and the fact it can send 10 packets initially before it expects any acknowledgement. So anything larger than 14kb will require an acknowledgement and so a round trip and so a delay. After this the amount TCP can send before requiring an acknowledgement (the CWND) grows exponentially but it starts small. Personally I’m not convinced that 14kb number holds true anymore; SSL/TLS negotiation (assuming you’re using HTTPS) takes up some of that 14kb also requires round trips, and then HTTP/2 (again assuming you are using that) requires further kbs and round trips to send the initial messages, all before your HTTP request is sent and received. So by the time this all happens the window size will either be a fraction of the 14kb, or have already grown exponentially to a larger size. Still, the general principal of keeping it as small as possible to allow more of the page to download quicker is still valid - just don’t necessarily fixate on that 14kb number.

Whether you chose to inline CSS at all is entirely up to you. The speed gains are impressive, and you are right that first page views are typically more important, but there are downsides, including the fact it requires a build step to figure out what CSS to include and then to include it, the fact is duplicates the data across pages, the fact you may need to release all web pages with it inlined if you ever change your CSS (as opposed to just releasing the CSS file)... etc. Personally, unless your are a super busy and super optimised site (e.g. the Google home page), I think the added complexity isn’t worth it. More of my thoughts on it here: https://www.tunetheweb.com/blog/inlining-css-is-not-for-me/

Does this change under HTTP/2? Well yes and no. In theory HTTP/2’s multiplexing means multiple requests can be on the go at the same time so you don’t need to fire up another connection to request the CSS so you may not need to inline at all. However this still requires a round trip to request the CSS after getting the HTML so is not as fast as inlining, even if it’s faster than HTTP/1.1 (where you would need to wait for the HTML to completely finish downloading to allow the connection to be used for the CSS request, or fire up another connection with the TCP and HTTPS delays that entails).

HTTP/2 Push was supposed to resolve this - keep the CSS as a separate file, but when the HTML is requested answer back with the HTML file and the CSS file (push the CSS file). No round trip delay and still a separate CSS file - best of both worlds. The reality is, as ever, a little trickier. The main issue is how to avoid pushing the CSS again for any subsequent pages (which has same downsides as inlining). There are varies ways of doing this but a cookie based implementation is probably the best and most practical at the moment. Even with this there are other complexities and bugs to consider. HTTP/2 push has failed to really take off as an inlining replacement because of this.

Upvotes: 1

Related Questions