Usability-first Search Engine Optimization

How to Remove Code Bloat From WordPress Header

Most content management systems try to add as many features to their platforms as possible, and WordPress is certainly no exception to this rule. I like to choose my “features”, but disabling them from the dashboard is often not an option. Whether you want to minimize code bloat to improve performance, or tighten up security on your WordPress install, the following areas of WordPress’s head section are a good place to start.

You can pick and choose which of the following CSS, JS, and meta data you want to remove—I’ll leave that up to you—but I describe the purpose of each bit of fat we’re trimming from WordPress.

Removing a function you don’t want is often as simple as adding a few lines of code to the functions.php file of your (preferably child) theme’s directory. Skip the ‘How This Works’ section if you just want the code.

  1. How it Works (Optional)
  2. Remove Shortlinks Meta Data
  3. Remove Rest API Meta Data
  4. Remove WordPress Emojis

How it Works

Essentially, you’re using WordPress’s add_action() function to hook you’re own custom function, let’s call it goodbye_bloat, to WordPress’s action hook after_setup_theme.

add_action( 'after_setup_theme', 'goodbye_bloat' );

function goodbye_bloat () {
remove_action( 'wp_head', 'rest_output_link_wp_head' );
remove_action( 'wp_head', 'wp_shortlink_wp_head' );

Your custom function goodbye_bloat uses WordPress's remove_action function to prevent specific callbacks from loading with your theme.

The after_setup_theme action is a hook called during each page load after the theme is initialized. This ensures that the callback you are removing has been added before you try to remove it.

As you can see, you can remove more than one callback with your custom function. In the example above, we've removed two callbacks: the REST API link and Shortlink, and as a result, they'd won't appear in your source code.

If ever you need to re-enable a function, it's as simple as removing the functions or filters you added to functions.php. I do, however suggest that you add a comment above each function you disable, with a short description and date, to help you undo anything you want to at a later date.

WordPress 3 introduced its own flavour of URL shortener; Shortlinks, similar to and TinyURL. If your hosting your site on, it might look something like[string-here]; otherwise, the URL might simply use your page or post ID, and look something like[id-here].

Source example:

<link rel='shortlink' href='[id-here]' />


add_action( 'after_setup_theme', 'goodbye_bloat' );

function goodbye_bloat () {
remove_action( 'wp_head', 'wp_shortlink_wp_head' );

REST API Meta Data

WordPress 4.4 introduced an meta link to let other sites and applications know that your site now supports the new JSON REST API.

Source example:

<link rel='' href='' />

The following added to your theme's functions.php will remove the link from the WP header, but won't disable the REST API:


The following will remove the meta data link from the head section of your pages:

add_action( 'after_setup_theme', 'goodbye_bloat' );

function goodbye_bloat () {
remove_action( 'wp_head', 'rest_output_link_wp_head', 10 );

If you'd like to also remove the API link from your HTTP headers, you can also add the following to the goodbye_bloat function:

remove_action( ‘template_redirect’, ‘rest_output_link_header’, 11, 0 );

If, for whatever reason, you do want to completely disable the REST API, you'd add the following to functions.php instead:

function disable_json_api () {

  // Filters for WP-API version 1.x
  add_filter('json_enabled', '__return_false');
  add_filter('json_jsonp_enabled', '__return_false');

  // Filters for WP-API version 2.x
  add_filter('rest_enabled', '__return_false');
  add_filter('rest_jsonp_enabled', '__return_false');

add_action( 'after_setup_theme', 'disable_json_api' );

WordPress Emojis

In WordPress 4.2, native support was incorporated into WP core for emojis, which you can think of as a bigger, better version of smileys. Emojis can be a fun addition to certain types of blogs, but if you don't have a need for a thumbs up or a big grinning face on your site, you don't need the internal CSS and calls to JS that come with them.

Source example:

Internal JavaScript

<script type="text/javascript">
window._wpemojiSettings = {"baseUrl":"","ext":".png","source":{"concatemoji":""}};
!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;c.supports={simple:d("simple"),flag:d("flag")},c.supports.simple&&c.supports.flag||(f=c.source||{},f.concatemoji?e(f.concatemoji):f.wpemoji&&f.twemoji&&(e(f.twemoji),e(f.wpemoji)))}(window,document,window._wpemojiSettings);

Internal CSS

<style type="text/css">
img.emoji {
    display: inline !important;
    border: none !important;
    box-shadow: none !important;
    height: 1em !important;
    width: 1em !important;
    margin: 0 .07em !important;
    vertical-align: -0.1em !important;
    background: none !important;
    padding: 0 !important;


function disable_wp_emojicons() {

  // all actions related to emojis
  remove_action( 'admin_print_styles', 'print_emoji_styles' );
  remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
  remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
  remove_action( 'wp_print_styles', 'print_emoji_styles' );
  remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );
  remove_filter( 'the_content_feed', 'wp_staticize_emoji' );
  remove_filter( 'comment_text_rss', 'wp_staticize_emoji' );

  // filter to remove TinyMCE emojis
  add_filter( 'emoji_svg_url', '__return_false' );

  // filter to remove the DNS prefetch
  add_filter( 'tiny_mce_plugins', 'disable_emojicons_tinymce' );
add_action( 'init', 'disable_wp_emojicons' );

// filter to disable TinyMCE emojicons
function disable_emojicons_tinymce( $plugins ) {
  if ( is_array( $plugins ) ) {
    return array_diff( $plugins, array( 'wpemoji' ) );
  } else {
    return array();

About matt

Matthew Edward is the founder of Springboard SEO, a usability-first search engine optimization company in Montreal.

  • Chan

    Pretty awesome post. I love WordPress but is significantly slower than other CMS systems. Anyway I can find to enhance performance is always a big plus.

  • David Clark

    Hey Matt, just wondering why you’ve chosen not to remove a lot of the stuff you talked about. You still have shortlink in your source code. Any reason why you haven’t removed it? Does it serve any particular function being in the header?