Yoast / wordpress-seo

Yoast SEO for WordPress
https://yoast.com/wordpress/plugins/seo/
Other
1.78k stars 894 forks source link

wp_head output speed test friendly #2822

Closed lmseo closed 7 years ago

lmseo commented 9 years ago

Hi,

Thanks for the excellent plugin you guys have developed. Would there be any chance to move the loading of scripts further down the wp_head? In the front-end, everything is currently been output before all the CSS Several speed tests such as the audit tab in Chrome Dev Tools keep throwing flags like "Optimize the order of styles and scripts." There are only a couple of inline scripts on the homepage from Yoast plugin that are causing these flags.

<script type='application/ld+json'>/*<![CDATA[*/{"@context":"http:\/\/schema.org","@type":"WebSite","url":"http:\/\/www.vqconstruction.com\/","name":"V &amp; Q","potentialAction":{"@type":"SearchAction","target":"http:\/\/www.vqconstruction.com\/?s={search_term_string}","query-input":"required name=search_term_string"}}/*]]>*/</script><script type='application/ld+json'>/*<![CDATA[*/{"@context":"http:\/\/schema.org","@type":"Organization","url":"http:\/\/www.vqconstruction.com\/","sameAs":[],"name":"V & Q Construction","logo":""}/*]]>*/</script>

--current class-frontend.php--

add_action( 'wp_head', array( $this, 'front_page_specific_init' ), 0 );
add_action( 'wp_head', array( $this, 'head' ), 1 );

--speed test friendly--

add_action( 'wp_head', array( $this, 'front_page_specific_init' ), 20 );
add_action( 'wp_head', array( $this, 'head' ), 21 );

Thanks, Luis.

Rarst commented 9 years ago

Questionable benefit.

  1. Test seems to be stupid and interpret inline JS as JS file, which it isn't.
  2. We don't control priorities at which everyone out there outputs CSS. We move to 21, someone outputs CSS at 30, do we have to move to 31 now?.. It's endless.

If you are concerned about this for your own site, it should trivial to unhook and re-hook these. Such things need to be micromanaged for specific site anyway.

lmseo commented 9 years ago

It is rather unprofessional to start a reply with "Test seems to be stupid" specially when the test is coming from Google and this is an "SEO" plugin. Audits in Chome Dev Tools, just like PageSpeed Insights include current web best practices to improve website performance(I assume), just in case you were not aware of. If you feel Chrome Dev tools is on the wrong side here maybe taking it up with someone like https://twitter.com/paul_irish could settle it. The guys works at Chrome Dev and he is a genius when comes to browser performance. Moving on.

Inline scripts need to be executed by the JavaScript interpreter before control is switch back to the rendering engine and HTML can continue to be parsed. There is no parallel downloading of resources while JavaScript is executed, generally speaking. This means any remaining resources below the inline scripts can only be downloaded once the script finishes execution just like external scripts, except there is no extra HTTP request, which is great. That is why it is recommended to inline SMALL pieces of script and when possible move those to the bottom of the page. What is not recommended however, is to inline scripts before any other resources, specially those used to render first screen paint.

The scripts included with your plugin are rather small, which is good. However, even with a clean installation of WordPress and just your plugin activated, there are already 3 inline scripts on the page that would need to be executed before any resources are even begin to download. Performance bottleneck. These scripts add nearly nothing to the rendering process in most websites but there they are, way at the top of hundreds of websites, by default.

<script type='application/ld+json'>/*<![CDATA[*/{"@context":"http:\/\/schema.org","@type":"WebSite","url":"http:\/\/www.vqconstruction.com\/","name":"V &amp; Q","potentialAction":{"@type":"SearchAction","target":"http:\/\/www.vqconstruction.com\/?s={search_term_string}","query-input":"required name=search_term_string"}}/*]]>*/</script>

<script type='application/ld+json'>/*<![CDATA[*/{"@context":"http:\/\/schema.org","@type":"Organization","url":"http:\/\/www.vqconstruction.com\/","sameAs":[],"name":"V & Q Construction","logo":""}/*]]>*/</script>

<script type="text/javascript">/*<![CDATA[*/window._wpemojiSettings={"baseUrl":"http:\/\/s.w.org\/images\/core\/emoji\/72x72\/","ext":".png","source":{"concatemoji":"http:\/\/www.vqconstruction.com\/wp-includes\/js\/wp-emoji-release.min.js"}};!function(a,b,c){function d(a){var c=b.createElement("canvas"),d=c.getContext&&c.getContext("2d");return d&&d.fillText?(d.textBaseline="top",d.font="600 32px Arial","flag"===a?(d.fillText(String.fromCharCode(55356,56812,55356,56807),0,0),c.toDataURL().length>3e3):(d.fillText(String.fromCharCode(55357,56835),0,0),0!==d.getImageData(16,16,1,1).data[0])):!1}function e(a){var c=b.createElement("script");c.src=a,c.type="text/javascript",b.getElementsByTagName("head")[0].appendChild(c)}var f,g;c.supports={simple:d("simple"),flag:d("flag")},c.DOMReady=!1,c.readyCallback=function(){c.DOMReady=!0},c.supports.simple&&c.supports.flag||(g=function(){c.readyCallback()},b.addEventListener?(b.addEventListener("DOMContentLoaded",g,!1),a.addEventListener("load",g,!1)):(a.attachEvent("onload",g),b.attachEvent("onreadystatechange",function(){"complete"===b.readyState&&c.readyCallback()})),f=c.source||{},f.concatemoji?e(f.concatemoji):f.wpemoji&&f.twemoji&&(e(f.twemoji),e(f.wpemoji)))}(window,document,window._wpemojiSettings);/*]]>*/</script>

The reason I suggested using priority "20" when "hooking" your output to the wp_head is because WordPress by default "hooks" wp_enqueue_scripts with a priority 10 to the wp_head. This means even with a clean install of WP the style.css file that is needed by every single website by default, will have to wait for those 3 scripts I mentioned, before it even begins downloading. So technically speaking, any number larger than 10 should work on most websites.

Ideally speaking, you want to add the style.css link as close to the top of the page as possible to speed up first screen paint. Your plugin outputs very important information to the page, however it does so above the style.css which is counterproductive for page performance and so for SEO.

PS:Actually, technically speaking a small inline CSS that only includes the rules for the above the fold content is the best current practice, but it is just not option for most people. So maybe looking into a solution for that issue that could add even greater value to an already awesome plugin.

<!DOCTYPE html>
<html lang="en-US" prefix="og: http://ogp.me/ns#">
<head>
<meta charset="UTF-8" />
<link rel='stylesheet' id='novo-css'  href='http://da79db5a66cfbfa8f589-c06041d322f1ad6b39306f4da82d1689.r29.cf1.rackcdn.com/wp-content/themes/argo/style.css' type='text/css' media='all' />

Let me hear your thoughts.

Thanks, Luis.

Rarst commented 9 years ago

It is rather unprofessional to start a reply with "Test seems to be stupid" specially when the test is coming from Google and this is an "SEO" plugin.

In my defense lately I had my share of drowning in invalid bug reports, caused by (acknowledged) issue in Google's tools.

This is the message I get in audit:

The following external CSS files were included after an external JavaScript file in the document head.

There was no external file before styles. It might be case of bad wording. It might be case of false positive. In the end it just makes me extremely wary of running around changing code to please a test that... sees things. :)

You don't have to "sell" me on performance, I am passionate enough about topic myself. What you do have to "sell" me is that this is actually a practical issue, with actual performance profile demonstrating the bottleneck.

To be clear I am trending in favor of tweaking this, but I am not making or recommending any performance related changes lightly.

tittisan commented 9 years ago

I'm interested too in this subject. Even if I choose to not compile that option for the schema.org (I'm talking about metadata Google Knowledge Graph), still the script is loaded (in this case, "Inline script block #1" instead of #2) and in the wrong place, before CSS, blocking anyway:

There's a loading difference from my homepage to single page, where these scripts aren't loaded, because only for that item from a score of 85 to 100 is a big difference for me. I also believe that yours is a good plugin, but it has a big general impact on loading (tested many times, beyond this specific ISSUE - yes, this is an issue, it's not an opinion). Fix things like this would be useful to EVERYONE, and I don't think it's a big effort for you to fix this.

So: can you please move those scripts after the style sheets, and/or, when someone is not using that option, avoid unnecessary load? It's not a lightly difference when someone is trying to optmize at the best resolving a 2% here and there, and it's a big difference if someone, like me, at the end has decided to not compiling that option to avoid blocking, but one script load anyway. At least, you could specify how to disable it via functions.php in case someone does not want to load it when leaving empty. Thanks.

tittisan commented 9 years ago

Found add_filter( 'disable_wpseo_json_ld_search', '__return_true' ); but doesn't work.

tittisan commented 9 years ago

OK, this code works: add_filter( 'wpseo_json_ld_output', '__return_false' );

brunotavares commented 8 years ago

This inside my custom theme functions.php did the trick for me. Should be fairly easy to make it a plugin too.

if (class_exists('WPSEO_Frontend') && WPSEO_Frontend::get_instance() != null) {
    $seoInstance = WPSEO_Frontend::get_instance();

    remove_action( 'wp_head', array( $seoInstance, 'front_page_specific_init' ), 0 );
    remove_action( 'wp_head', array( $seoInstance, 'head' ), 1 );

    add_action( 'wp_head', array( $seoInstance, 'front_page_specific_init' ), 20 );
    add_action( 'wp_head', array( $seoInstance, 'head' ), 21 );
}

That wasn't enough for me, though. There're other plugins enqueuing scripts in higher priority than my theme does, so I also changed my theme:

add_action('wp_enqueue_scripts', 'geeksixteen_enqueue_styles', 1);

These two fixes made sure my styles are pretty high up the header and no blocking JS (or any JS block whatsoever) is before it. Google PageSpeed is happy :)

Rarst commented 8 years ago

I am still highly undecided about this. Moving this around sort of breaks public API if someone already relies on manipulating these hooks.

As for me this sort of optimization gets into realm of manual tweaking, as it was pointed out even WP core outputs plenty of head scripts, not to mention amount of stuff typical WP install spits out.

Marking needs decision.

atimmer commented 7 years ago

Closed after architects discussion.