🏗️

自作フレームワークでポートフォリオサイトを作ってみた話

2022/08/27に公開

自作したフロントエンドフレームワーク Jelly を使って SPA を構成しました。
使用した技術や工夫した点などを紹介します。

完成したもの

https://yukikurage.net


使用技術

PureScript

Github リポジトリ:
https://github.com/purescript/purescript

PureScript は Haskell ライクな AltJS です。特徴は

  • 関数が第一級オブジェクト
  • 静的型付け
  • 関数の純粋性の保証
  • 正格評価

などです。

Jelly

Github リポジトリ:
https://github.com/yukikurage/purescript-jelly

自作のフレームワークです。

仮想 DOM を使用せず、状態と DOM を直接結びつけているのが特徴です。

詳しくは

Zenn の記事:
https://zenn.dev/yukikurage/articles/4735819c3b421b

東京工業大学デジタル創作同好会 traP のブログ:
https://trap.jp/post/1656/

を参照してください。

TailwindCSS

公式サイト:
https://tailwindcss.com/

ユーティリティファーストな CSS フレームワークです。

class に文字列を設定できるなら任意の言語、任意のフレームワークで使用できるので、便利です。

Marked

Github リポジトリ:
https://github.com/markedjs/marked

Markdown パーサーです。Markdown を投げると html にしてくれます。使い勝手が良いです。

Highlight.js

公式サイト:
https://highlightjs.org/

Markdown のコードブロックにシンタックスハイライトをつけるために使いました。

ブログ記事 Markdown テスト で実際に動いています。

追記 Highlight.js の高速化

PageSpeed Insights のスコアが悪い原因が Highlight.js の使い方であることが分かったので修正しました。

結果、モバイルのスコアは 55 → 95、PC のスコアは 95 → 100 に上がりました。

Highlight.js はそのままだとめったに使わない言語のシンタックスも読み込むので、以下のように変えます。

↓ これを

import hljs from "highlight.js";

↓ こう

import hljs from "highlight.js/lib/core";
import javascript from "highlight.js/lib/languages/javascript";
import css from "highlight.js/lib/languages/css";
import haskell from "highlight.js/lib/languages/haskell";
import typescript from "highlight.js/lib/languages/typescript";
import go from "highlight.js/lib/languages/go";
import xml from "highlight.js/lib/languages/xml";
import markdown from "highlight.js/lib/languages/markdown";
import bash from "highlight.js/lib/languages/bash";

hljs.registerLanguage("javascript", javascript);
hljs.registerLanguage("css", css);
hljs.registerLanguage("haskell", haskell);
hljs.registerLanguage("typescript", typescript);
hljs.registerLanguage("go", go);
hljs.registerLanguage("xml", xml);
hljs.registerLanguage("markdown", markdown);
hljs.registerLanguage("bash", bash);

使う言語セットは各自変えてください。これでバンドルサイズが 1.2 MB から 278.4KB まで小さくなったので、だいぶ速度が変わりました。

Github Pages

デプロイ先に使っています。最近(?) Github Actions から直接デプロイする公式の方法ができたので、ついでにそれを使っています。

詳しくは
https://github.com/actions/deploy-pages

追記 Contentful

ブログと Works の配信にヘッドレス CMS である Contentful を使いました。

https://www.contentful.com/

マークダウンエディタがあり快適です。

また、Image の大きさやフォーマットをリクエストパラメーターで制御できるのが面白いです。

以下の記事が参考になりました。

https://dev.classmethod.jp/articles/contentful-image-optimization/

Google Fonts

Web フォントで良い感じにしました

FontAwesome

Web フォントで良い感じにしました 2

工夫した点

デザイン

自分はデザイン屋でもなんでも無いですが、できる限り妥協せずに作りました。

意識したのは

  • コンテンツの表示時に余計なアニメーションを入れるのは最低限にする
  • ページを広く使う
  • レスポンシブなデザインにする

などです。

特に三個目は Tailwind CSS との相性が良く簡単に実装できました。

また、このサイトを作るに当たってロゴを作ったりもしました。こうすると、ファビコンとかに使えて良いですね。

カラーモード

フッター部分にあるカラーボタンでテーマを変更できます。

この仕組みには Jelly の Context を使っています。

具体的には

https://github.com/yukikurage/web-portfolio/blob/master/src/Contexts/ColorMode.purs

で ColorMode の Context を定義して、

https://github.com/yukikurage/web-portfolio/blob/3056e1cc9e65f45664085ea56a194cb0522381f0/src/Main.purs#L27

で実際に provide しています。

このようにすることで、どのコンポーネントからも現在の ColorMode を取ることができますが、

https://github.com/yukikurage/web-portfolio/blob/3056e1cc9e65f45664085ea56a194cb0522381f0/src/Contexts/ColorMode.purs#L153

ついでに useColor Hooks を作って 1 行でテーマが適用できるようにしました。

例えばこのように使えます。

https://github.com/yukikurage/web-portfolio/blob/3056e1cc9e65f45664085ea56a194cb0522381f0/src/Components/PageTitle.purs#L25

ルーティング

SPA ですので、ルーティングはハッシュを使ってやっています。

ページを定義してカラーモードと同じようにコンテキストで管理しています。

https://github.com/yukikurage/web-portfolio/blob/master/src/Data/Page.purs
https://github.com/yukikurage/web-portfolio/blob/master/src/Contexts/Page.purs

NotFound ページも作ったりしました。

https://yukikurage.net/#aaaaaaaaaaaaaa

高速化

Google Fonts や FontAwesome が遅かったので改善しました。

Google Fonts は必要なフォントを直接配布するようにしました。

FontAwesome は必要な部分だけ読み込むようにしました。

例えば今回は About ページで他のサイトへのリンクを表示するためだけに使っているので、brands 以外いりません。したがって

<link
  rel="stylesheet"
  href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/all.min.css"
/>

これを

<link
  rel="stylesheet"
  href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/fontawesome.min.css"
/>
<link
  rel="stylesheet"
  href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/brands.min.css"
/>

こうしました。正直そんな速くなったかといわれるとうーんです。

追記

上記 Highlight.js の最適化でずいぶん速くなりました。

Markdown で本文を記述

いちいちサイトの中身を直接書いていたのではやってられないので、Markdown で書けるようにしました。具体的には About の本文、Works の詳細、Blog の記事です。

シンタックスハイライトも効くようにしたので、結構使えると思います。

実装はここです。

https://github.com/yukikurage/web-portfolio/blob/master/src/Components/Markdown.purs
https://github.com/yukikurage/web-portfolio/blob/master/src/Components/Markdown.js

ランダム背景

背景はランダムで表示されます。少しでもゲーム性があった方が面白いと思ったからです。

全部で 8 種類あります。

画像圧縮

これも高速化といえば高速化なのですが、webp にして、なおかつ画像サイズを小さくしました。

若干ガビガビなところがあるので今後修正します。

https://gist.github.com/tabrindle/ed9f77b4e96f4c98b49b

を参考にしてコマンドで圧縮画像を生成しています。

https://github.com/yukikurage/web-portfolio/blob/master/convert_webp.sh

(結構ごり押し!)

スマホ対応

画面が縦長でもきちんと表示できるように調整しました。こればっかりは DevTools でスマホ表示を見ながらちょっとずつ変更を重ねる必要がありそうです。

感想

フレームワークからサイトを作るというなかなか無い経験をできたのは大きいと思います。

今後はこれを作るに当たって得た知見を Jelly にフィードバックし、改善していこうと考えています。

また、Tag でフィルタリングする機能、Pagination などは実装できていないので、それも実装する予定です。

ヘッドレス CMS を使ってブログを管理したり (使いました!) SSG 化するのも面白そうです。

以上、短い記事でしたが、何かの参考になれば幸いです。

GitHubで編集を提案

Discussion