BoldGrid / w3-total-cache

GNU General Public License v2.0
152 stars 85 forks source link

W3TC “eliminate render-blocking CSS” causes Facebook to miss og:image tag #292

Open mavas84 opened 4 years ago

mavas84 commented 4 years ago

When the option Performance > Minify > Eliminate render-blocking CSS by moving it to the HTTP body is enabled, neither Facebook nor Twitter will parse far enough to see the meta tags for images Reference topic: https://wordpress.org/support/topic/w3tc-eliminate-render-blocking-css-causes-facebook-to-miss-ogimage-tag/

maxicus commented 4 years ago

No easy fix for that due to

<link rel=stylesheet href="a.css">
<style>some inline styles modifying a.css content</style>

so content cant be moved.

Similar effect can happen even if theme pushes a lot of inline styles, so more clean fix is to increase priority of hander adding what should be done in plugin adding those 's.

DaveHamilton commented 4 years ago

Just a note that this same thing which effects Twitter and Facebook also affects Bing's search crawler, meaning all pages from affected sites appear in Bing with errors such as no title tag, no description, same canonical link, etc. It effectively neuters a site in Bing, Facebook, Twitter (and those are just the three we've found thus far... I'm sure there are more parsers which limit their maximum size-parsed-per-page).

Taking @maxicus's comment into consideration, maybe the layout of the section needs to be considered here, putting all the non-style tags well-ahead of all this other stuff?

maxicus commented 4 years ago

@DaveHamilton which plugin do you use for adding metas? Also, do you have tag below css? Normally themes have it rendered first, so it should be available to parser with limit...</p> </div> </div> <div class="comment"> <div class="user"> <a rel="noreferrer nofollow" target="_blank" href="https://github.com/DaveHamilton"><img src="https://avatars.githubusercontent.com/u/1993106?v=4" />DaveHamilton</a> commented <strong> 4 years ago</strong> </div> <div class="markdown-body"> <p>@maxicus We have Yoast putting our metas in, and all our meta tags (and <title> tags) are above the calls to our CSS. The problem (for us, at least, and presumably for others, too), is that when "eliminate render-blocking CSS" is enabled, it puts the CSS above those meta and title tags, regardless of where it would otherwise be placed.</p> </div> </div> <div class="comment"> <div class="user"> <a rel="noreferrer nofollow" target="_blank" href="https://github.com/DaveHamilton"><img src="https://avatars.githubusercontent.com/u/1993106?v=4" />DaveHamilton</a> commented <strong> 4 years ago</strong> </div> <div class="markdown-body"> <p>We were talking about this and had an idea: what if we put a tag in to <em>tell</em> W3TC exactly where to inject it? If the tag doesn't exist, then you do what you're already doing by default, but this allows the user to have control if/where they need it.</p> <p>So, for example, something like:</p> <pre><code><title> <meta blah blah> <meta blah blah blah> <meta more blah blah> <!--W3TC Insert CSS here--> <style>some inline style</style></code></pre> <p>etc...</p> </div> </div> <div class="comment"> <div class="user"> <a rel="noreferrer nofollow" target="_blank" href="https://github.com/maxicus"><img src="https://avatars.githubusercontent.com/u/541402?v=4" />maxicus</a> commented <strong> 4 years ago</strong> </div> <div class="markdown-body"> <p>@DaveHamilton fresh WordPress installation with Yoast have title, description and other metas above the first <style> or <link> tag and therefore all minified assets and content placed by W3TC also below it. Seems that issue is theme/plugin-specific when theme/plugin decides (incorrectly) their styles are more important than metadata.</p> <p>You may force W3TC's placement to offset everything it adds to end of head tag by the code below. As I wrote earlier, it's not all-win solution since it may change the order of styles when inline ones applied and overwrite what is told by css files (it's BTW a sign of ineffective CSS of theme used, but quite common practice).</p> <pre><code>add_filter( 'w3tc_minify_css_step', 'my_w3tc_minify_css_step' ); function my_w3tc_minify_css_step($i) { $head_end_pos = strpos( $i['buffer'], '</head>' ); $i['buffer'] .= 'xx1 ' . $i['embed_pos'] . ' ' . $head_end_pos; if ( $head_end_pos >= 0 && $i['embed_pos'] < $head_end_pos ) { $i['embed_pos'] = $head_end_pos; } return $i; }</code></pre> <p>Let me know if that helps in your case.</p> </div> </div> <div class="comment"> <div class="user"> <a rel="noreferrer nofollow" target="_blank" href="https://github.com/DaveHamilton"><img src="https://avatars.githubusercontent.com/u/1993106?v=4" />DaveHamilton</a> commented <strong> 4 years ago</strong> </div> <div class="markdown-body"> <blockquote> <p>@DaveHamilton fresh WordPress installation with Yoast have title, description and other metas above the first <style> or tag and therefore all minified assets and content placed by W3TC also below it.</p> </blockquote> <p>So... this gets interesting, because that's exactly what our site does, too. I have this page excluded from W3TC's Minify settings, so you can see. <a href="https://www.macobserver.com/news/product-news/sonos-s2-app-room-groups/">https://www.macobserver.com/news/product-news/sonos-s2-app-room-groups/</a> (you can ignore the embedded Ezoic script — that's happening well <em>after</em> the server upon which W3TC runs.</p> <blockquote> <p>Seems that issue is theme/plugin-specific when theme/plugin decides (incorrectly) their styles are more important than metadata.</p> </blockquote> <p>This is entirely possible, of course! :) In fact, we went in presuming this, but then we saw the first <style> tag well below the Yoast stuff... so we're not sure what it is we're doing wrong. </p> <p>Maybe something other than the first <style> tag is the trigger for W3TC?</p> </div> </div> <div class="comment"> <div class="user"> <a rel="noreferrer nofollow" target="_blank" href="https://github.com/maxicus"><img src="https://avatars.githubusercontent.com/u/541402?v=4" />maxicus</a> commented <strong> 4 years ago</strong> </div> <div class="markdown-body"> <blockquote> <p>So... this gets interesting @DaveHamilton it is.</p> </blockquote> <p>On a fresh WP in it's root I did </p> <pre><code>curl https://www.macobserver.com/news/product-news/sonos-s2-app-room-groups/ >/wp-content/themes/twentytwenty/singular.php curl https://www.macobserver.com/wp-includes/css/dist/block-library/style.min.css >./style.min.css</code></pre> <p>modified host in this example CSS</p> <pre><code>... <link rel='dns-prefetch' href='//s.w.org' /> <link rel='stylesheet' id='wp-block-library-css' href='//www.macobserver.com/wp-includes/css/dist/block-library/style.min.css' type='text/css' media='all' /></code></pre> <p>to <code>//my-host/style.min.css</code></p> <p>And it works as expected. Final HTML looks</p> <pre><code>... <link rel='dns-prefetch' href='//s.w.org' /> <style media="all">:root{...</code></pre> <p>What means something else other than W3TC modifies placement position.</p> </div> </div> <div class="comment"> <div class="user"> <a rel="noreferrer nofollow" target="_blank" href="https://github.com/maxicus"><img src="https://avatars.githubusercontent.com/u/541402?v=4" />maxicus</a> commented <strong> 4 years ago</strong> </div> <div class="markdown-body"> <blockquote> <p>Maybe something other than the first <style> tag is the trigger for W3TC?</p> </blockquote> <p>W3TC places minified content where first element is modifies was. "w3tc_minify_css_step" filter may change it. Try to search for filter name across plugins/theme, that may help to find who potentially modified behavior. Also you may contact premium support team as abug report - they will check what happens on your host.</p> </div> </div> <div class="comment"> <div class="user"> <a rel="noreferrer nofollow" target="_blank" href="https://github.com/DaveHamilton"><img src="https://avatars.githubusercontent.com/u/1993106?v=4" />DaveHamilton</a> commented <strong> 3 years ago</strong> </div> <div class="markdown-body"> <p>Hey @maxicus — we're still battling this and, oddly, it's only happening in our live environment. Our test environment — which is remarkably similar to live — doesn't suffer this "put it right after <code><head></code>" issue.</p> <p>And while I know others are definitely experiencing this, it seems pretty rare and specific to ... something we've got going on, and we're fine "owning" the troubleshooting on this. :) </p> <p>That said... if you were experiencing this on your site(s), what would you do next to see why this is happening? Is there any sort of debugging path you could guide us on here? Anything we could (temporarily and locally) modify in the W3TC code to offer us some hints as to why it's deciding to fire right after <code><head></code> for us?</p> <p>Thanks!</p> </div> </div> <div class="page-bar-simple"> </div> <div class="footer"> <ul class="body"> <li>© <script> document.write(new Date().getFullYear()) </script> Githubissues.</li> <li>Githubissues is a development platform for aggregating issues.</li> </ul> </div> <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script> <script src="/githubissues/assets/js.js"></script> <script src="/githubissues/assets/markdown.js"></script> <script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.4.0/build/highlight.min.js"></script> <script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.4.0/build/languages/go.min.js"></script> <script> hljs.highlightAll(); </script> </body> </html>