highlight.jsを非同期で読み込む
highlight.jsを使えば、<pre><code> ~ </pre></code>で挟んだソースコードを自動でシンタックスハイライトしてくれます。
軽量かつ簡単に利用できるので当ブログでも使用しているのですが、公式サイトに載っている方法だと同期的に読み込むのでレンダリングをブロックしてしまいます。
シンタックスハイライトはクリティカルなものではないので、非同期で読み込ませることで、モダンブラウザでの読み込み速度を少し速くすることができます。
元々のコード
公式サイトのUsageに載っている以下のコード
<link rel="stylesheet" href="/path/to/styles/default.css">
<script src="/path/to/highlight.pack.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
を非同期にしていきます。
/path/to/styles/default.cssと/path/to/highlight.pack.jsの部分は各自の環境に合わせて変えてください。
cssをpreloadに
link rel="preload"を使いたいのですが、最新のブラウザでしか対応しておらず、古いブラウザだとcssが読み込まれなくなってしまいます。そこで、
ブラウザの対応を気にせず rel="preload" で CSS を非同期で読み込めるのが、JavaScript の Polyfill「loadCSS」です。使い方は head タグに script を記述するだけと簡単です。IE でもレンダリングをブロックするスタイルシートを排除でき、サイトを高速化できます。
ここを参考にcssをpreloadにします。その結果、
<link rel="stylesheet" href="/path/to/styles/default.css">
の部分が
<script>
<!-- loadCSSのコード -->
</script>
<link rel="preload" href="/path/to/styles/default.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
こうなりました。
noscriptに関しては、そもそもjavascriptが有効になっていなければhighlight.jsは動かないので、javascriptが無効の時はhighlight.jsのスタイルのcssを読み込まなくていいやと思って書いていません。
javascriptをasyncに
javascriptの場合は、async属性に対応していないブラウザでもasync属性が無視されるだけでjavascriptが読み込まれなくなるわけじゃないので簡単です。
<script src="/path/to/highlight.pack.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
ここの部分を、
<script async src="/path/to/highlight.pack.js"></script>
<script>window.addEventListener("load", function() { hljs.initHighlighting() });</script>
こうします。
highlight.pack.jsの読み込みを非同期にしたので、その直後のhljs.initHighlightingOnLoad();が実行される際にはhljsオブジェクトがまだ定義されていません。
なので、initHighlightingをaddEventListenerを使って、サイトが読み込まれた際に実行することにします。
参考
Hi, is there a way to know when highlighting is finished? Would be awesome to have ability to take a callback, so it'll work nicely with something like marked markdown parser: https://github.co...
コメント