画像や Google Fonts のチラつきが気になったので datauri を使って改善

背景画像が占める領域が大きいので読み込み時のちらつきが気になる。(Chromeを使用)

これは画像のキャッシュが効いていても解消されませんでした。

ヘッダー背景
※GIF画像。更新を連打しています。

キャッシュをしていても、結局のところ「スタイル読み込み → 画像の非同期読み込み」という順番は変わらないためだと思われます。

つまりは背景の部分だけ同期的な読み込みをすればいいわけで、結論を出すのは簡単でした。

ということで datauri を使おう

厳密には同期じゃないのですが、datauri で同期的に画像を使うことができます。

data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%221280%22%20height%3D%22100%22%20viewBox%3D%220%2099.75%201280%20100%22%3E%3Cpath%20fill%3D%22%2374716D%22%20d%3D%22M640%20201.1c-287.512%200-534.245-40.46-640-98.158V240h1280V102.94c-105.755%2057.7-352.488%2098.16-640%2098.16z%22%2F%3E%3C%2Fsvg%3E  

単調な背景画像なので datauri にしてもこの程度の量です。

SVG画像なので base64 でのエンコードはせずにURLエンコードで済ませました。

ついでにロゴの部分も

ロゴというのはこやつの事です。

deerest

複雑なパスゆえに禍々しくなったので画像で。

ヘッダーロゴのURI

文字サイズをかなり小さくしてもコレです。

大きいサイズの物に datauri はご法度な風潮ありますが、この禍々しさを見れば納得。
変数や mixiin にして隔離したほうがよさそうです。

画像を datauri で同期的にするという事は、それだけレンダリングブロックの時間も長くなるので、そこが datauri を使うかどうかの悩みどころ。

ロゴに関してはそれでもちらつきが気になったので datauri 化しました。

datauri は無理して使うことはない

あんな禍々しい事しておいてアレだけど…。

datauri は「リクエスト数を抑えられる」といった紹介が多いですが、インターフェースで使われている画像のリクエストに関してはキャッシュが効いているため、そこまで気にする必要はないんじゃないかなぁと私は考えています。
(かといってキャッシュされていないであろうコンテンツ中の画像に datauri を使うのもナンセンスだけど)

ただ、スタイルシートもキャッシュしてもらえるので、結局のところ非同期がいいのか同期がいいのかという話にはなりそうです。

せっかくのキャッシュ機能を殺してしまうので、imgタグなどのドキュメントの要素に datauri はあまり向かなそうです。

もちろん、Google Analytics でいう「New Visitor」がほとんどを占めているようなサイトではリクエスト削減の効果は大きいでしょう。

ちらつき解消もヘッダーのみで十分

UX向上のために、今回の記事テーマである画像のちらつきは解消しておくのも一つの手です。

しかし、このちらつきもロードをする際に一瞬発生するだけなので、ヘッダー周りの画像だけ datauri 化し、フッターなどは画像キャッシュにお任せしても良いと思います。

リクエスト数で困っているなら話は別ですが、フッターに目が行くまでに読み込みは終わっていると思うので、画像は非同期読み込みにして、少しでもアクセスから文章のレンダリングまでの時間の方を短縮した方がストレスは少なそうです。

Google Fonts も datauri

俗にいう「FOUT」とはまた違った物かもしれませんが、このちらつきも気になります。

ちらつきフォント

datauri は「エンコードした形式ならインラインで読めるよ」って機能なので画像以外でも使えます。

Google Fonts のCSSファイルを開くとsrc:の部分にフォントファイルのリンクがあるので、それをエンコードして使います。

このサイトで使ってるヤツ: https://fonts.googleapis.com/css?family=Arvo&text=Drest

使用の際は&text=で使う分の英数字を指定してフォントファイルのサイズを削減しましょう。

注意点

Google Fonts はユーザーエージェントによって提供するフォントの形式を変えているため、形式「woff」を提供しているユーザーエージェントでアクセスしてフォントファイルをダウンロードしましょう。(Edgeなど)

Chromeなどのモダンブラウザでアクセスすると「woff2」を読み込むCSSが配信されますが、「woff2」はまだ対応してないブラウザも多いです。

「woff」ならほとんどのブラウザに対応しています。

datauri 化と使用方法

フォントファイルのエンコードには以下のサイトを使いました。
http://dopiaza.org/tools/datauri/index.php

CSSはこんな感じ。

@font-face {
  /*
   * "Arvo" - https://www.google.com/fonts/specimen/Arvo
   * License - SIL Open Font License 1.1
   */
  font-family: 'Arvo';
  font-style: normal;
  font-weight: 400;
  src: local('Arvo'),
       url('data:application/font-woff;base64,~~~') format('woff')
  ;
}

Googleの領分から抜けてしまったのでクレジットもちゃんと書いておきます。

「woff」にすら対応していないブラウザが気になる場合は、対応するフォントのURLを追加してあげましょう。(代替手段なので datauri 化はしなくていいと思う)

たった5文字表示するだけでも例によって禍々しい事になるため、アイコンフォントのようなフォントファイルのサイズが大きい物は素直にリクエストしてもらいましょう。

Javascript でCSSファイルを遅延読み込みした際のちらつきを改善

Google の PageSpeed Insights で指摘される「CSS の配信を最適化する」の欄に書いてある最適化のノウハウに、以下のコードでCSSを遅延読み込みする方法があります。

<script>  
  var cb = function() {
    var l = document.createElement('link'); l.rel = 'stylesheet';
    l.href = 'small.css';
    var h = document.getElementsByTagName('head')[0]; h.parentNode.insertBefore(l, h);
  };
  var raf = requestAnimationFrame || mozRequestAnimationFrame ||
      webkitRequestAnimationFrame || msRequestAnimationFrame;
  if (raf) raf(cb);
  else window.addEventListener('load', cb);
</script>  

</body>の直前にこのコードを入れてやると、ドキュメントの読み込みが終わったあとにスタイルシートを遅延読み込みできてレンダリングブロックしなくなるよねってヤツです。

しかしこのコード、スタイルを遅延読み込みするということで…。

スタイルちらつき

読み込む度にスタイル無しのドキュメントがちらついてホラー映像みたいな感じになる。

対策としては、スタイルの読み込みが終わるまでドキュメントの表示を隠してしまおうという、とっても本末転倒な方法があります。

<style>  
  html{
    visibility: hiddeon;
  }
</style>  

<head>内でvisibility:hiddeon;を指定しておき、

html{  
  visibility: visible;
}

遅延読み込みされるCSSでvisibility:visible;を指定する事によってスタイルが適用されるまでドキュメントを隠しておく事ができます。

恐らく、Google の正攻法(重要な CSS をインライン化)的には最初に見える部分のスタイルは<head>内に全て書いておく事を想定しているのだと思います。

結局このブログでは「点数のために色々犠牲にしすぎ」という結論に至ったため遅延読み込みは使っていません。

改善後のヘッダー

改善ヘッダー

datauri 化していないアイコンはちらついていますが、他の部分は改善され、ちらつきがなくなりました。

Edge では全く改善されずにちらつきました。