HTTP/2 Push / Wordpress not working

Hi team - trying to get LCP time down. Have tried lots of things and was hoping HTTP/2 push of “above the fold” hero image would help but can’t seem to get the HTTP/2 Push to work.

Example page: The Perfect Customer Satisfaction Survey Email Template
WordPress with CloudFlare Plugin installed and configured
define(‘CLOUDFLARE_HTTP2_SERVER_PUSH_ACTIVE’, true); - added to config.php file
Have even added an HTML preload element to the web page: <link rel="preload" as="image" href="/wp-content/uploads/Typewriter-e1607663932776.jpg">

Looking at the Chrome Network report nothing is reporting as Push/Other.
Webpage Speed test report of same page: (WebPageTest Test Details - Dulles : www.gen...ey-invitation/8748 - 05/06/21 06:21:51)
WebPageTest Test Details - Dulles : www.gen...ey-invitation/8748 - 05/06/21 06:21:51 doesn’t show PUSHED for image either

Any suggestions or assistance much appreciated.

In the future HTTP2/Push & HTTP3/Push will most probably be removed anyway so I would not rely on that, see:

I would go for all the other recommendations GPSI will provide to you once you test your site with it.

To Push (if you use Apache) please do it like this:

Header add Link "</assets/app.min.css>; rel=preload; as=style"

Adjust the Link /assets/app.min.css to match your assets. Just adding the Link to the header wasnt enough for me, for me it begun to work after pushing with my server to CloudFlare.

Also make sure HTTP2 Push is activated on you origin server:
https://httpd.apache.org/docs/current/howto/http2.html#push

I anyway would recommend opting to use Early Hints as they most probably will be the future

EDIT:

after some other tests Pushing also stopped for me on other sites where it actually pushed before.
Tested on latest Chrome (Version 90.0.4430.93 x64 Win 10)

2 Likes

Thanks for that info - I wasn’t aware of the dropping of HTTP2 Push. Very frustrating as I’ve been working on getting it working for a couple of days.

It feels like back to the drawing board on getting my LCP times down. Have been working through the GPSI data but it’s a nightmare on WordPress sites when you’re using plugins and page builders. Soo many JS and CSS files.

+1

Conclusion: dont use WordPress

But even WordPress sites can easily achive GPSI (mobile) of about 85-90 its just harder if pages/templates are not set up properly and with the mind of achiving good scores

Easier said than done in a small business with limited resources. :frowning:

If you have any go-to resources on how best to achieve it I’m all ears.

Thanks.

If it’s just the hero image, have you tried using a progressive JPG?

1 Like

I hadn’t but the problem doesn’t seem to image size, it’s only 22KB. The problem seems to be that it takes a long time to be discovered and start downloading - which is why I though PUSH would be a good approach.

How about a prefetch in the header?

<link rel="prefetch" href="http://www.example.com/wp-content/uploads/my_image.png">

p.s. I’m a big fan of push and have used it for fonts. I’d be sorry to see it go.

1 Like

Thanks for the idea: I hadn’t tried rel="prefetch" but just tried it then.

Seems to be downloading at almost exactly the same time as the hero image, but now downloading two copies. So no speed up in the LCP. :frowning:

1 Like

The problem with your site is:

  1. priorities

You need about 136 ressources to display your whole page.
You preload 25 CSS Files which you are preloading.

As @sdayman already mentioned you can prefetch the ressource. This would result in:

  • first loading 25 CSS files
  • then display the picture
  • after PageLoad: pre-fetching (also pre-rendering) the picture again due to prefetch

Better would be also preloading the image.
The order or the meta-links “preload” defines the order how they should be processed/prioritised

I on my pages go with:

<link rel=preload type=image/webp as=image href=/assets/IMAGE.webp>

So I would recommend you:

  1. combine all CSS into one (also preload just that big one)
  2. convert to webp even if your image is not big
  3. preload the image before preloading the CSS files (order)
  4. defer ALL JS till “DOMContentLoaded” then execute it so it does not produce renderblocking.
  5. create critical CSS which you include as inlineCSS in your header (before the preloads etc)
  6. use static Caching - the slower your server responds the later the FCP/LCP is hit.
  7. defer pictures in general! LCP (Last Contentful Paint) is not just what you see first, because if you have big CLS your content can shift and then also things that you normaly do not see are also be added to “LCP” as they have been above the fold before somewhere while the page loaded.

That should give you a fair bootst in FCP

EDIT:

You can also use Cache Everything on “https://www.genroe.com/blog/*” as this Blog seems to be static. But please do not forget then to install the CloudFlare Plugin (or “Sunny” or something like that) to automatically on changes purge the respecting URLs.
This again will give you a good boost in TTFB

1 Like

I believe you guys are having the wrong idea about prefetching. As opposed to preload, which preloads an asset to be used on the current page, prefetching is for resources expected to be used on the following pages (under the assumption the user will click to see them.) These HTTP/2 hints can be quite confusing, as there’s also DNS-prefetching, which applies to assets on the same page! IMHO prefetch should be used in rare cases. Resource Hints - What is Preload, Prefetch, and Preconnect? - KeyCDN

As for the original question, I see that Cloudflare HTTP/2 push is working as a header for it is added, with 25 links (CSS and JS). Cloudflare documentation says the limit is 50 files. I don’t know for sure what’s preventing Cloudflare from pushing the images. Could this be a result of the “lazy loading” instruction, which goes in the opposite direction of a preload?

<img width="560" height="373" src="https://www.genroe.com/wp-content/uploads/Typewriter-e1607663932776.jpg" ... loading="lazy" />
1 Like

Thanks for the tip. Without Push, I was hoping something else could load that image earlier. Lazy loading shouldn’t trigger because the image is in the viewport. So that pretty much leaves us with something like a progressive JPG to get something in there ASAP.

In the end though, as @M4rt1n says, the page as a whole needs to be way more efficient.

2 Likes

Yes thats also why it loads the image twice with prefetch.
I will correct my answer. Thanks for pointing out! Anyway the recommendation going with preload for me was right.

As he complained about the LCP (Largest Contentfull Paint) a progressive JPG would not solve this as it would not change when the image finishes painting/rendering

3 Likes

Exactly, it’s unnecessary here. But it won’t trigger at the JS/browser level, while the decision by Cloudflare plugin to add a HTTP/2 hint is of course done at the server/PHP level. So my idea here is that perhaps when Cloudflare plugin gets the page somewhere down the WordPress pipeline, it sees the HTML requests for images with a lazy-loading command and decides it shouldn’t include them as part of the push bundle. Just a wild guess, I really don’t know why images aren’t being pushed.

Why it is not getting pushed are the following reasons:

  1. http2 Pushes can be implemented at the webserver (Apache or Nginx). Which should look like this:
Header add Link "</wp-content/uploads/Typewriter-e1607663932776.jpg>; rel=preload; as=image"
  1. http2 Pushes can be implemented by PHP for example, but just
<link rel="prefetch" href="https://www.genroe.com/wp-content/uploads/Typewriter-e1607663932776.jpg">

is included which will not trigger http2/pushes, NOR preloads.
Could be realised with PHP like this:

header("Link: </wp-content/uploads/Typewriter-e1607663932776.jpg>; rel=preload; as=image");

But there are plenty of plugins which will do this for you. Anyway this is missing in the response header.

I now also tested FireFox against Chrome and yes FireFox still accepts pushes while Chrome does not anymore… at least for me.

Correct, but as he uses WordPress this probably is getting implemented somewhere where he can not change this. Anyway this will not affect the behaviour of preloads/pushes so there is no impact on this function.

First off - thank you to everyone for taking the time to respond. Also thank you - as my issue has caused discussions and differing viewpoints - I see that it is a difficult thing to fix, i.e. I don’t feel I’ve asked a dumb question.

I’ll review things in detail and proceed:

  1. Assume HTTP2 Push is no longer useful
  2. Try to reduce # of CSS files and combine them - I had them combined in the past but the WP Rocket plugin explicitly states to not combine them under HTTP2!
  3. Lazy-Loading: this is a “feature” in a recent version of WordPress - it now automatically adds lazy loading to all images. Turning it off for the above the fold images has proven, difficult…
  1. WordPress is a great, prebuilt/lots of plugins but also terrible because if you want to retain upgrade ability with new versions of plugins and themes you can’t patch them easily to point fix small things like this. @M4rt1n is exactly correct here.
  2. I’ve upgraded my CloudFlare account for more caching

I’ll keep working on it.

  1. I think why people advise against combining CSS with HTTP/2 is because /2 is supposed to load everything in parallel, eliminating the need to try to combine for speed. In fact, that may even slow things down as 4 small files in parallel will finish loading before 1 large file.
  2. I wouldn’t worry about disabling lazy loading for above the fold, as that shouldn’t trigger.

Yep - that’s exactly what WP Rocket says. But I may be over doing the number of files - 25 CSS files is excessive. Plug-in bloat.

1 Like

I definitely recommend installing the cloudflare wordpress plugin. If you already have it installed, you may need to click the apply recommended settings for cloudflare button again in the plugin if you have not done it for a long while. As the plugin gets updated, new optimizations are sometimes pushed, and I don’t think it auto applies new optimizations without clicking the button.

I’m not a fan of that setting, as it often changes things I already specifically set. But the plugin does link to the support document that lists the settings: