Consider HTTP/2.0 server push CSS stylesheet alternative to in-lining CSS

135 views
Skip to first unread message

Andy Thompson

unread,
Jul 13, 2017, 3:56:53 PM7/13/17
to pagespeed-insights-discuss
PageSpeed Insights says since my website has a CSS link in the header, "Your page has 1 blocking CSS resources. This causes a delay in rendering your page."

I've added it to be server pushed in HTTP/2.0, which most browsers support. This means it's almost equivalent to CSS inlining, yet the above message still displays.

I think it would make sense to consider HTTP/2.0 server push to be as good as CSS inlining for performance. Is it possible this could be updated?
Message has been deleted

Andy Thompson

unread,
Jul 14, 2017, 5:30:28 PM7/14/17
to pagespeed-insights-discuss
I should add that one reason server push is better than in-line css, is Content-Security-Policy headers don't need to add unsafe-inline, which by it's name is unsafe due to XSS being able to change things.

Thomas Schulz

unread,
Jul 21, 2017, 9:47:56 AM7/21/17
to pagespeed-insights-discuss
+1 for this.

Carlos Lizaga Anadon

unread,
Jul 27, 2017, 3:35:01 PM7/27/17
to pagespeed-insights-discuss
Hi Andy,

The rule basically says that you need to load synchronously just the necessary amount of CSS to render your website on a typical 1024 x 768 px screen (the current average size).
That actually means that you should be able to inline said CSS in your head using <style> nodes and just load asynchronously the rest of the CSS needed to complete the full render.
Please, keep in mind that there's a limit on the <head> size that might not exceed 14-16 KB.

Also, for certain cases you might want to use <style scoped> node.

Best regards,
Carlos.

Andy Thompson

unread,
Aug 6, 2017, 5:32:45 AM8/6/17
to pagespeed-insights-discuss
Securely inlining is a lot of effort though, compared to adding a HTTP header to trigger HTTP 2.0 push.

Whether it's comparable in performance as inlining doesn't really factor into whether the Insight checks should rate it as bad as not HTTP pushing it, as it's clearly much better than doing nothing.

Joshua Marantz

unread,
Aug 6, 2017, 5:31:36 PM8/6/17
to pagespeed-insights-discuss
Actually it is not at all clear that http push is better than doing nothing.  If you push a non-critical resource you may slow delivery of critical resources when bandwidth is limited.

The main question for me is whether/how you have partitioned critical vs non-critical css.  

Second question is how to deliver critical CSS: inlining and h2 push are both options with since pros and cons.  IMO h2 push wins if the h2 server or proxy attempt to model the browser cache and only push css to clients that don't already have it.  Inlining wins otherwise and in particular when browsers or proxies don't support h2.

Third question is how to delay-load non-critical CSS.  I am skeptical of solutions that don't involve both RAF and setTimeout.  Loading css from end of body is not sufficient.


On Aug 6, 2017 5:32 AM, "'Andy Thompson' via pagespeed-insights-discuss" <pagespeed-ins...@googlegroups.com> wrote:
Securely inlining is a lot of effort though, compared to adding a HTTP header to trigger HTTP 2.0 push.

Whether it's comparable in performance as inlining doesn't really factor into whether the Insight checks should rate it as bad as not HTTP pushing it, as it's clearly much better than doing nothing.

--
You received this message because you are subscribed to the Google Groups "pagespeed-insights-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pagespeed-insights-discuss+unsub...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pagespeed-insights-discuss/0cac03df-f72f-41a2-a204-6b4df492d2d0%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Andy Thompson

unread,
Aug 7, 2017, 12:36:06 AM8/7/17
to pagespeed-insights-discuss
Just to be clear, I wasn't meaning h2 pushing the full CSS content, only the critical path CSS as a separate file.

Also I'm not saying this should replace the CSS inlining rule, only that it be another option. Both options don't have to be as good as each other.


On Sunday, August 6, 2017 at 10:31:36 PM UTC+1, Joshua Marantz wrote:
Actually it is not at all clear that http push is better than doing nothing.  If you push a non-critical resource you may slow delivery of critical resources when bandwidth is limited.

The main question for me is whether/how you have partitioned critical vs non-critical css.  

Sure, but that's the same question as for CSS inlining, someone could easily have just inlined their full CSS files.

Second question is how to deliver critical CSS: inlining and h2 push are both options with since pros and cons.  IMO h2 push wins if the h2 server or proxy attempt to model the browser cache and only push css to clients that don't already have it.  Inlining wins otherwise and in particular when browsers or proxies don't support h2.
It's not all about being the fastest, it's also how it's implemented. If you want best security on a site that takes user input, then you're using CSP headers and blocking unsafe inline css. You have to then either nonce it or hash it to solve a specific case without adding "unsafe-inline", whereas with H2 push you just push it.
 

Third question is how to delay-load non-critical CSS.  I am skeptical of solutions that don't involve both RAF and setTimeout.  Loading css from end of body is not sufficient.
This also isn't a question relating to H2 push specifically. Non-critical CSS would be implemented the same way for the h2 and CSS inlining approach. 

If we're talking about h2, then we're also talking about HTTPS, so there's not a lot most proxies can do with the connection anyway.

As for server support, if you're going to h2 push, your server is going to support it.

Carlos Lizaga Anadon

unread,
Aug 7, 2017, 5:18:29 AM8/7/17
to pagespeed-insights-discuss
Hi,

I don't see major problems loading the critical path CSS in an <style> node if you've access to the separate file. 
Unless you're using an H2O http/2 server you would have to implement something to read user's cookies in order to know if you have to send him the resource or not.

While I see that H2 push will have benefits over inline, I do think that it is harder to implement properly.

Andy Thompson

unread,
Aug 7, 2017, 7:15:34 AM8/7/17
to pagespeed-ins...@googlegroups.com
You don't actually need to do the checks and avoid push to get the same network level benefit as CSS inlining, which would also send the same styles every request.

I can see there might be some tiny performance benefits of inlining over it though, but this won't be anywhere near as significant as waiting for a 2nd request/response. 

Certainly clever logic to avoid the push when unneeded is worth points too though, but hard to achieve.
--
You received this message because you are subscribed to a topic in the Google Groups "pagespeed-insights-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/pagespeed-insights-discuss/_diiYU73r8A/unsubscribe.
To unsubscribe from this group and all its topics, send an email to pagespeed-insights-...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pagespeed-insights-discuss/9f607796-5043-4a0e-8bad-7508b3a6880b%40googlegroups.com.

Joshua Marantz

unread,
Aug 7, 2017, 10:33:36 AM8/7/17
to pagespeed-insights-discuss
RE csp: that is a good point.  You would need to construct nonces for inline blocks. 

RE server support: that is not a given, just because you add h2 preload hints in your application logic doesn't mean the server will handle them.  But obviously you know about your server when you make that decision.

RE push speed vs inlining... It ought to be good enough but we (mod_pagespeed team) have had a lot of trouble proving that with measurement.  It would be great to see evidence of it working well in practice.


On Aug 7, 2017 7:15 AM, "'Andy Thompson' via pagespeed-insights-discuss" <pagespeed-ins...@googlegroups.com> wrote:
You don't actually need to do the checks and avoid push to get the same network level benefit as CSS inlining, which would also send the same styles every request.

I can see there might be some tiny performance benefits of inlining over it though, but this won't be anywhere near as significant as waiting for a 2nd request/response. 

Certainly clever logic to avoid the push when unneeded is worth points too though, but hard to achieve.

On 7 Aug 2017, at 10:18, Carlos Lizaga Anadon <carlos...@gmail.com> wrote:

Hi,

I don't see major problems loading the critical path CSS in an <style> node if you've access to the separate file. 
Unless you're using an H2O http/2 server you would have to implement something to read user's cookies in order to know if you have to send him the resource or not.

While I see that H2 push will have benefits over inline, I do think that it is harder to implement properly.

El lunes, 7 de agosto de 2017, 6:36:06 (UTC+2), Andy Thompson escribió:
Just to be clear, I wasn't meaning h2 pushing the full CSS content, only the critical path CSS as a separate file.

Also I'm not saying this should replace the CSS inlining rule, only that it be another option. Both options don't have to be as good as each other.

--
You received this message because you are subscribed to a topic in the Google Groups "pagespeed-insights-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/pagespeed-insights-discuss/_diiYU73r8A/unsubscribe.
To unsubscribe from this group and all its topics, send an email to pagespeed-insights-discuss+unsub...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "pagespeed-insights-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pagespeed-insights-discuss+unsub...@googlegroups.com.

Carlos Lizaga Anadon

unread,
Aug 7, 2017, 11:02:54 AM8/7/17
to pagespeed-insights-discuss
I found these two articles really nice:

This one speaks about rules and case studies that Chromium Team found: https://docs.google.com/document/d/1K0NykTXBbbbTlv60t5MyJvXjqKGsCVNYHyLEXIxYMv0/edit
This one speaks about the difficulties found trying to implement h2 push properly: https://jakearchibald.com/2017/h2-push-tougher-than-i-thought/

Worth a read.

Andy Thompson

unread,
Aug 8, 2017, 2:04:21 AM8/8/17
to pagespeed-ins...@googlegroups.com
I'm h2 pushing my CSS on https://andytson.com/, but that's all of it, not critical path. That said there isn't too much to split off as far as I know.

I thought of another reason people may prefer h2 push to CSS inlining:

CSS files you can gzip transfer encode in all situations (if accepted). HTML with CSS inlining you can only securely gzip transfer encode if there are no sensitive tokens in the HTML response (unless varying the content of the page every request).

I don't actually know if any h2 push implementations reuse the original request's accept-encoding to allow content negotiation. That said, it'd be disappointing if a http client supported h2 push without allowing decompression.
Reply all
Reply to author
Forward
0 new messages