はじめに
しばらく閉鎖状態となっていた当サイトですが、ドメインは自動更新で放置していたので、久々に復活させることにしました。
とは言っても一日に何度も更新させるような意欲は無いため、不定期で更新していく予定です。
再始動にあたり、ウェブサイトそのものをある程度見直しており、できるだけシンプルで高速に動作するように1から作り直しました。
サイト再構築を行うにあたってはjxck.ioさんおよびsuzukikenichi.comさんが大変参考になりました。この場でお礼申し上げます。
- jxck.io
- suzukikenichi.com
ウェブサイト構成
ここでは当サイト、pr1sm.comを構成している各要素について簡単に説明します。 使用しているホスティングは以前と変わらずVultrのままです。 低コストなだけでなく性能も充実しているという、非常にコストパフォーマンスが良いサービスなので重宝しています。 Vultrに関する詳細は記事化していますので、興味があればご覧ください。 ウェブサーバはずっとNGINXを使い続けています。 軽量かつ高速で動いてくれるのでスピード厨にとっては神のような存在です。 長年Vultrを利用していましたが、毎月のサーバのコストを考えた結果、Cloudflare Pagesに移行しました。 これにより、サーバ、TLS設定、CSPなどはCF依存のものになっています。 SSGはCF PagesがZolaに対応していたため、そのまま移行することができました。 ただし執筆時点ではバグがあるため、そのまま導入することができず、バイナリをリポジトリに置いて展開する必要がありました。 数年前はSSL/TLSというように、TLS(Transport Layer Security)の他にSSL(Secure Socket Layer)も付け加えていましたが、今となってはTLS主体なので、もはやSSLを付ける必要はないかもしれません(とはいえ設定でSSLの文字が入っている項目もあります)。 また、現時点ではサーバにHTTP/2を適用させていますが、もうしばらくしたらHTTP/3に更新しようと考えています。 HTTPS化に必要な証明書にはLetsEncryptを使用していますが、非常に簡単に導入することができて自動更新も対応しているので、本当にありがたいご時世になったと感じます。 昔は今は亡きStartSSLの証明書を使うなどしていましたが、当時と比べてもLetsEncryptの使いやすさには涙が出ます。 TLSの設定にはMozillaのSSL Configuration Generatorがとても便利でした。 TLSのセキュリティチェックは定番のSSL LabsのSSL Server Testが便利です。 当サイトではContentSecurityPolicyおよび複数のSecurityHeadersを適用しています。 そこそこ堅めに設定していますが、その状態でどれくらいまでのサイトなら構築できるのかというテストも兼ねています。 現在の設定では しかし、chromeとは異なりfirefoxではインラインコードしかhash指定できないようなので若干妥協しています。もし利用可能になったり、代替策があれば CSPの設定にはMozillaのObservatoryやGoogleのCSP Evaluatorがとても参考になりました。 SecurityHeadersの設定に関してはOWASP Secure Headers Projectおよびsecurityheaders.comが大いに役立っています。 なお、CSPやSHで扱うレポートには、securityheader.comの創設者であるScottHelme氏が設立したReportURIという便利なサービスがあります。 以前のサイトではWordPressを使用していましたが、全体的に軽量で動くものが欲しかったため、Rust製の静的サイトジェネレータ(Static Site Generator)であるZolaを用いてウェブサイトの構築を行っています。 Zolaの利用には一定の学習が必要ですが、依存関係にあるファイルが無く、そして高速なビルドが可能なことからとても使いやすいものとなっています。 当サイトではZolaの導入および設定方法を記した記事を作成しています。もし興味があればご覧ください。 また、Zolaでは記事の執筆にマークダウンが必要となっているため、その際のエディタとしてAtomを利用していました。 AtomはGithub社によって制作されたテキストエディタであり、数千種類もの拡張機能があるため、非常にカスタマイズ性に優れています。 しかし、2022年6月8日にGithubがAtomの開発停止を宣言したため、代替としてVisual Studio Code(VSCode)を使用することにしました。 Sunsetting Atom Visual Studio Code VSCodeはAtomと同様に拡張性があるだけでなく、軽量さも持ち合わせているので多くの人々から利用されています。 2024-10-02追記 今更ですが、ダークモードにも対応しました。 これはOSのモードによって自動的に切り替わるスタイルになっています。 Markdown(md)はZolaが必要とする記法をもとに作成します。 テンプレートエンジンは同じくRust製のTeraが使われています。 テンプレートは以下の通りです。 descriptionについてはテンプレートを改変しており、 記事のアップデート時間は しかしながら、Zolaが自動生成する なのでほんの少し手間ですが、Zolaの構成を保つことを優先にして記事の更新を行うときに限り これらテンプレートのソースは以下のリンクに置いてあります。 構造化マークアップはmicrodataを使用しています。 JSON-LDによるマークアップも検討していますが、気が向いたら対応したいとは考えています。 また、最近気付いたのですが、JSON-LDはインライン記述が必要になるものの、 そのため、動的にJSON-LDのマークアップデータを生成することで対応できますが、マークアップテストでは反映されなかったりすることもあるようです。 ただし、Googleによると動的に生成されたJSON-LDでもサポートはされるとのこと。 デザインは以前と同じくシングルカラムを採用しています。 HTTP/2が登場する前は、基本的にCSSなどのコンテンツは一つにまとめ、リクエスト数を減らすことが推奨されていましたが、現在ではサーバの設定によって並列ダウンロードができるようになったため、それを活用するために複数のCSSに分割しています。 他にもloadCSSという方法でCSSを非同期で読み込むことも考えましたが、できるだけContentSecurityPolicyを尊重したかったため、インライン記述が必要となる方法は現時点では採用していません。 その代わりに また、ブラウザがデフォルトで出力するスタイルをなるべく使用することで、CSSの記述量を減らしました。 基本的にあまり必要とされないJSは極力使わないようにしています。 現時点ではServiceWorker用のファイルが2つ( ServiceWorkerは4つのキャッシュセクションに分類(Core,Pages,Images,Assets)し、キャッシュ時間はデフォルトの24時間のままにしています。 もともとSWはIE11に対応していませんが、構文によってはエラー文章が発生して鬱陶しかったのでBabelを使ってそれをスルーできるようにコードを変換しました。 アクセス解析には興味がないのでGoogleAnalyticsは入れていませんし、サイトが激重になる原因筆頭であるAdsense関連も一切使用していません。 以前のサイトではリンクをマウスオーバーすることで先読みを行うInstantClickを採用していましたが、そもそも構成上サイト内を複数巡回する人は少なく、Lazyloadに比べるとそこまで必要にはならないと結論に至ったため、現在は使っていません。 ちなみにInstantClickは随分前から更新されていませんが、有志によって改良が加えられたバージョンが公開されているので、興味のある方は見てみるといいかもしれません。 また、類似したツールにはInstantClick作者によるInstantPageや、GoogleChromeLabsが制作したquicklinkがありますが、それらを用いた統計によると有益な効果がほとんど見られなかったようなので、こちらも使用していません。 基本的に もしブラウザ提供のLazyloadが利用できない場合には、代替策としてJavaScriptを用いてLazyloadを作動するLazysizesを適用します。 Lazysizesそのものには特に変更したい点が無かったため、デフォルトのまま使用しています。 使用する画像(大抵はjpgとwebp)は事前にエンコードをしており、jpgではmozjpeg、webpはgoogleが提供しているものを使用します。 Qualityは共に75に設定しており、どちらも非可逆圧縮で処理しています。 pngはほとんど使用しない予定ですが、事前エンコードにはzopflipngを使用しています。 zopfli zopflipng-bin zopflipngを実行する際には しかし、zopflipngは動的にエンコードを行うには時間がかかりすぎるため、サーバ内でリアルタイム処理を行ったり、大量のファイルを扱う場合には、optipngの改良版であるoxipngがおすすめです。 ちなみにZolaを経由している外部ファイル(CSS,JS,IMG等)のほとんどは設定によって それに加え、integrity属性も追加することでファイルの整合性もチェックしています。 大抵のファイルは事前にgz圧縮およびbr圧縮を行っています。 ヘッダもHTTP/2によって圧縮(HPACK)をされているので通信量を削減できます。 また、css類はminify(縮小化)することでファイルサイズの削減も行っています。 gz圧縮にはdeflate互換性のあるzopfliを使います。強度は brotli(br)圧縮は処理が異なるためdeflate互換性がありません。しかし最近のブラウザの多くは既に対応済みです。 br圧縮の強度に関してはデフォルトでも最大設定なので、そのまま使用しています。 事前圧縮されたファイルはクライアントにそのまま送信しており、ブラウザがbr圧縮に対応していれば、brの方をクライアントに提出し( 仮に両方の圧縮に対応していない場合でも、nginxのgunzip機能( 事前圧縮していないコンテンツに関してはnginxによるgzもしくはbr圧縮が動的に行われます。 圧縮強度は最低でもそこそこ圧縮できるため、動的圧縮を行う場合はサーバ負荷の軽減を優先にgzでは 余談ですが、圧縮ファイルを受信する際、セキュリティソフトによっては このケースではサーバから圧縮ファイルを受け取っているものの、セキュリティソフトが間に入ってチェックしているため、ブラウザではファイル展開後として扱われます。 とはいえ、レスポンスヘッダの表示が変わっているだけなので、通常使用においては特に問題はありません。 現時点では音声や動画は当サイトでは取り扱わない予定です。 以前のサイトではYoutubeの動画をiframeでembedしていましたが、CSPでの対応が面倒なのと大して使わないコンテンツにCSSやJSのリソースを使うのはもったいないとして、埋め込み化をやめました。 これまではRSS Feedでの配信を行っていましたが、もはや需要がほとんど無いので配信停止することにしました。Server
2024-04-03追記
TLS
CSP+SecurityHeaders
script-srcをselfにしていますが、本来はstrict-dynamicを使いつつhash指定されたJSのみを使うことを考えていました。selfは廃止するつもりです。HTML
Markdown
+++
title = "タイトル名"
description = ""
date = 2022-01-14
updated = 0000-01-01
draft = true
[taxonomies]
categories = ["web"]
[extra]
thumb = "ファイル名.jpg"
+++
ここから概要文(summary)
<!-- more -->
ここから本文
<!-- more -->以前の文章(Zolaではsummaryとして扱われる)をエスケープ処理および短縮することで別途用意しているため、実際には使っていません。updated = 0000-00-00で作成できますが、テンプレート内にとりあえず置いておこうとupdatedのみで中身がない場合(月日が00の場合も含む)はビルド時にエラーが発生してやや面倒なので、ユーザ作成([extra])で作ろうとも考えていました。sitemap.xmlやatom.xmlなどにはupdatedの時間も反映されることから、改変する必要が出てきます。updatedを追記するようにしています。draftはtrueにすることでビルド時に公開設定にならないものです。[taxonomies]はカテゴリやタグ等を設定することができます。ただし、事前にconfig.tomlでの設定が必要です。[extra]は先述したようにユーザ作成の自由に使える部分であり、このケースではthumb = "ファイル名.jpg"が記事のアイキャッチ扱いとして設定しています。当サイトではアイキャッチ画像は表示していないので内部データのみが反映されます。構造化マークアップ
type="application/ld+json"の場合はインラインでもContentSecurityPolicyに引っかかりません。CSS
rel=preloadを使っており、対応しているブラウザではファイルの事前読み込みを行うようにしています。JS
sw-loader.jsおよびsw.js)とLazyload用に1つ(lazysizes.js)を設置しており、こちらもrel=preloadで事前読み込みを行っています。ただ、Lazysizesに関してはブラウザでのLazyloadサポートが圧倒的になると同時に利用者層も厚くなれば廃止する予定です。Images
<img>にはloading="lazy"およびdecoding="async"の両方を付与させており、幅広いブラウザで読み込み最適化を行います。--lossy_transparent --iterations=20 --filters=0meを設定しています。?h=hashというクエリを付与しており、ファイルが変更されるとクエリが変更されるいわゆるキャッシュバスター(cachebust)システムになっています。圧縮
--i1000で処理しています。brotli_static on;)、対応していなければgzを渡します(gzip_static on;)。gunzip on;)により、gzファイルを解凍してから送信します。gzip_comp_level 1;、brではbrotli_comp_level 1;に設定しています。Content-Encodingがx-content-encoding-over-networkに書き換えられる模様。音声や動画
feed
構文およびマークダウン一覧
以降からは、このサイトで用いられる構文(マークアップ)およびマークダウンのテストサンプルを記述します。
マークダウン記法についてはCommonMarkのMarkdown Referenceで簡単な説明を見ることが可能です。
- Markdown Reference
各HTML要素についてはMozilla Developer NetworkのHTML 要素リファレンスにて詳細を確認できます。
- HTML 要素リファレンス
セクション2
セクション(section)は<h1>や<h2>、<h3>に<h4>で使用される見出しとなる構文です。
マークダウンでは#の数によって振り分けが行われます。
例では## テストと記述することでテストという文字が<h2>で展開されます。
ちなみにこの段落は### セクション2であり、#が3つ付いているため、<h3>です。
また、各セクションのheading(h2~)前後には<section>タグを設置しています。
Zola側でビルド時にそれぞれのhタグ前後にsectionを自動で付与してくれれば楽なのですが、現時点では未対応であり、対応してくれるかどうかも不明です。 ここはセクション3
<h4>です。
リスト
これは<ul>や<ol>の中に<li>を用いることで箇条書きのリスト化を行います。
数回半角スペース(基本的に2,3回以上)もしくはtabによるインデント1回を挿入することで入れ子を作成することも可能です(ただしolを使っている際に番号指定のリストを行った箇所では入れ子できない場合があります)。
表示上の関係から、基本的に入れ子は2つまでに留めます。 マークダウンは 入れ子は前要素の次の行で 入れ子の入れ子を追加するには 少しややこしくなりますが、各種タグをリスト内で入れ子内に加える場合は4回半角スペースもしくはタブ2回をタグの前に入力します。 ただし、 マークダウンは順序なしリスト
<ul>では順番が関係ない要素で用いられます。- 要素によって作成されます。 - 要素(-の前に半角スペース2回かタブ1回)を入力することで作成できます。-の前に4回スペースを入力します。<pre>のような複数行に渡る場合のある特殊なタグを入れ子内に加える場合は```の代わりに8回半角スペースもしくはタブ2回を対象となるすべての行に加えることで可能となります。順序ありリスト
<ol>では順序が必要となる要素で用いられます。1. 要素で作成されます(次の行からは数字は加算しなくても可)。
引用
引用には<blockquote>が用いられます。
マークダウンでは> 文章で表示を行います。
ここは文章の引用部分です。 複数行に渡って記述することも可能です。
>> 文章で二重引用を用いることもできます。引用元の最後には
<cite>タグで囲んだURLをリンク化させて記載します。
説明リスト
説明リストでは<dl>および<dt>、<dd>を用いて表示されます。
大抵のマークダウンには対応していないため、手動でタグを用いて記述する必要があります。
Zolaでは非対応です。
<dl>は説明リスト(description list)を意味し、リスト全体を囲みます。
<dt>は説明用語(description term)を意味し、リスト内の各名前を扱います。
<dd>は説明詳細(description details)を意味し、<dt>ごとの説明を記載します。
- ここは説明用語です(dt)
- ここは詳細説明(dd)です
- りんご(dt)
- 赤くて甘い(dd)
テーブル
テーブル(table)も基本的にはマークダウンに対応していないため、手動でタグを付ける必要があります。
Zolaではマークダウンに対応しています。
<table>は使用する表全体を囲みます。
<thead>は<th>タグをグループ化します。
<tr>はtable rowを意味し、表に対して水平方向の部分をグループ化します。
<th>はtable headerを意味し、表の見出しおよびタイトルとなる部分を作成します。
<td>はtable dataを意味し、見出しおよびタイトルに対応する内容(データ)を作成します。
マークダウンでは以下のような形式でテーブルを出力することが可能です。
|a |b |c |
|---|---|---|
|1 |2 |3 |
|4 |5 |6 |
出力結果はこうなります。テーブルは手打ちで行うと非常に面倒なので、マークダウン対応可能だとかなり手間が省けます。
| a | b | c |
|---|---|---|
| 1 | 2 | 3 |
| 4 | 5 | 6 |
| ファイル名(この行はth) | 元サイズ(byte) | gz圧縮後(byte) | 削減率((元サイズ-圧縮後)/元サイズ) |
|---|---|---|---|
| pr1sm-logo.svg(この行はtd) | 302 | 206 | 31.78% |
| favicon.ico(この行はtd) | 1,078 | 228 | 78.84% |
| manifest.min.webmanifest(この行はtd) | 561 | 240 | 57.21% |
| ファイル名(この行はth) | サイズ(byte) |
|---|---|
| body.min.css.br(この行はtd) | 117 |
| header.min.css.br(以下略) | 91 |
| main.min.css.br | 138 |
| markdown.min.css.br | 212 |
| footer.min.css.br | 131 |
| 合計 | 689 |
画像表示
画像は<picture>タグを用いて画像を分岐させながら表示します。
基本的にjpgを使いますが、ブラウザがwebpに対応していれば代わりにそれをクライアントに出力します。
AVIFはまだ対応できるブラウザが少ないため、今後大幅にシェアが増えた場合に追加します。
また、記事内の画像すべてに<figure>および<figcaption>を使用することで画像の補助を行います。
ページ内で表示する画像サイズは最大widthが480px、aタグを経由して直接画像を表示する場合は最大width960pxを用います。
コード
コードは<code>を用いることで表示します。
マークダウンは`コード`です(`は半角を使う)。
また、3連続のバッククオート同士でコードを囲う(```コード```)ことで<pre>も適用され、複数行に渡って表示することが可能になります。
test.html
<p>テスト</p>
<p>テスト2</p>
おわり。