dvg-179

GatsbyJSで Progressive High Performance Blog

このブログは GatsbyJS という静的ジェネレーターで作成している。
前回までも Gatsby を使ったブログ制作環境について書いてきたけど、ドキュメントなど読み進めて、だいぶわかってきたので色々とカスタマイズを始めている。

今週、Hello World! Progressive Web-Blog!! という Google の @uskay さんのブログがはてブに上がっていた。「Progressive Web-Blog」ってキャッチーで、いい言葉だと思う一方、ライバルな感じもしてじっくり読ませてもらった。 Gatsby はまさに Progressive Web-Blog を作るのには打ってつけのジェネレーターなので。

Progressive Web-Blog

前述の @uskay さんのウェブボウズは、Web Components + Service Worker + Firebase + PRPL Pattern で Progressive Web App(PWA) 化して、すんごいパフォーマンスのブログを実現されている。
Service Worker のキャッシュを考慮しても、「Web Components ってパフォーマンスもいいのか」とビックリした。Chrome の Audits のスコアを見ても、ほぼ満点なスコア…。

しかし、Web Components の書き方を見てると HTML の拡張というよりは、 JS がメインで書き方が React とそんなに変わらない。
JSX を使わず、テンプレートリテラルで書いてるだけで、ほぼ似たような書き方に見える。動的に書き替えないようなサイトなら、Web Components は React 使わずに組めて、いい感じな気がする。

Gatsby で Progressive Web-Blog

Gatsby 自体に Service Worker がデフォルトで入っているので、SSL 環境で公開さえすれば(または localhost) Service Worker が動く。
DNS の設定を置いている Cloudflare を設定変更して、この dvg.179.jp も SSL に入れて、Service Workerが有効にできた。 Gatsby 側の Service Worker 設定をするところが見つからないので、細かな設定はできていないけど、とりあえず PWA 化に向けて一歩前進。

DNSによるSSL化

VPS に SSL 証明書インストールして、nginx の設定して…とかハードル高いとビビってたけど、DNS側だけで SSL にできてしまえるのは便利。 実際には DNS からサーバー間は平文での通信かもしれないので、ホントのプロダクションでは推奨されない方法なのかもしれない。

Gatsby 側での追加設定

現在このブログは gatsby-starter-blog という starter ≒ テーマ を使用している。 この starter の場合、PWA に必要な Web App Manifest が出力されない。

ただ対応は簡単で、Gatsby 作者が公開している gatsby-plugin-manifest を追加すればいい。 gatsby-config.json に必要な項目を追記して gatsby build すると manifest.json が出力されるようになり Google の PWA チェックリストでも合格点をもらえる PWA を出力できる。

gatsby-config.js(一部抜粋)

module.exports = {
  plugins: [
    {
      resolve: `gatsby-plugin-manifest`,
      options: {
        name: "dvg - 179",
        short_name: "dvg 179",
        start_url: "/",
        background_color: "#e2e22d",
        theme_color: "#e2e22d",
        display: "minimal-ui",
        icons: [
          {
            src: `/favicons/profPig.jpg`,
            sizes: `180x180`,
            type: `image/jpg`,
          },
          /*
          // ホントはこの二つを設定する
          {
            src: `/favicons/icon-192x192.png`,
            sizes: `192x192`,
            type: `image/png`,
          },
          {
            src: `/favicons/icon-512x512.png`,
            sizes: `512x512`,
            type: `image/png`,
          },
          */
        ],
      },
    },
  ]
}

現状、僕のアイコンのブタの元画像が見つけられなくて、大きなアイコンを作れないので PWA が 82点止まり。
体感的には圧倒的には速い Gatsby だけど パフォーマンスのスコアが 97点なのもちょっと不満。現時点ではウェブボウズさんに完敗なのが悔しい!PWA はイイとしてもパフォーマンスのスコア(ウェブボウズさん:98)で負けているのは悔し過ぎる。

今後全部満点取れるようなカスタマイズをしていきたい。目指せハイパフォーマンス・ブログ。
ついに iOS にも次期11.3から Service Worker が来る( Beta では公開済み)ので、今年は Service Worker → PWA 究極のハイパフォーマンスサイトがどんどん盛り上がりそう。

dvg179 Auditsのスコア

カスタマイズに着手した!

PWA 化と並行して、Gatsby のドキュメントや Starter のコードを覗き、まずは最低限のカスタマイズにも着手した。 やりたいことは色々とあるけれど、今回はまず以下の2点だけ実施した。

  • SNSシェアボタン設置
  • OGPの追加

SNSシェアボタン

シェアボタンは、(Hatch tech blog)[http://hachibeedi.github.io/] さんや Gatsby の Starter のソースを参考にした。(というかほぼそのまま)

Twitter や Facebook などのグローバルなサービスに関しては、React-share というモジュールがデフォルトで、簡単にボタンが設置できる。ソースを見た Starter もほぼその実装だった。

はてブを React-share に組み込み PR を目指そうかとも思ったけど、とりあえず簡単に組み込める方法にとどめた。

src/components/ShareBtn/ShareBtn.jsx(一部抜粋)

import React from 'react'
import Helmet from 'react-helmet'

import './ShareBtn.css'

export default function SNSShare({title, link}) {
  return (
    <ul className="snsShare">
      <Helmet>
        <script type="text/javascript" src="//b.st-hatena.com/js/bookmark_button.js" charset="utf-8" async="async" />
      </Helmet>

      <li className="snsShare_unit">
        <a
          href="http://b.hatena.ne.jp/entry/"
          className="hatena-bookmark-button"
          data-hatena-bookmark-layout="vertical-normal"
          data-hatena-bookmark-lang="ja"
          title="このエントリーをはてなブックマークに追加"
        >
          <img
            src="//b.st-hatena.com/images/entry-button/[email protected]"
            alt="このエントリーをはてなブックマークに追加"
            width="20"
            height="20"
            style={{border: 'none'}}
          />
        </a>
      </li>
    </ul>
  )
}

Gatsby 自体に Style-loader が入っているので、JSファイルで直接読み込める。 スタイルはホントは Scss で書きたいけれど、変換が面倒なのでコンポーネントごとに css で書き読み込んでいる。

コンポーネントごとに CSS ファイル置いて、ディレクトリにまとめておくと、依存関係もわかりやすいし、とても使い勝手がいい。
まさにコンポーネント思考そのもの。

React Helmet

シェアボタンの設置自体はシンプルだけど、合わせてOGP の設定も必要で、こちらの方が少しややこしい。

Gatsby の魅力の一つは静的なページに書き出した後、ブラウザでの表示が SPA(実際はPWA) になること。
ただ SPA の場合、記事の詳細ページを表示した際に OGP(Open Graph protocol) などの書き替えが必要になる。
そんな時、どこからでも <head></head> 内を書き替えれるのが React Helmet という便利なモジュール。

src/components/Meta/Meta.jsx(一部抜粋)

import React from 'react'
import Helmet from 'react-helmet'

export default function Meta({postNode, postPath}) {
  return(
    <Helmet>
      <meta property="og:url" content={url} />
      <meta property="og:type" content="article" />
      <meta property="og:title" content={title} />
      <meta property="og:description" content={description} />
      <meta property="og:image" content={ProfPig} />
    </Helmet>
  )
}

みたいな感じで、どこにでも好きなところに書いたら、最終的に <head> 内に出してくれる。

今、次の課題

SNS シェアボタンは設置できたけれど、ブログ全体のスタイルを触ろうと思うと、僕が使っている gatsby-starter-blog はカオス感がある。
typography.js と各 React コンポーネントのスタイル定義が入り混じっている箇所が多く、どこでスタイルが定義されているのか見通しが悪い。

gatsby-starter-blog からスタイル定義を抜いた starter がコミュニティで公開されている。たぶん、大体の人にとって typography.js + 直スタイル定義がわかりにくいのではと予想する。

ようやく作法的なものがわかってきたので、もう少し深く触っていこうと思う。 次回以降、Gatsby starter の比較とか、カスタマイズ関連、Audits スコアアップとか書いて行く予定!

  • このエントリーをはてなブックマークに追加

デザインとエンジニアの間で彷徨う開発ブログ。
by nnjyami(んじゃみ)