Web

highlight.js のハイライト処理を Web Workers で実行する

投稿日:2021年3月15日 更新日:

1. highlight.js の利用方法

Webページ上でシンタックスハイライトを行う JavaScript ライブラリ「highlight.js」ですが、普通に読み込んで使うとページの読み込みや表示に時間が掛かってしまいます。Web Vitals の指標でいうと Largest Contentful Paint (LCP) の評価が低下するということです。

しかし「Web Workers を使って highlight.js を利用する方法」であれば、ページの読み込みに時間が掛かる問題をかなりのところまで低減できますので、その方法を紹介します。

2. highlight.js を使う一般的な方法

念の為、highlight.js を利用する一般的な方法もここに書いておきます。

※ この内容は、How to use highlight.js に書いてあります。

例えば、Webページに JavaScript コードを載せる場合であれば、まずそのコードを <pre><code class="js"></code></pre> で囲んで記述します(>&gt; と書きます)。

<pre><code class="js">window.addEventListener('DOMContentLoaded', (event) =&gt; {
  console.log('DOM fully loaded and parsed');
});
</code></pre>

あとは、highlight.js の CSS ファイル・JavaScript ファイルを読み込み、hljs.highlightAll(); という JavaScript コードを実行するように記述します。

<link rel="stylesheet" href="/path/to/styles/default.css">
<script src="/path/to/highlight.min.js"></script>
<script>hljs.highlightAll();</script>

以上により、JavaScript コードがハイライト表示されます。

この方法は簡単でよいのですが、先程書いたように「ページの読み込み」や「ページを表示する処理」に時間が掛かります。

3. Web Workers を使った highlight.js の利用方法

次に Web Workers を使った方法です。

こちらも How to use highlight.js で説明されているのですが、最低限の説明しかありません。ここではもう少し実用的なところまで付け加えて説明します。

先程と同様に、Webページに JavaScript コードを載せる場合であれば、まずそのコードを <pre><code class="js"></code></pre> で囲んで記述します。ここはもちろん同じです。

次に以下の内容を記述した JavaScript ファイルを作成してWebサーバー上に配置し、クライアントからアクセスできるようにしておきます。ここでは、このファイルの名前を hljs-worker.js とします。

onmessage = function(event) { 
  importScripts('/path/to/highlight.min.js'); 
  const result = self.hljs.highlightAuto(event.data); 
  postMessage(result.value); 
}

そして HTML 側には、以下の JavaScript コードを記述します。

<script>
addEventListener('load', function() { 
  //-------------------------------------- 
  // Apply highlight.js using Web Workers 
  //-------------------------------------- 
  (() => {
    // 処理を軽くするため、なるべく対象を絞ったセレクタを指定する
    const codes = document.querySelectorAll('pre > code'); 
    // <pre><code> がなければ、ここで処理を終了させる
    if (codes.length == 0) return;

    // Add stylesheet link
    const link  = document.createElement('link'); 
    link.rel  = 'preload'; 
    link.href = '/path/to/styles/default.css'; 
    link.media = 'all'; 
    link.as = 'style';
    link.onload = function() { this.rel = 'stylesheet' };
    document.querySelector('head').appendChild(link);  // CSSファイルが読み込まれる

    // <pre><code> 毎に highlight.js でハイライトする
    codes.forEach(code => { 
      // nohighlight クラスが指定されていれば何もしない
      if (code.classList.contains('nohighlight')) return; 
      code.classList.add('hljs'); 
      // code 毎に専用の onmessage をセットするので、それぞれに専用の Workerインスタンスが必要
      const worker = new Worker('/path/to/hljs-worker.js'); 
      worker.onmessage = event => code.innerHTML = event.data;
      worker.postMessage(code.textContent); 
    }); 
  })(); 
})
</script>

処理の内容については、コメントに書いておきました。

ポイントは以下です。

  • ページ上に <pre><code> がなければ、highlight.js の CSS ファイル・JavaScript ファイルが読み込まれることはありません。
  • ハイライトするページでも、メインスレッドとは別のスレッドでハイライト処理が実行されるので、Core Web Vitals の指標への影響はかなり小さいです。
  • <pre><code> 毎に Worker インスタンスを生成しており、hljs-worker.js ファイル内の importScripts() がその回数だけ実行されますが、highlight.min.js ファイルはブラウザで最初の1回でキャッシュされたものがそれ以降利用されます(Webサーバーとブラウザの設定にも依りますが)。

4. まとめ

highlight.js の一般的な利用方法と比べると、Webページの表示がかなり速くなります。最近重要になってきた Core Web Vitals という指標を重視するのであれば、Web Workers を使った方法しかありえないという判断になるはずです。手順は少し面倒ですが、Webページが速く表示されるというのは、ユーザーの立場から見ても望ましいことです。

Web

シンタックス・ハイライト・ライブラリ「highlight.js」の使い方

2018.12.22
Web Vitals

highlight.js が引き起こすレイアウト・シフトを防止する

2021.02.01
Web Vitals

LCP を意識した Highlight.js の読み込み方

2021.02.04

📂-Web

執筆者:labo


comment

メールアドレスが公開されることはありません。

関連記事

Web

複数のGoogleアカウントのGmailページを一括で開く

複数のGmailアカウントのメールページを一括で開く方法について書いています。

Web

HTTP の Range ヘッダフィールドを使い、ページの一部分だけを取得する

HTTP/1.1 の Range ヘッダフィールドを使って、ページの一部分のみを取得する実験です。 目次1. Range ヘッダフィールドとは?2. 環境3. 使うツール4. 対象ページ5. 実験6. …

DokuWiki

DokuWiki のプラグイン開発に関する情報

DokuWiki をなるべくスマートにカスタマイズしようとすると(設定変更以上のことをやりたい場合です)、テンプレートかプラグインを自作せざるを得ません。他の方法があまり用意されていないためです。 テ …

no image

ドメインに関して気を付けること

目次TLS証明書ドメインの乗っ取り1. TLS証明書が発行されてしまうとまずい2. メールアドレスが利用されてしまう TLS証明書 証明書の期限を短くする。 ドメインの乗っ取り 1. TLS証明書が発 …

ICTリテラシー

無料レンタルサーバーとDokuWiki で作る自分用情報サイト

本サイトに パソコン内に自分専用の情報データベースをつくる というページがあります。詳細はリンク先を見て頂くとして、本ページではこれに関連して、「自分専用の情報サイトを作る」ためのオススメの方法につい …