なうびるどいんぐ

脳みそ常時-3dB

【Hugo】シンタックスハイライトが不要な時にCSSを読み込まない

      HimaJyun

タイトル通りの奴です。Hugoではシンタックスハイライトも静的に実行できるので、jsの実行が減ってクライアント側の負荷を軽減できる。

で、せっかくjsが減って負荷が減ったんだから、どうせなら不必要な時にCSSを読み込まないようにして転送とCSSのパースも減らしたいよね、的な?

スポンサーリンク

CSSの"賢い"ローディング

前回の記事(【Hugo】Table of Contentsをjsなしでコンテンツの中に移動する)と同じように、まず最初にアプローチを説明しておこう。

Hugoではconfig.tomlにpygmentsUseClassesを指定するとハイライトを囲んでいるpreにclassが付くようになる。

pygmentsUseClasses = true

(pygmentsUseClassesを使うと逆にpygmentsStyleは使えなくなる。その辺りは修正が必要)

と、いう事は……?そう、そのclassが付いてるpreが存在するかどうかでCSSを読み込むかどうかを切り替えればいいだけ。

コード

といってもやる事は簡単、ぶっちゃけ「記事にするほどか?」と思うくらい単純。

.Contentから<pre class="chroma">を探して切り替えるだけ。

{{- /* .Contentからchromaクラスの付いたpreを探す */ -}}
{{- $find := findRE `<pre class="chroma">` .Content 1 -}}

{{- /* 数をカウントする */ -}}
{{- $len := len $find -}}

{{- /* 数が1以上(見つかった)かどうか判定 */ -}}
{{- if ge $len 1 -}}
    {{- /* 読み込む */ -}}
    <link rel="stylesheet" href="CSSのURL">
{{- end -}}

これは次のように1行でまとめて書いてもOK。

{{- if ge (len (findRE `<pre class="chroma">` .Content 1)) 1 -}}
    {{- /* 読み込む */ -}}
    <link rel="stylesheet" href="CSSのURL">
{{- end -}}

Hugoには正規表現で検索するfindREがあるが、これの非正規表現版はなぜか存在しない。仕方ないのでfindREで探している。

それと、今回は<pre class="chroma">があるかどうかだけ分かればいいので、findREの第三引数(limit)でマッチ回数を1回だけに制限している。

と……それだけなのだ、これで記事が終わってしまうのだ。

設定で切り替える

さすがにこれで記事を終わらせるとアレ(語彙力)なので、フラグ切り替えのコードもついでに。

と言っても簡単、ifの条件が一個増えるだけ。

{{- if (.Param "highlightSmartLoading" | default true) -}}
    {{- /* 必要な時だけ読み込む */ -}}
    {{- $find := findRE `<pre class="chroma">` .Content 1 -}}
    {{- $len := len $find -}}

    {{- if ge $len 1 -}}
        <link rel="stylesheet" href="CSSのURL">
    {{- end -}}
{{- else -}}
    {{- /* 常に読み込む */ -}}
    <link rel="stylesheet" href="CSSのURL">
{{- end -}}

判定が上手く動かない時とかに役立つかもしれない。

余談

これは書いてて思ったことなのだが、ぶっちゃけご丁寧にCSSの読み込みを切り替えるよりファイルをひとまとめにして常に読み込んでしまった方が"早い"と思う。

ファイルが複数あると当然ながらその分だけHTTPのやり取りが往復するわけで、CSSのサイズが小さいなら往復のRTTとかの方が大きいだろう。

ましてやCSSなんてgzip転送されるだろうし、なおさら。

 - Web制作