• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

Startup Hero

The Official Blog Of Name Hero

Learn To Fly Above The Competition Get Started
  • HomeWelcome
  • CoursesVideo Training Center
  • About UsWhat is StartupHero?
  • BlogGet the latest
  • Start HereStartup 101
  • SpeakingPodcast & Media
  • ResourcesTools to help You
    • Reselling WordPress Hosting
    • Resell Hero
    • How To Start A Blog
  • NameHeroCloud Web Hosting

How To Inline And Defer CSS On WordPress Without Plugins

By Bhagwad Park on December 5, 2018 22

How To Inline And Defer CSS On WordPress Without Plugins

Knowing how to inline and defer CSS on your WordPress site is a vital part of improving the viewer experience. While it doesn’t improve your page load time, it makes a huge difference to how the user perceives the page to load.

Normally, all externally linked CSS stylesheets are render-blocking. Which means that the browser doesn’t proceed until they’ve been downloaded. So it’s a best practice to defer them (not the same “defer” as with Javascript though). Unfortunately, this has some side effects that we need to take care of.

This tutorial will show you how to:

  1. Generate critical CSS
  2. Defer CSS stylesheets
  3. Inline the critical CSS from Step 1

So let’s go.

Step 1: Generate Critical CSS

The importance of this step will become evident after step 2. For now, just visit a site like like, enter your site’s URL or page, and click “Generate Critical Path CSS”. The tool will scan your website and eventually give you a blob of text like this:

Copy Critical CSS

Copy this and keep it safe. We’ll use it later.

Step 2: Defer CSS Stylesheets

Most CSS in WordPress is (and should be) enqueued properly using the “wp_enqueue_style” function. This will place a <link> element in the head that looks like this:

CSS Files Without Preload

As mentioned earlier, this CSS stylesheet is render blocking. If you plug your page into a tool like Google’s PageSpeed insights for example, it’ll complain that a lot of stuff is preventing the page from displaying – and those tools will be right.

About the rel=’preload’ Attribute

To solve this problem, browsers have started supporting the “preload” attribute for resources like scripts. Basically, it tells the browser that the resources marked in this manner can be downloaded simultaneously in the background and that they’re not terribly important for page loading.

Of course, that’s not true. The CSS stylesheets are important. They define how your site looks after all! But for the moment, we’re interested in using the “preload” attribute value to defer our external stylesheets.

You can do this by inserting the following code into your WordPress’s functions.php file:

function add_rel_preload($html, $handle, $href, $media) {
    
    if (is_admin())
        return $html;

     $html = <<<EOT
<link rel='preload' as='style' onload="this.onload=null;this.rel='stylesheet'" id='$handle' href='$href' type='text/css' media='all' />
EOT;
    return $html;
}
add_filter( 'style_loader_tag', 'add_rel_preload', 10, 4 );

After you save your changes, your CSS stylesheets will have the “preload” tag attached to them like this:

CSS is Preloaded

Great right? Not so fast!

Step 3: Panic As your Site Breaks

Unfortunately, running the above code makes your site “unstyled” like this:

But the Page is Doesnt Display

This is because the CSS styles with “preload” haven’t been applied since the page went ahead and rendered without them. This is where the “critical” CSS from Step 1 comes in.

The “critical CSS” refers to only those CSS rules that apply to the “above the fold” content – namely the content that’s visible when your page first loads. This is typically a very tiny subset of the actual CSS contained in all the stylesheets.

In Step 1, we generated this critical CSS, and we need to insert it into the <head> of our webpage with following code:

function hook_css() {
    ?>
           [insert critical css here]
    <?php
}
add_action('wp_head', 'hook_css');

Replace [insert critical css here] with the code you copied from Step 1.

Note that this must include the <style></style> tags around it. If you’re using a different tool, it might just give you the CSS rules without the <style> opening and closing tags. Make sure you add them!

Once you’ve done this, your page will load normally and look the same. With the important difference that all your stylesheets are loading in a deferred manner! Say hello to fast page load speed scores!

Bhagwad Park Profile Picture
Bhagwad Park

I’m a NameHero team member, and an expert on WordPress and web hosting. I’ve been in this industry since 2008. I’ve also developed apps on Android and have written extensive tutorials on managing Linux servers. You can contact me on my website WP-Tweaks.com!

Reader Interactions

Comments

  1. Zach says

    February 5, 2019 at 2:34 pm

    Hey there,
    Really interesting method to remove CSS render-blocking. An issue with the function though, it only works for the home page. The critical path CSS I copied into the head only works for the home page. So other pages still break and even after page loading is complete, the layout is broken.

    Could the function and method be improved to include conditional logic so I can target pages on an individual basis? Or even better, on a template by template basis?

    Reply
    • Bhagwad Park says

      February 20, 2019 at 11:42 am

      It’s possible, but I would suggest just including ALL the critical CSS inline – even for those pages that don’t need it.

      What you’re suggesting is valid in theory, but in practice it would require a LOT of maintenance. And each time you make a change like adding a plugin, changing a theme, or even styling a table, you would need to make modifications to your code. This would quickly become unmanageable.

      Given the small size of text, the performance benefits would be truly minuscule – so small, that I doubt they could even be measured. So if I were you, I would gather all the critical CSS from all my site’s pages in one blob and paste them for all pages.

      Reply
  2. David Elstob says

    June 9, 2019 at 6:50 am

    If you use Fast Velocity Minify – some prefer Autoptimize – you can inline all your CSS in the header or header and footer. As long as the file size in the header is no more than 50 – 60 kb you are good. No need to worry about critical CSS.

    Obviously it’s better to deffer unused style rules, but if you’re within this limit then the benefits aren’t worth the hassle.

    AMP has a 50 kb CSS limit for same reason.

    Reply
    • Dragan says

      November 16, 2020 at 10:53 am

      Hello David,
      I’m amateur, with no previous knowledge or experience with website building nor wordpress or something but I’m leraning little by little. I have a question with Fast Velocity Minify and what to do with CSS or JS processed files.
      – /wp-content/plugins/elementor/assets/xxx.css
      – /wp-content/plugins/woocommerce/assets/js/xxx.js
      Should I exclude or include any of them or what ? Honestly I haven’t ask on WP forum since I started with FVM recently and then I noticed this blog and topic that I was looing for. Thank you in advance. Cheers and take you all care! Dragan

      Reply
  3. Manish Vadnathani says

    September 10, 2019 at 3:52 am

    I’m having little problem with this technique. I’m using W3 Total cache plugin, As I load my critical css before loading any css and js, Critical css works fine but My Combined CSS Files doesn’t load combinely, they load separately. So my http requests increases from 29 to 45. This technique works but i don’t know how to load my combined css files after putting critical css first in the header.

    Can anyone please tell me why that’s happening? and give me a solution if possible 🙂

    Reply
  4. Egan says

    January 12, 2020 at 12:25 am

    I’m personally use AO for my website. The interface seems more friendly for me instead fvm. Unfortunately AO does not have feature for defer some assets, but they have preload and preconnect. I got 85 – 89 score in PageSpeed and thats more than enough since the page below 500kb. The real problem i need to solve is the Ads.

    Reply
  5. Philip says

    February 4, 2020 at 9:37 am

    Is there a way to defer a single stylesheet instead of all stylesheets?

    Reply
    • Bhagwad Park says

      February 5, 2020 at 12:26 pm

      You’ll need to modify the code with an “if” condition to check for the specific style tag that you want to defer.

      Reply
    • Rémi Meullemeestre says

      May 14, 2020 at 8:28 am

      You can.
      I personnaly did it like that so far :

      function add_style_attributes( $html, $handle ) {

      if ( ‘bootstrap’ === $handle ) {
      return str_replace( “media=’all'”, “media=’all’ integrity=’sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T’ crossorigin=’anonymous'”, $html );
      }
      if ( ‘fontawesome’ === $handle ) {
      return str_replace( “media=’all'”, “media=’all’ integrity=’sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr’ crossorigin=’anonymous'”, $html );
      }
      return $html;
      }

      add_filter( ‘style_loader_tag’, ‘add_style_attributes’, 10, 2 );

      In this exemple, I also add the integrity and crossorigin attributes that the regular enqueue script does not handle by default.

      Hope it helps.

      Reply
  6. Martin says

    March 21, 2020 at 3:09 pm

    Hi,

    the above code doesn’t work – if uploaded in the functions.php, it results in string errors. Suggest this to be checked, so it can be used.

    Thanks!!
    Martin

    Reply
    • Bhagwad Park says

      March 23, 2020 at 12:11 am

      Hi Martin,

      Could you share the exact error you’re getting when you add the code along with the line number if possible, and the exact code you’re using?

      Reply
  7. Martin says

    March 24, 2020 at 6:23 pm

    Hey,
    sure: I am using exactly your code snipped that you highlight above for the functions.php and pasted it in the functions.php of my child theme folder.

    The resulting error: Parse error: syntax error, unexpected end of file in /XXX/XXX/XXX/wp-content/themes/mindfulness/functions.php on line 552

    Reply
  8. Ryan Pearson says

    May 2, 2020 at 4:03 pm

    I’m having an issue in Firefox with this code. With Chrome, Safari, Opera and Edge, this code correctly works, and loads the css files after the page has rendered.

    However, with Firefox, this code is preventing the CSS files from loading at all.

    Has anyone else experienced this problem?

    Reply
    • Remondo says

      May 13, 2020 at 12:00 pm

      I have the same issue, my styles aren’t fonctional withing Firefox, plus, my nagivation is not even displayed in Chrome on top. Beside that, I also encounter various issues with img sizes on the front page, and, I presume, in other pages as well.

      In short, it might be an interesting solution, because yes, the Chrome audits tells me it indeed remove most of the render-blocking CSS assets, but in the end it’s definitely not fully fonctionnal for my case, so I guess I will try another method or will just simply let them the way the behave initially.

      Reply
  9. Denish says

    May 3, 2020 at 9:10 am

    Thanks, this is great!

    Reply
  10. apmeyer says

    July 10, 2020 at 9:40 am

    As noted above, this isn’t playing nice with Firefox.

    Reply
  11. Pereceh Internet says

    July 10, 2020 at 10:06 pm

    it’s better to just defer javascript than defer css.

    Reply
  12. Squivo says

    July 15, 2020 at 1:39 am

    This works fine in FF for me – just need to follow the more detailed guidelines here: https://web.dev/defer-non-critical-css/

    and also, instead of adding the critical.css in wp_head, it’s better to carve out a case in the style_loader_tag where:

    if ( strpos( $href, ‘themes//critical.css’ ) ) return $html;// Make sure this loads and is not deferred

    Reply
  13. Squivo says

    July 21, 2020 at 3:55 pm

    I lied by the way ( caching is hard ) : FF sucks… you have to include a clause to return based on HTTP_USER_AGENT ( if Firefox, don’t mess with the script_tag )

    Reply
  14. Q says

    September 25, 2020 at 3:45 am

    There are several solutions for FF, but the easiest is to add something like:

    rel=”stylesheet preload”

    which works as a fall-through, for browsers which do not support preload.

    Reply
  15. Bryan Veloso says

    February 18, 2021 at 1:16 am

    Pagespeed optimisation really takes time. Thanks for sharing this stuff, it’s quite useful. Less plugin, less bloat.

    Reply
  16. Thomas Vav says

    March 22, 2021 at 2:01 am

    Hello and thank you for this guide.
    Unfortunately something is wrong with my setup.

    I have installed both codes to my site (1st part with preload at the functions.php file and 2nd part with thefunction hook_css code at the header), but when I reload my site, I get a phrase appearing at my homepage, at the top left corner. This includes a few words from the function command.

    Why is this happening and how to fix it?

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Primary Sidebar

Connect With Us!

Superhero Resources

Fix Common Issues

  • How To Setup Free And Automatic SSL Certificates
  • How To Setup Cloudflare With Railgun
  • How To Fix Memory Exhausted Errors In WordPress
  • How To Edit PHP Version/Upload Limit/Add Extensions
  • How To Move/Migrate Your Business To Name Hero

Free Guides

  • How To Setup NameHero Hosting
  • How To Create A Web Hosting Business With WordPress
  • How To Start A WordPress Blog
  • How To Migrate WordPress To A VPS
  • How To Speed Test And Optimize Your WordPress Website
  • Magento 2.X Installation Guide
  • How To Clean Up A WordPress Hack

Training

Recent Posts

  • Will Google FLOC Affect Website Owners?
  • Good Riddance To Contact Forms – Hello Google Forms!
  • How To Identify CLS Issues Using Google Chrome
  • How To Achieve ~90% Cache Hit Ratio On Cloudflare
  • How Does Google Judge EAT? Probably Links!
  • Inlined CSS – When To Use vs Stylesheets
Subscribe in a reader
  • Web Hosting
  • WordPress Hosting
  • Reseller Hosting
  • VPS Hosting
  • Twitter
  • Facebook
  • LinkedIn
  • YouTube
  • FTC Disclosure
  • Earnings Disclosure
  • Privacy Policy

Copyright © 2021 · Smart Passive Income Pro on Genesis Framework · WordPress · Log in