Full-stuck engineer(Not Full-stack)
JS/PHP/Go/Docker/Nginxなど。技術または趣味よりの発信ブログです。このブログ自体も自分がnetlify/gatsbyJS/Reactで書いてます。一部の記事はgithubアカウントでコメントできます。
元々からブログを移行したいと話しており、本日ついにブログを移行しました。
とりあえず、先にパフォーマンスから見ていただきたい。
FCP : 900ms (モバイル/CPU Slowdown時)
ついに念願の Lighthouse パフォーマンス 100 を達成しました。 LighthouseではCPUを絞っているので遅いですが、
自分の PC では DOMContentLoaded の値が 約10msです。
FCPは250msくらい。
阿部寛を超えるための技術: はてなブログから Nuxt に移行した話
このブログに先を越されてしまいましたが、ちなみにこのブログは・・・
阿部寛にはFirst Contentful Paint 10ms差で勝ったっ!
(実際は誤差みたいなもので、何回かやってると負けることもありますが)
あちらは Vue、こっちは React なので、差別化は出来てるかと・・・ まあ計測した値によるけどもとほぼ一緒(体感は変わらず)という感じです。
ちなみに、元々の サイト はこんな感じでした。
元々のサイトは Wordpress 製ですが、このサイトもかなり最適化されており、普通のサイトと比べると十分早かったはずです。
簡単に説明するとこんな感じです。
このようなパフォーマンス改善を入れることにより、lighthouse の Perfomance 値は 96 となっていました。
普通なら「これで十分じゃない?」という感じではありますが、Wordpress での運用は、自分としてはこういった不満がありました。
デフォルトで Wordpress はマークダウンをサポートしていません。 そのため、JetPack のマークダウンプラグインを使用して書いておりましたが、やはりサイト上のエディタを使って書くのは少しやり辛さがありました。
いろいろできて便利だと感じる反面、ほとんど使わない機能や設定が複雑なため使わない機能もありました。 また多機能な分 MySQL などのサーバの用意や実際に動くサーバなども用意しなくてはならず、メモリ不足で自分が契約している VPS が落ちてしまうことも。
WordPress を使っていて外せないのがセキュリティ問題です。 ログインページには攻撃は来ますし、大きな脆弱性が判明してよくニュースになります。 アップデートはしていましたが、使っている身としてはやっぱりうんざりする事件というのもありますね。
Wordpress は古い歴史のある CMS ですので、基本的にサーバでのレンダリングが必要です。 そのためまず SPA な設計ではありませんし、Progressize Web App 対応するというのは難しいです。
後は基本的に脱 jQuery をやりたかったということもあります。元々のサイトでは jQuery 読み込みがパフォーマンスを下げており、これ以上上げるにはjQueryをやめるという選択肢しかないといった感じでした。
今回の技術スタックはこんな感じです。
元々から移行に静的サイトジェネレータを考えており、最初はHexoやHugoなどを試してみました。
しかし Hexo は基本的に git に記事を含めなきゃいけないということがあり、1 文字の誤字修正などを頻繁に行う自分としてはあまりハマらず。 また、やはり SPA かつ PWA などにも対応できる技術スタックでないと、「自分が考える爆速にはならないのでは?」という気持ちがありました。
そんな中出会ったのが GatsByJS です。
GatsByJS のユニークな点として、ビルド時にデータソースからデータを取得し、GraphQL を使用することで API のように取得ができるという点です。 画面は React でレンダリングするので、静的サイトかつ SPA/SSR で PWA な今時のモダン Web が結構簡単に立てられます。
プラグインを通して大体のものが対応しており、json ファイルなどはもちろん、Wordpress Rest API を通しての取得なども可能です。
テンプレートのようなものも多く公開されており、自分は gatsby-starter-calpa-blog というスターターを使っています。
こちらのスターターは、Google Analytics 対応や github の issue を使ったコメント機能など、機能やデザイン的に理想に近いと思ったため採用。
また一部要らない部分や不具合なども含めて自分向けに書き直し、最適化しているという感じです。
当然、Wordpress を捨てると決心したのですが、やはり Web で記事を書き留めることが出来る CMS 管理ツール自体は欲しいと思っていました。 この Contentful というサービスはヘッドレス CMS というものであり、つまり CMS の管理画面だけを提供するサービスで、Rest API などからデータを取得できるという感じです。 GatsByJS には Contentful をデータソースとする plugin があり、元々のスターターが採用していたというのもあってこれに決めました。 個人ブログ記事であればほぼ無料で記事を書けますし、画像などもアップロードできるのでかなりお気に入りのサービスです。
Netlify は静的ページのホスティングサービスです。 git プッシュや Webhook から CI を使ってサイトを配信できます。 そのため、contentfulで記事を更新したタイミング飛ばすようWebhookの設定を行っていれば、自動更新が可能です。
パフォーマンス面でも TLS1.3 対応や http2 対応、CDN なども持っており、SPA サイトを配信するには最適なサービスとなっています。
しかも、これも個人レベルの用途であればまず無料で使えます。
ここで気づいたかと思われますが、このブログ自体は今のところはすべて「完全無料」で成り立っています。大手サイト並みにアクセスが来るのであればまた考える必要がありますが、そうなることはまずないためこれからも当分無料でサーバーレスです。凄すぎでは?
ここまで早くなった理由として、このような最適化を行いました。
元々 GatsByJS は静的ジェネレータのため、その時点でパフォーマンス的に強いです。 そのため静的ページのホスティングに最適化された Netlify とは非常に相性が良く、修正も CI が行ってくれるので非常に開発し易いです。
元々 jQuery が使われているテンプレートだったのですが、ソースを見る限りほとんど依存しておらず、簡単に撤去出来ると感じたため撤去しました。 一番の問題点として使用している CSS フレームワークである Bootstrap が jQuery を要求するという部分なのですが、ここは bootstrap の jQuery 依存を目指す OSS であるbootstrap-nativeに置き換えることで対応できました。 その他、jQuery に依存した js の排除なども行いました。
元々 CSS が一部インライン化されていない箇所があり、CSS をインラインで処理するように変更いたしました。 CSS インラインで行うことにより、DOM 構築時にほとんどレンダリングのブロックをしないため、DOMContentLoaded の値はかなり下がりますし、実際読み込みが少なくなるので早くなります。
これはテンプレートが元々対応していたのでそのままですが、画像はすべて遅延ロードをしています。 遅延ロードをすることで CSS のインライン化と同じく、初期のレンダリングのブロック回避につながります。
遅延ロードにはlozad.jsを使用しています。 サイズは 1KB 以下の軽量ライブラリで、パフォーマンスを考えてもかなり良いです。
ServiceWorker(Workbox) を使用することにより、このブログのオフラインとキャッシング対応を行っております。 ちなみに、プラグインを入れるだけでキャッシュ設定なんかは既に GatsByJS 側がサポートしてくれていますので、自分はほとんど設定していないです。 また、プレフィッチ(リソース先読みの機能)に関しては、GatsByJS がデフォルトでサポートしているようです。リンクを画面上に持ってきたタイミングでもはや勝手に行ってくれます。
SEO等の問題にかかわるであろうSSRに関してもGatsByJSがデフォルトでサポートします。 SSRなら静的ファイルは無理なのでは?と思いますが、GatsByJSはSSRで配信されるファイル自体を静的に持っているため可能なのです。
こういうところが GatsByJS 最高かよと感じるところです。 なんで国内で流行らないんだ?もっと流行れという気持ちが強い。
このサイトのソースコードは github にそのまま上げています(API の接続情報以外)。
potproject/blog.potproject.net
ここに書いていないことも結構ありますが、SEOでのmetaタグやXMLフィードなどもサポートしており、ブログとしては必須なものは揃っているはず。
ほぼそのままクローンして start していただければ、動くはずです。 まだまだ直せていない部分や実装したい部分、コード的にわかり辛い部分も多いため、これからもブログの修正等を行っていき、とりあえず Lighthouse オール100を目指す予定です。
後は、これを機にブログの執筆意欲がもっと出るように・・・