Chrome周りで2019年に変化したことまとめ

2019年もあと残りわずか。
年末は振り返りをする良い機会ですよね。
そんなわけで今年の Chrome の進化の話や、Chrome 周りの出来事をまとめていきたいと思います。

自分の主観でインパクトが大きかったものから順番に上げていきます。:smiley:

※ 本記事は [STORES.jp Advent Calendar 2019 - Adventar](https://adventar.org/calendars/4549) の10日目の記事です。


## Native lazy loading
https://developers.google.com/web/updates/2019/09/nic77#lazy-loading

ページ表示速度改善でよく使われる手法の画像の lazy load（遅延読み込み）。
lazy load は今まで lazy load 用の JavaScript のライブラリを読み込んで実装するのが一般的でしたが、Chrome 76からの機能でブラウザの機能として lazy load を実行できるようになった、というものです。

lazy load をさせたい要素に対して、`loading="lazy"` をつけるだけ。
めちゃ簡単です。

```html
<img src="image.jpg" loading="lazy" width="400" height="250" alt="...">
```

サンプルページ
https://awsyk.s3-ap-northeast-1.amazonaws.com/lazyload.html
<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="html,result" data-user="ykyk1218" data-slug-hash="WNbvWQN" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="chrome lazy load sample">
  <span>See the Pen <a href="https://codepen.io/ykyk1218/pen/WNbvWQN">
  chrome lazy load sample</a> by ykyk1218 (<a href="https://codepen.io/ykyk1218">@ykyk1218</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


とっても便利な機能ですが、Chrome 以外が対応してくれないと結局あまり意味なかったりするので他のブラウザはどうするのか気になります。

 ちなみに `loading=lazy` を使わずに lazy load を実現する場合は `Intersection Observer API` を使って実装する方が、Google がコンテンツを認識しやすいようです。

> Googlebot がページ内のすべてのコンテンツを確実に認識できるようにするために、遅延読み込みを正しく実装して、すべての関連コンテンツがビューポートに表示できるときに読み込まれるようにしてください。たとえば、次のような方法があります。
・IntersectionObserver API とポリフィルを使用する
・ビューポートに表示されるデータのみを読み込む JavaScript ライブラリを使用する

https://developers.google.com/search/docs/guides/lazy-loading

## Googlebotのレンダリングエンジンが最新のChrome相当になった
https://webmasters.googleblog.com/2019/05/the-new-evergreen-googlebot.html

Google のクローラである Googlebot と言えば今までは、Chrome の古いバージョン（ Chrome 41など）のレンダリングエンジンでした。
そのため最新の JavaScript の記法がクローラーで読み込めなかったり、LazyLoad に対応仕切れなかったりなどしていたため、JavaScript で描画するコンテンツは SEO に弱いとされていました。

2019年の5月ぐらいに Google が Googlebot を最新の Chrome と同等のレンダリングエンジンを使用することを発表をしました。新しい記法の JavaScript もちゃんと解析できるようになりましたし、これによって `IntersectionObserver` に対応したことで遅延読み込みするコンテンツも Googlebot はちゃんと読み込んでくれるようになります。



## ダークモード対応
https://developers.google.com/web/updates/2019/07/nic76#dark-mode

chrome 76からダークモード対応したスタイルをかけるようになりました。
Mac の設定がダークモードの時にダークモードに対してスタイルを適用することができます。

`prefers-color-scheme: dark` でダークモードの時のスタイル当てることができます。

```css
@media (prefers-color-scheme: dark) {
  body {
    background-color: black;
    color: white;
  }
}
```

https://codepen.io/ykyk1218/pen/qBEWLPe


<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="html,result" data-user="ykyk1218" data-slug-hash="qBEWLPe" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="qBEWLPe">
  <span>See the Pen <a href="https://codepen.io/ykyk1218/pen/qBEWLPe">
  qBEWLPe</a> by ykyk1218 (<a href="https://codepen.io/ykyk1218">@ykyk1218</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


## Largest Contentful Paint（LCP）
https://developers.google.com/web/updates/2019/09/nic77

ページ内で一番大きいコンテンツが表示されるタイミングの計測ができるようになりました。
Chrome の検証ツールの Performance からみれます。
LCP と書いてあるところが対象です。
この例だと記事のアイキャッチがLCPになっているので、ちゃんと計測できていますね。 :grinning:


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6808/d8ee9106-44c1-7a65-4189-a2f9efeda73d.png)

JavaScript によって非同期でコンテンツを表示させるようなものが出てきて、load や DOMContentLoad の時間がユーザーの感じる時間とかけ離れてきていて意味のない指標になってきているため、First Content Pait（FCP）やFirst Meaningful Paint（FMP）といった指標が出てきました。
今回のLCPは一番大きな要素、ということで、よりユーザーにとってページが表示された！と感じる速度に近くなったんじゃないかなあって思います。

### 計測方法
FCPやFMP同様、 `PerformanceObserver` を使って計測をすることができます。

**サンプルページ**
URL: https://awsyk.s3-ap-northeast-1.amazonaws.com/lcp.html

こんな感じのページ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6808/d26c9a08-77c0-ee99-924d-b78a038a0b08.png)


**ソースコード**
（下記のページのサンプルを参考に作ってます）
https://web.dev/lcp/#how-to-measure-lcp

```html

<!DOCTYPE html>
<html>
  <head>
  <meta name="robots" content="noindex,nofollow" />
  <meta charset="UTF-8">
  <title>This is Template</title>
  <style type="text/css">
    img {
      margin-bottom: 50px;
      width: 800px;
    }
  </style>
  <script>
    let lcp;
    const po = new PerformanceObserver((eList) => {
      const e = eList.getEntries();
      const last = e[e.length - 1];
      lcp = last.renderTime || last.loadTime;
    });

    const poOpts = {
      type: 'largest-contentful-paint',
      buffered: true
    }
    po.observe(poOpts);

    addEventListener('visibilitychange', function fn() {
      const visState = document.visibilityState;
      if (lcp && visState === 'hidden') {
        console.log('LCP:', lcp);
        removeEventListener('visibilitychange', fn, true);
      }
    }, true);
  </script>
</head>

<body>
<p>Hello World!</p>

<div>
<img src="/sample-image/DSC_0003.jpg" alt="sample">
<div>
  サンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキスト<br>
  サンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキスト<br>
  サンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキスト<br>
  サンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキスト<br>
  サンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキスト<br>
  サンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキスト<br>
  サンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキスト<br>
  サンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキスト<br>
  サンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキスト<br>
  サンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキスト<br>
  サンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキスト<br>
  サンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキスト<br>
  サンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキスト<br>
  サンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキスト<br>
</div>

</div>
</body>
</html>
```

<img width="436" alt="DevTools_-_awsyk_s3-ap-northeast-1_amazonaws_com_lcp_html.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6808/e32a49e0-f796-0e85-5cff-bf5becbdf3d3.png">

こんな感じで値が取れました。
Chrome内で計測しているパフォーマンスと、JavaScriptで表示時間に若干の差があります。

## Web Share API

AndroidやiPhoneのデフォルトのシェア画面をJavaScriptから呼び出すことができます。
Twitterのツイートボタンとか置くよりもこっちの方が良かったりするかな？

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">web share api sample <a href="https://t.co/R8EDiUoiuQ">pic.twitter.com/R8EDiUoiuQ</a></p>&mdash; ykyk1218@MENTAのメンター (@ykyk1218) <a href="https://twitter.com/ykyk1218/status/1202252810458292224?ref_src=twsrc%5Etfw">December 4, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Web Share APIはちょっと前からあって、今回の変更は画像や動画ファイルが共有できるようになる、というのが大きな変更点です。
iPhoneでもWeb Share APIは動作するのですが、今回の変更の画像や動画を共有できるようになる、というのがどうもまだうまく動かないようです...

（Android端末がないため画像の共有の動作は未検証）
<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="html,result" data-user="ykyk1218" data-slug-hash="oNgvQmm" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="web share api sample">
  <span>See the Pen <a href="https://codepen.io/ykyk1218/pen/oNgvQmm">
  web share api sample</a> by ykyk1218 (<a href="https://codepen.io/ykyk1218">@ykyk1218</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


# ちょっとマニアックな変更

## Chrome Dev Toolを使って詳細なスタイルがわかるようになりました
Chrome Dev Tool にある InspectMode でスタイルの詳細な情報が見れるようになりました。

Inspectモードはこれのことです
<img width="146" alt="prefers-color-scheme_-_CSS__カスケーディングスタイルシート___MDN.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6808/647574fa-975c-0c2c-8fb9-75c44cee3da5.png">

こんな感じで表示されます。
便利ですね :relaxed: 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6808/330e8410-88d4-4483-312b-feeb3f1d931e.png)

## PWA Omnibox Install Button
https://developers.google.com/web/updates/2019/07/nic76#pwa-install

PWAのアプリケーションをインストール
https://ykyk1218.github.io/

アドレスバーの右の方にひっそりある +ボタンをクリックするとインストールダイアログが表示されるようになってます。
web app manifestを用意して正しく読み込めるようになっていれば、表示されるようになるはず
（iPhone版のChromeには表示されませんでした、残念）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6808/6e50769f-9258-7ba3-3065-1471ff8509a5.png)

Web界隈にどっぷり浸かっている人はともかく、果たしてこれに気づいている一般ユーザーの人はいるのだろうか...

## More control over the PWA mini-infobar
PWA対応をしたサイトにアクセスすると表示されるインストール用のバナーみたいなもの
Android版 Chromeにのみ表示されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6808/9034fc90-ec7f-6e51-9d9c-e7036f5bbd08.png)
https://developers.google.com/web/updates/2019/05/mini-infobar-update

以前にも似たようなものがあったのですが、もう少しコンパクトにになりました。



## The formdata event
https://developers.google.com/web/updates/2019/09/nic77#the_formdata_event

フォーム送信するときの formdata イベントが追加されました。

```js

const form = document.querySelector('form');
form.addEventListener('formdata', ({formData}) => {
  formData.append('my-input', myInputValue);
});
```

formData オブジェクトが渡せるので、form で何かしら post したい値を追加したい場合はここでカスタマイズすることができます。
submit イベントの後に formdata イベントが実行されるようになっています。

<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="js,result" data-user="ykyk1218" data-slug-hash="eYmmyEV" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="formdata event sample">
  <span>See the Pen <a href="https://codepen.io/ykyk1218/pen/eYmmyEV">
  formdata event sample</a> by ykyk1218 (<a href="https://codepen.io/ykyk1218">@ykyk1218</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


これは form の中にカスタムエレメントとして入力フィールドを用意しても、 form の submit にするときに値が入ってきてくれなかったりするので、そういう場合に formData に append する時に役立ったりします。

参考
[Web Components : フォームパーツの作り方・ハマりどころ](https://tech.basicinc.jp/articles/165)

> Shadow DOM を通常の form に入れても作用しない
> この `<my-input-text>` に入力したものは無情にもどこにも POST されません。これは `<form>` と `<input>` の所属する Node Tree が違うから起こる現象です。






# 未来のChromeのお話
ここからはまだリリースされていないけど、今後こういうことをするよっていうのが発表されているChromeの未来の話を少ししたいと思います。

## same-site cookie 
直近の一番ホットな話題はこれでしょう。
Chrome 80からクロスドメインの時にCookieの挙動を変更するようになります。

以下の記事が詳しく説明をしています。
https://web.dev/samesite-cookies-explained/

### 今まで
アクセスしたページからのリクエストにCookieがデフォルトで付与される。

### これから
アクセスしたページと違うドメイン（クロスドメイン）へはデフォルトでCookieを送信しない

- SameSite=Strict : クロスドメインの時は送信しない
- SameSite=Lax : POSTリクエストやXHR、iframe、imgのリクエストを別ドメインに送信する時はCookieを送信しない
- SameSite=None : 別ドメインでもCookieを送信する

Chromeはデフォルトで `SameSite=Lax` になります。
https://web.dev/samesite-cookies-explained/#changes-to-the-default-behavior-without-samesite


### 使い方
`chrome://flags/` にアクセスをして `SameSite by default cookies` を有効にすれば使えるようになります。

例: ブラウザでYoutubuにログインしている状態でもiframeでYoutubeを読み込んでもログイン状態にならない
<img width="752" alt="A_Pen_by_ykyk1218.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6808/209081ae-8b92-e960-f1fb-3b378cb5dcfd.png">


## Chromium版 「Microsoft Edge」 の誕生
https://www.itmedia.co.jp/news/articles/1911/05/news051.html

直接Chromeの話題ではないのですが、Microsoft EdgeがブラウザのベースにChromiumを使うという話がありました。

Microsoftと言えばIEで、IEからEdgeに代わりようやく他のブラウザと挙動がそれってきて、さらにChromiumベースになることでより差分がなくなってきたのではないでしょうか？IE対応でCSSハックをしたり、IEだけJavaScriptエラーになるなど、IEに苦しめられてきた世代としては大きな出来事でした。


## portalsタグ
新しいタグが出てきました。こういう話はワクワクしますね :smiley:

`portal` は `a` や `iframe` タグの代替（もしくは上位互換）になります。
`portal` タグを使うことで、事前に遷移先の要素を取得できるためシームレスな画面遷移ができるようになります。

https://web.dev/hands-on-portals/

実際の使い所は...記事の一覧から記事の詳細ページに遷移させる時に `portal` を使うといいのかもしれません。
ただ今の仕様だと `portal` で指定したコンテンツは全て事前にリクエストをして取得するようになるので（ServiceWokerを使ってキャッシュを生成するような動きに近い感じ）全部を `portal` にするのは現実的ではありません。
新着だけ、とかアクセスが多そうなところに限定するといいかもしれませんね。

### 使い方
`chrome://flags/` にアクセスをして `Enable Portals` を有効にすれば使えるようになります。

https://awsyk.s3-ap-northeast-1.amazonaws.com/portals/portal.html


# 感想
Google が Web サイトを閲覧する上でのユーザー体験を非常に重視しているなあというのがわかるような変更が多い印象でした。
特に JavaScript 周りの改善で、そこの意識をすることが多かったです。

LCP という新しい計測方法もユーザーが快適に Web を閲覧するための指標となりますし、Googlebot を最新相当の Chrome にすることで、よりユーザーと近い見た目をクローラーもできるようになってきています。

PWA 周りも色々ありましたが、まだいまいち浸透していない感じありますね...
Web サイト運営者視点で見ても PWA 対応することのメリットがまだ弱いと思いますし、ServiceWorker いれてゴリゴリやるとなると工数のわりに効果は？っていう感じがあるからでしょうか。
ユーザー視点で見ても PWA というのを知らないでしょうから、インストールさせるダイアログが出てもなんのこっちゃという感じでしょう。プッシュ通知もうざがられてきています。

個人的にはPWAはWebのあり方を変える面白い仕組みだとは思うので、もっと流行って欲しいなあという気持ちがあります。とは言え流行るにはMac側の対応状況も大きく影響があることでしょう。

来年はどんな変化をしていくのでしょうか。楽しみですね！！

---

STORES.jp Advent Calendarの他の記事も是非のぞいてみてください :santa:
https://adventar.org/calendars/4549