71
77

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ポートフォリオのパフォーマンス向上のためにやった/やってること

Last updated at Posted at 2019-09-12

やったこと

ポートフォリオをリニューアルするのに際し、とにかく最初の描画速度を上げたかった、理由は「他にこだわりどころがなかったから」だ

作ったものはこちら(一部未完成)
リポジトリ

環境

  • 開発環境:Nuxt(generate)
  • ホスティング:firebase
    • 多分有名所のホスティングサービスの中で最速だと思っています。

WebPの使用

WebPについて

Chrome系のブラウザでしか描画できないが、ファイルサイズが圧倒的に小さくなるので、それだけパフォーマンスが向上する。

画像自体のホスティングはCloudinaryというCDNを利用した。
Cloudinaryを使うと、WebPに対応していないブラウザでは自動的に別の形式の画像を配信することができます。

AMP対応

AMPについて

AMPを使うと、スマホでGoogleの検索ページからアクセスしたときに自動的にGoogleクローラがキャッシュしたAMP対応HTMLにアクセスしてくれます。検索した時点でキャッシュされるので表示が爆速になります。

今回は、indexのみamp版のページを用意することにしました。
Nuxt generateを使っているので、amp htmlの形式に合わせたHTMLを生成するためにはhooksのタイミングでHTMLを置換する処理を走らせる必要があります。
こんな感じ

nuxt.config.js
import ampify from './src/plugins/ampify'

export default {
  ...
  hooks: {
    // This hook is called before saving the html to flat file
    'generate:page': page => {
      page.html = createAsciiArt(page.html)
      if (page.route === '/amp') {
        page.html = ampify(page.html)
      }
    },
    // This hook is called before serving the html to the browser
    'render:route': (url, page, { req, res }) => {
      page.html = createAsciiArt(page.html)
      if (page.route === '/amp') {
        page.html = ampify(page.html)
      }
    }
  }
src/plugins/ampify.js
const ampScript =
  '<script async src="https://cdn.ampproject.org/v0.js"></script>'
const ampBoilerplate =
  '<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>'

module.exports = html => {
  html = html.replace(/<html/gi, '<html ⚡')

  let styleConcat = ''
  html = html.replace(
    /<style[^>]*data-vue-ssr[^>]*>(.*?)?<\/style>/gi,
    (match, sub) => {
      styleConcat += sub
      return ''
    }
  )
  html = html.replace(
    '</head>',
    `<style amp-custom>${styleConcat}</style></head>`
  )

  html = html.replace(/<link[^>]*rel="(?:preload|prefetch)?"[^>]*>/gi, '')

  html = html.replace(/<link[^>]*rel="(?:amphtml)?"[^>]*>/gi, '')

  html = html.replace(/\s*data-(?:[^=>]*="[^"]*"|[^=>\s]*)/gi, '')

  html = html.replace(
    /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
    match => {
      return /application\/ld\+json/gi.test(match) ? match : ''
    }
  )

  html = html.replace('<link rel="amphtml" href="/">', '')

  // Replace img tags with amp-img
  html = html.replace(/<img([^>]*)>/gi, (match, sub) => {
    return `<amp-img ${sub} layout="responsive"></amp-img>`
  })

  // Add AMP script before </head>
  html = html.replace('</head>', ampScript + ampBoilerplate + '</head>')

  return html
}

これでgenerate時に /amp 以下のページだけamp対応に置換してくれます。
imgをamp-imgに置換はしていますが、コーディングの際にタグに直接 widthheight を指定して上げる必要があります(ちなみに、widthheightを直接指定するとサイズの計算を事前に済ませてくれるので画像読み込み時のガクガクがなくなります。普通のimgでも指定してあげると、体感速度が上がって良いです)
また、Styleは一つのタグでまとめなくては行けないため、generate時に一つのタグ内に収まるように、assetsの配下にcssを集約しましょう。タグ一つにまとめることでレンダリング速度も多少向上します。

また、通常のHTMLとAMP HTMLで相互にリンクを貼る必要があるため、以下のようにします。
amp側からは先程の置換で一緒にリンクも張っています

nuxt.config.js
export default {
   link: [
       {rel: 'amphtml', href: './amp'}
   ]

今回はindexのみamp対応にしているため、indexからのみ貼ったほうがいいのですが、めんどくさかったので全ページに貼っています()

generateしたらこちらでテストしてあげると良いです。

imgにdecoding="async"をつける

decoding="async"と明示的に書くことによって、画像の描画をコンテンツの表示を邪魔しないように非同期的に行ってくれます。
また、Chrome限定ですが loading="lazy" もつけてあげると良いでしょう。

71
77
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
71
77

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?