Disabling WordPress Emoji Scripts: Why It Matters and How to Do It Right

wp-emoji injects 13KB of render-blocking JS on every page - useless on modern devices. Remove it cleanly and quickly.

Since WordPress 4.2 (2015), core auto-injects a JavaScript and CSS pair that polyfill emoji rendering: they detect whether the browser can paint emoji natively, and if not, they pull bitmap fallbacks from twemoji.maxcdn.com. Useful in 2015. In 2026 every modern device (iOS, Android, Windows 10+, macOS, desktop Linux) renders emoji natively, so the script ships zero value to visitors while still costing them time.

Why this matters

The script adds 13KB of JavaScript in wp_head as render-blocking; an inline blob that performs Canvas-based feature detection (an INP-expensive operation); and an external DNS lookup to s.w.org and twemoji.maxcdn.com that nibbles 100-300ms off FCP. Removing it shaves 50-150ms from FCP on midrange mobile and bumps Lighthouse scores by 2-5 points.

Removal does not break emoji display: Safari, Chrome, Firefox, and Edge all paint 😀 natively in every version released after 2017. Only ancient stacks (IE11 on XP, Android 4.x) still need the fallback, which on a 2026 production site accounts for roughly 0.01% of traffic. Even there, the original character still renders - just monochrome instead of color.

How to detect

View source on the homepage and search for wp-emoji or twemoji. Either match means the script is active. F12 > Network should also show a request for wp-emoji-release.min.js. PageSpeed Insights flags it under "Reduce unused JavaScript".

How to fix

Three approaches, easiest first:

Method 1: RankPlus toggle. In the scan optimization page, enable "Disable Emojis". Recommended if RankPlus is already installed.

Method 2: dedicated plugin. Install Ryan Hellyer's "Disable Emojis (data-protection regulations Friendly)" - tiny, no settings, sets and forgets.

Method 3: child-theme functions.php. Drop in:

remove_action('wp_head', 'print_emoji_detection_script', 7);
remove_action('wp_print_styles', 'print_emoji_styles');
remove_action('admin_print_scripts', 'print_emoji_detection_script');
remove_action('admin_print_styles', 'print_emoji_styles');
remove_filter('the_content_feed', 'wp_staticize_emoji');
remove_filter('comment_text_rss', 'wp_staticize_emoji');
remove_filter('wp_mail', 'wp_staticize_emoji_for_email');

add_filter('tiny_mce_plugins', function ($plugins) {
    return array_diff($plugins, ['wpemoji']);
});

add_filter('wp_resource_hints', function ($urls, $relation_type) {
    if ('dns-prefetch' === $relation_type) {
        $urls = array_filter($urls, function ($url) {
            return strpos($url, 's.w.org') === false;
        });
    }
    return $urls;
}, 10, 2);

Whichever method you use, flush page cache (WP Rocket, LiteSpeed Cache, W3 Total Cache) - cached pages still carry the script until the cache rotates.

Common mistakes

Mistake one: removing only print_emoji_detection_script and forgetting the rest. The DNS prefetch to s.w.org survives, and the classic editor still loads the emoji TinyMCE plugin. Mistake two: editing the parent theme's functions.php instead of the child theme - the next theme update wipes your work. Mistake three: assuming Google indexing breaks. The feature-detection code has nothing to do with SEO; if your post body contains literal emoji characters, Googlebot reads them fine without the script.

Verifying the fix

Reload the site in incognito and view source - wp-emoji or twemoji should be absent. In F12 > Network, filter on emoji; the request count should be zero. Re-run PageSpeed Insights and expect a 2-5 point bump alongside a smaller "Reduce unused JavaScript" callout. Verify that emoji still appear inside posts (🚀 ❤️ 🎉) - they should look normal.

Tip: If your page cache wrapped classic-editor comments before the change, emoji inside cached comments may render differently until you re-edit them. New content uses native emoji and looks right immediately.