WordPress「highlight.js」を非同期かつ必要なページだけで読み込む方法

ブログの記事でソースコードを表示するために、シンタックスハイライト表示ができる「highlight.js」をWordpressで利用しています。

CDN版を利用させてもらっているのですが、必要なファイルを読み込むために「header.php」か「footer.php」に下記のコードを記載すると、GoogleのPagespeed Insightsで「スクロールせずに見えるコンテンツのレンダリングをブロックしている JavaScript/CSS を排除する」と指摘されます。

<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.0.0/styles/default.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.0.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>

上記のコードだと、Pagespeed Insightsで指摘事項がありました・・・。気にしなくてもいいかなとも思いましたが、プラグインに頼らず自力で!勉強も兼ねて!Pagespeed Insightsの指摘事項を無くすことにチャレンジしてみました。

そして、困った困ったといろいろ試してみて、下記の非同期で読み込む方法で解決しました。と、そのままだと全てのページで「css」と「js」ファイルを読み込んでこようとするので、必要なページのみで読み込む方法を最後に記載します。

「CSS」と「js」ファイルを非同期で読み込む

読み込む順番?タイミング?なども考慮しないといけないとは思いますが、詰めきれてはいないです。が、PageInsighsの指摘はなくなったのでコードを記載しておきます。

まずは「cssファイル」の非同期読み込み

下記のコードを「footer.php」に記載。「highlight.js」のスタイルは、「Monokai Sublime」を利用しています。

<script>
(function(d){
var s = d.getElementsByTagName('script')[0];
var c1 = d.createElement('link');
c1.rel = 'stylesheet';
c1.href = '//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.0.0/styles/monokai-sublime.min.css';
s.parentNode.insertBefore(c1, s);
})(document);
</script>

次が「javascript」の非同期読み込み

「highlight.min.js」が読み込まれたのを確認してから、スクリプト「hljs.initHighlightingOnLoad()」を実行しています。下記のコードも「footer.php」に記載。

<script>
function loadScript(src, callback) {
    var done = false;
    var head = document.getElementsByTagName('head')[0];
    var script = document.createElement('script');
    script.src = '//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.0.0/highlight.min.js';
    head.appendChild(script);
    // Attach handlers for all browsers
    script.onload = script.onreadystatechange = function() {
        if ( !done && (!this.readyState ||
                this.readyState === "loaded" || this.readyState === "complete") ) {
            done = true;
            callback();
            // Handle memory leak in IE
            script.onload = script.onreadystatechange = null;
            if ( head && script.parentNode ) {
                head.removeChild( script );
            }
        }
    };
}
loadScript("highlight.min.js", function() {
    hljs.initHighlightingOnLoad();
});
</script>

「css」と「js」ファイルを非同期で読み込むことで、PageSpeedInsightsでの「highlight.js」に関する指摘事項がなくなります。

必要なページのみで読み込む

上記のコードを記載するだけだと、全てのページで「css」と「js」ファイルの読み込みを行います。このブログがそうなのですが、日記のような記事がメインでソースコードを紹介することがほとんどないので、必要なページのみで読み込みを行い、少しでもサイトを軽くするようにします。

こういうのは動的CMSのWordpressの強み、以下の関数で実現できます。

<?php is_single($post); ?>

$postは「記事のID」になります。

ただ、上記の関数だと1ページのみの指定しかできないので、複数ページを指定するときは、以下の関数を使います。

<?php is_single(array(17,'beef-stew','Irish Stew')); ?>

上記の関数だと、記事IDやスラッグが複数指定できます。

完成形

「非同期で読込む」「必要な記事のみ」の条件を満たした、このブログで使用しているコードを記載しておきます。2つの記事でのみ読み込む、記事のIDは1008と1010です。

このコードを「footer.php」に記載。

<?php
if ( is_single(array(1008,1010) )) :?>
<script>
(function(d){
var s = d.getElementsByTagName('script')[0];
var c1 = d.createElement('link');
c1.rel = 'stylesheet';
c1.href = '//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.0.0/styles/monokai-sublime.min.css';
s.parentNode.insertBefore(c1, s);
})(document);
</script>
<script>
function loadScript(src, callback) {
    var done = false;
    var head = document.getElementsByTagName('head')[0];
    var script = document.createElement('script');
    script.src = '//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.0.0/highlight.min.js';
    head.appendChild(script);
    // Attach handlers for all browsers
    script.onload = script.onreadystatechange = function() {
        if ( !done && (!this.readyState ||
                this.readyState === "loaded" || this.readyState === "complete") ) {
            done = true;
            callback();
            // Handle memory leak in IE
            script.onload = script.onreadystatechange = null;
            if ( head && script.parentNode ) {
                head.removeChild( script );
            }
        }
    };
}
loadScript("highlight.min.js", function() {
    hljs.initHighlightingOnLoad();
});
</script>
<?php endif; ?>

デメリット

「highlight.js」を読み込みたい記事を書くたびに、コードに記事IDを追加・footer.phpをアップロードする必要があります。

まとめ

軽いは正義!だと思います。まだまだWordpressの勉強が足りないですが、「highlight.js」は色々はハイライトスタイルが利用でき面白いです。