ページフリック対策

ページフリックと、アンチフリッカースニペットとか全く知らなかったのでアウトプットする。
###この記事の対象者
・Google OptimizeでA/Bテストをページ丸ごと行っている人
・上記でページフリックが起こり対策を考えてる人

##TL; DR
アンチフリッカースニペットを何も考えずにコピペで対策してたけど、何してるのか理解してコピペしようという話


##1. ページフリックとは
A/Bテスト時のページのちらつきのこと。
テスト対象ページにユーザーが訪れたときに、オリジナルページに対して背景の変更やCSSの変更などのDOM操作が走り、見えている画面に変更が加えられ、一瞬画面がチラッとする現象のこと。


##2. ページフリック対策（アンチフリッカースニペットとは）
アンチフリッカースニペットとはページフリック対策のこと。
以下のソースをheadの上のほうに以下のコードを仕込んで対応できる。

###設置について
以下ドキュメントをご参照ください。
[Optimizeヘルプ『アンチフリッカー スニペットを設置する』について](https://support.google.com/optimize/answer/7100284)

引用
>アンチフリッカー スニペットを設置するには:

>1. 以下のコード全体をコピーして、オプティマイズですべてのページの <HEAD> 内のなるべく前方に追加します。ただし、dataLayer 宣言を使用している場合は、その後に追加します。
2. グローバル サイトタグ（gtag.js）またはタグ マネージャーのコンテナがアンチフリッカー スニペットの直後に設置されるようにします。

>注: OPT_CONTAINER_ID は、オプティマイズ コンテナ ID に置き換えてください。タグ マネージャーをご利用の場合は、次のセクションを参照してください。

以下コードコピペでコンテナID変更すればOK

```html:index.html
<head>
<!--アンチフリッカースニペット開始　※できるだけ上部で読み込む-->
<style>.async-hide { opacity: 0 !important} </style>
<script>(function(a,s,y,n,c,h,i,d,e){s.className+=' '+y;h.start=1*new Date;
h.end=i=function(){s.className=s.className.replace(RegExp(' ?'+y),'')};
(a[n]=a[n]||[]).hide=h;setTimeout(function(){i();h.end=null},c);h.timeout=c;
})(window,document.documentElement,'async-hide','dataLayer',4000,
{'GTM-XXXXXX':true});</script>
<!--アンチフリッカースニペット終了-->
<!-- GTM optimize よりをアンチフリッカースニペットの下に読み込む-->
</head>
```
**※引数で渡している値は、公式ドキュメントより設定値を変更することが可能です。詳しくは『３．どんな処理をしているの？』のサイトを確認ください**

##使ってみて気になった点

###①複数コンテナの読み込み方法
複数コンテナの読み込みをしなければいけない場合は以下の書き方は✖です。

```html:index.html
<head>
<style>.async-hide { opacity: 0 !important} </style>
<script>(function(a,s,y,n,c,h,i,d,e){s.className+=' '+y;h.start=1*new Date;
h.end=i=function(){s.className=s.className.replace(RegExp(' ?'+y),'')};
(a[n]=a[n]||[]).hide=h;setTimeout(function(){i();h.end=null},c);h.timeout=c;
})(window,document.documentElement,'async-hide','dataLayer',4000,
{'GTM-XXXXX':true});</script>

<style>.async-hide { opacity: 0 !important} </style>
<script>(function(a,s,y,n,c,h,i,d,e){s.className+=' '+y;h.start=1*new Date;
h.end=i=function(){s.className=s.className.replace(RegExp(' ?'+y),'')};
(a[n]=a[n]||[]).hide=h;setTimeout(function(){i();h.end=null},c);h.timeout=c;
})(window,document.documentElement,'async-hide','dataLayer',4000,
{'GTM-YYYYY':true});</script>
</head>
<!-- 2回コピペで読み込むみたいなのはダメ-->
```

処理をきちんと理解していればこんな書き方をする人はいないと思いますが、
この記述方法では上から順に実行されるので、コンテナID『GTM-XXXXX』が読み込まれた瞬間にアンチフリッカースニペットの処理が途中で開始します。

複数読み込みたい場合は以下の書き方だと〇

```html:index.html
<script>
~~省略~~
(window,document.documentElement,'async-hide','dataLayer',4000,
{'GTM-XXXXXX':true,'GTM-YYYYYY':true}); ←オブジェクトにキーを追加
</script>
```

###②タイムアウトの変更
4000の値はオプティマイズの読み込みに時間がかかりすぎる場合のhtml要素から.async-hideクラスを削除するまでのデフォルト待機時間（ミリ秒）

```html:index.html
<script>
~~省略~~
(window,document.documentElement,'async-hide','dataLayer',5000,　←時間変更可能
{'GTM-XXXXXX':true}); 
</script>
<!--5000ミリ秒にしてみた-->
```


##3. どんな処理をしているの？

簡単に言うとオプティマイズのコンテナを非同期的に読み込み、その間ページを非表示にする処理をしている。

以下のサイトをご一読ください。
[オプティマイズ『オプティマイズのアンチフリッカー スニペットの使用』について](https://developers.google.com/optimize?hl=ja)



##まとめ
SEO系の施策をするとき
『ブラウザの気持ちになって考えよう』と私の尊敬する上司は言ってくださっていますが
コピペで２回展開するみたいなものは、ブラウザの気持ちになってコーディングしていればきっと
『あれ、この処理２回も実行されているな・・・重くなるな～』とか『ほんとに両方の処理と実行されているのだろうか』とか考えることができるようになると思います。
ぜひブラウザになった気持ちで自分のコードを見直しましょう。コピペでも考えてしようというお話でした。