Optimizing Jetpack Custom CSS
Jetpack adds a lot of features and performance options to self-hosted WordPress sites, along with it’s own built-in CSS styling. Most of this styling is fairly universal, but some of the top/bottom margins and other elements don’t always blend smoothly with existing site styling. Adding Jetpack-specific styling to an existing stylesheet is fine, but it can be a bit bloated and unneeded if Jetpack isn’t installed on a site. The method below optimizes a custom Jetpack CSS stylesheet to only load if Jetpack is installed and active.
First register and enqueue a CSS file specifically for Jetpack in the theme’s functions.php file using the code below. Note that this conditionally enqueues the CSS file only if Jetpack is active.
<?php
// register optimized styles
function evo_register_optimized_styles() {
wp_register_style( 'jetpack-optimized', get_template_directory_uri() . '/assets/css/jetpack.css' );
}
add_action('init', 'evo_register_optimized_styles');
// enqueue optimized styles
function evo_enqueue_optimized_styles() {
if ( in_array( 'jetpack/jetpack.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
wp_enqueue_style( 'jetpack-optimized' );
}
}
add_action( 'wp_enqueue_scripts', 'evo_enqueue_optimized_styles' );
Then create a jetpack.css file in the directory as registered in the function above. Below is a basic example of some Jetpack-specific custom CSS.
*[class^="wp-block-jetpack-"] {
margin-top: 2rem !important;
margin-bottom: 2rem !important;
}
.wp-block-jetpack-slideshow {
margin-bottom: calc(2rem - 36px) !important;
}
*[class^="wp-block-jetpack-"] *[class^="wp-block-jetpack-"],
*[class^="wp-block-"] *[class^="wp-block-jetpack-"],
.wp-block-jetpack-markdown {
margin-top: initial !important;
margin-bottom: initial !important;
}
.wp-block-jetpack-contact-info *[class^="wp-block-jetpack-"] {
margin-bottom: 0.5rem !important;
}
.sharedaddy {
padding-top: 0.75rem !important;
}
.jetpack-likes-widget-wrapper iframe {
margin-top: 0.5rem !important;
}
.sd-title {
margin-bottom: 0 !important;
}
.sd-content ul li {
line-height: 0 !important;
margin-right: 0.25rem !important;
}
.jetpack-comment-likes-widget-wrapper {
margin-bottom: 0.25rem;
}
.jetpack-comment-likes-widget-wrapper iframe {
background: #f8f8f8;
border: 1px solid #cccccc;
box-shadow: 0 1px 0 rgba(0,0,0,.08);
border-radius: 3px;
height: 26px;
width: 62px;
margin-top: 3px;
padding: 1px 0 0 5px;
}
.jetpack-comment-likes-widget-wrapper span.comment-like-feedback {
display: block;
font-size: 11px;
}
Optimizing Comments in WordPress
Comments are a versatile feature for allowing discussions on posts and pages in WordPress. I currently don’t have comments open on my blog posts, but I want my themes to support them dynamically. The method below optimizes comments to conditionally display and enqueue styles on posts/pages only when comments are open or exist.
First add or update the theme support for comments in the theme’s functions.php file, within the after_setup_theme hook, with the code below.
add_theme_support( 'html5', array(
'search-form',
'comment-form', // support for the comment form
'comment-list', // support for the comment list
'gallery',
'caption',
'script',
'style',
) );
Then register and enqueue a CSS file specifically for the comments in the theme’s functions.php file using the code below. Note that this conditionally enqueues the CSS file on each post/page only if comments are open, or if comments exist after comments are closed.
<?php
// register optimized styles
function evo_register_optimized_styles() {
wp_register_style( 'comments-optimized', get_template_directory_uri() . '/assets/css/comments.css' );
}
add_action('init', 'evo_register_optimized_styles');
// enqueue optimized styles
function evo_enqueue_optimized_styles() {
if ( is_singular() && comments_open() || is_singular() && get_comments_number() ) {
wp_enqueue_style( 'comments-optimized' );
}
}
add_action( 'wp_enqueue_scripts', 'evo_enqueue_optimized_styles' );
Then create a comments.css file in the directory as registered in the function above. A simplified example of the CSS uses the styles below.
.comments-area {
margin: 2rem 0;
}
.comment-body {
margin: 1.5rem 0;
}
.comment-metadata,
.comment-reply-link,
.comment-notes,
.logged-in-as {
font-size: 0.875rem;
}
.comment-author .avatar {
border-radius: 18px;
}
.children {
margin-left: 3rem;
}
.comment-form label {
display: block;
}
Then create a comments.php file in root theme directory like the example below. Note that this conditionally displays the comments section to each post/page only if comments are open, or if comments exist after comments are closed.
<?php if ( comments_open() || get_comments_number() ) { ?>
<?php if ( post_password_required() ) { return; } ?>
<div id="comments" class="comments-area">
<?php if ( have_comments() ) : ?>
<h3 class="comments-title">
<?php comments_number( 'No Comments', 'One Comment', '% Comments' ); ?>
</h3>
<ol class="comment-list">
<?php wp_list_comments( array( 'style' => 'ol', 'avatar_size' => 36, ) ); ?>
</ol>
<?php if ( get_comment_pages_count() > 1 && get_option( 'page_comments' ) ) : ?>
<nav class="comment-navigation">
<h5><?php previous_comments_link( 'Older Comments ❯' ); ?></h5>
<h5><?php next_comments_link( '❮ Newer Comments' ); ?></h5>
</nav>
<?php endif; ?>
<?php if ( ! comments_open() && get_comments_number() ) : ?>
<h4 class="no-comments"><?php _e( 'Comments are closed.' ); ?></h4>
<?php endif; ?>
<?php endif; ?>
<?php comment_form(); ?>
</div>
<?php } ?>
Finally, add comments in the loop on single/page PHP files with the standard template tag below, typically at the bottom of the main content area.
<?php comments_template(); ?>
Optimizing the WordPress Head Tag Section
The initial WordPress head tag section is a bit bloated. There are some quick optimizations via the functions.php file that will improve a WordPress site’s loading time and increase security. The key elements the method below addresses:
• Remove Query Strings from Static Resources – This can improve caching and fix some speed test warnings – Note that this can break how some external resources load (ex: enqueuing a Google Fonts CSS link)
• Header Cleanup – This removes all the unnecessary tags: RSD link, WordPress version number (increasing site’s security), wlwmanifest link, shortlink, and extra feed links (primary RSS feed still functions correctly)
• Disable the Emojis – This removes the emoji support WordPress has built-in for older browsers that isn’t needed for modern browsers
// Remove query strings from static resources
function _remove_script_version( $src ) {
$parts = explode( '?', $src );
return $parts[0];
}
add_filter( 'script_loader_src', '_remove_script_version', 15, 1 );
add_filter( 'style_loader_src', '_remove_script_version', 15, 1 );
// Header cleanup
add_action( 'do_feed_rss2_comments', 'disable_feeds', -1 );
add_action( 'do_feed_atom_comments', 'disable_feeds', -1 );
add_action( 'feed_links_show_comments_feed', '__return_false', -1 );
remove_action( 'wp_head', 'feed_links_extra', 3 );
remove_action( 'wp_head', 'rsd_link' );
remove_action( 'wp_head', 'wp_generator' );
remove_action( 'wp_head', 'wlwmanifest_link' );
remove_action( 'wp_head', 'wp_shortlink_wp_head', 10, 0 );
// Disable the emojis
function disable_emojis() {
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_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', 'disable_emojis_tinymce' );
add_filter( 'wp_resource_hints', 'disable_emojis_remove_dns_prefetch', 10, 2 );
}
add_action( 'init', 'disable_emojis' );
function disable_emojis_tinymce( $plugins ) {
if ( is_array( $plugins ) ) {
return array_diff( $plugins, array( 'wpemoji' ) );
} else {
return array();
}
}
function disable_emojis_remove_dns_prefetch( $urls, $relation_type ) {
if ( 'dns-prefetch' == $relation_type ) {
$emoji_svg_url = apply_filters( 'emoji_svg_url', 'https://s.w.org/images/core/emoji/2/svg/' );
$urls = array_diff( $urls, array( $emoji_svg_url ) );
}
return $urls;
}
Optimizing Sites with the .htaccess File
Slow websites suck. Luckily, there are some quick optimizations via the .htaccess file that will improve a site’s loading time and boost your speed score. This is a good opportunity to increase the site’s security too. The key elements the method below addresses:
• Force HTTPS – This requires that you have an active SSL Certificate on your domain (Let’s Encrypt is a good free option) and forces all requests to use HTTPS for stronger encryption
• Accept-Encoding – This tells the browser whether or not the client can handle compressed versions of the content
• Expires Caching – This sets the time duration files will stay cached on visitor’s browsers, so when they revisit the site it loads much faster
• Gzip Compression – This compresses the website files reducing the overall size of the site
# FORCE HTTPS
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# ACCEPT-ENCODING
<IfModule mod_headers.c>
<FilesMatch ".(js|css|xml|png|gz|html|woff2|slim.min.js)$">
Header append Vary: Accept-Encoding
</FilesMatch>
</IfModule>
# EXPIRES CACHING
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access plus 90 days"
ExpiresByType image/jpeg "access plus 90 days"
ExpiresByType image/gif "access plus 90 days"
ExpiresByType image/png "access plus 90 days"
ExpiresByType image/svg "access plus 90 days"
ExpiresByType image/x-icon "access plus 90 days"
ExpiresByType video/mp4 "access plus 90 days"
ExpiresByType video/mpeg "access plus 90 days"
ExpiresByType text/css "access plus 1 week"
ExpiresByType text/javascript "access plus 1 month"
ExpiresByType text/x-javascript "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType application/x-javascript "access plus 1 month"
ExpiresByType application/pdf "access plus 90 days"
ExpiresDefault "access plus 1 week"
</IfModule>
# GZIP COMPRESSION
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
AddOutputFilterByType DEFLATE application/x-font
AddOutputFilterByType DEFLATE application/x-font-opentype
AddOutputFilterByType DEFLATE application/x-font-otf
AddOutputFilterByType DEFLATE application/x-font-truetype
AddOutputFilterByType DEFLATE application/x-font-ttf
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE font/opentype
AddOutputFilterByType DEFLATE font/otf
AddOutputFilterByType DEFLATE font/ttf
AddOutputFilterByType DEFLATE image/svg+xml
AddOutputFilterByType DEFLATE image/x-icon
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/xml
</IfModule>