Service Workerってなんなのよ (Service Workerのえほん)

_私 「ねぇ、Service Workerってあなた何者？」_
_Service Worker 「プログラム可能なネットワークプロキシです」_
_私 「.....(´Α｀lll)o0(ｲﾐﾌ)」_

_(この記事は元々[英語で投稿した記事](http://kosamari.com/notes/Service-Worker-what-are-you)の翻訳版です。挿絵に入っているテキストが英語のままなのはご了承ください🙏)_
## Service Workerってなんかカッコ良さそうだけど、実際問題なんなのかよくわからない

２０１５年７月、私はテキサス州オースティンで開催されたJavaScriptのカンファレンスに参加していた。ステージに立っていたのは[Jake Archibald](https://twitter.com/jaffathecake)、当時はなんかトイレの話ばっかりするおもしろイギリス人くらいにしか思ってなかったけれど、後々Service Workerのスペック策定に関わっているちょっとすごい人だと知る。

(なぜか)公衆トイレで発見したUXパターンについて話す傍ら、JakeはService Workerとかいうウェブサイトをアプリっぽくしてくれる（当時の私の理解では）、新しい技術について熱烈に語っていた。

なんとなく面白そう！プロジェクトで使えたらカッコ良さそう！と思ったものの、最初に取り掛かるまでがちょっと大変だった。Service Workerは新しいHTMLタグでもなければ、JavaScriptの新しいシンタックスでもない...「初めてのService Worker」的な記事を読んでみても、プロキシとかキャッシュとか（普段フロントエンドを担当していて）慣れない単語が出てきて混乱する。しょうがないので記事を読みながら、Service Workerはブラウザ内で呼び出せるエイリアンだ！と絵にしてみたらようやく理解できた。（意味不明？まぁちょっと話を聞いてください。）

## ブラウザ世界におけるエイリアン、Service Worker

![browser planet](https://cloud.githubusercontent.com/assets/4581495/20799983/e27f9aca-b7b1-11e6-9637-af726c3bd85f.png)

ウェブブラウザをコンピューター銀河における一つの惑星（例えば地球）だと例えてみる。このブラウザ星に住む人々はHTML, CSS, JavaScriptといった言語を使って社会を構築している。もし貴方がウェブ系エンジニアなら、この惑星にどんな原子(DOMエレメント)が存在するかとか、ごみの収集日(ガベージコレクション)とかを知っているだろう。

![server galaxy](https://cloud.githubusercontent.com/assets/4581495/20799989/e2880016-b7b1-11e6-9a30-d599eda05260.png)

この惑星はHyper Text Transfer Protocolという、通信手段を持っていて、例えばほかの銀河(サーバー)から資源を調達するのに使われる。このHTTPによってブラウザ星は自身をアニメGifやらツイートやらで埋め尽くすことが出来る。これがブラウザ星の最もユニークな特徴であり、多くの人を引きつける所以である。


![internet pluming pipe](https://cloud.githubusercontent.com/assets/4581495/20799986/e280dcfa-b7b1-11e6-827d-a34367a356fc.png)

HTTPというと魔法のように聞こえるけれど、実際にはインターネットと呼ばれる水道管を通してでないと、ほかの銀河とはHTTP通信できない。
この水道管の太さや長さは、どれくらい配管工(インターネットサービス・プロバイダ)にお金を払ったかとか、あなたの地域にどんなインフラが敷かれているかとかによって異なる。この水道管が細くて長いほど、他の銀河からの資源調達に時間がかかる。


![offline](https://cloud.githubusercontent.com/assets/4581495/20799988/e28499da-b7b1-11e6-87dd-603f4aad0045.png)

困ったことにこのインターネット水道管は常に存在するとは限らない。この水道管を見つけられなかったとき、ブラウザ星は(技術の存在しなかった)大昔をしのんで恐竜を引っ張り出してくる。


## でもちょっとまって！助っ人Service Workerの登場！

Service Worker はブラウザ星とインターネット水道管の間に立ってくれる助っ人のようなもの。Service Workerに通信したい内容を伝えると、サーバー銀河への通信を取り持ってくれる。なんとなくUFOに乗ったエイリアンっぽい感じがする。

![Service Wroker summoned](https://cloud.githubusercontent.com/assets/4581495/20799990/e28950d8-b7b1-11e6-8259-af58e2b348ec.png)

### Service Workerについて知るべき３つの事柄

1. **Service Workerは「呼び出す」もの。**呼び出さない限りあなたのブラウザにService Workerは存在しない。でも一旦呼び出したら、頼んだ仕事が終わるまでは帰ってくれない。Web Workerと違って、`terminate()` といった強制終了メソッドは無い。

2. **Service Workerはウェブサイトの外に住んでいる。**通常ブラウザウィンドウを閉じるとなにも使えなくなってしまう(ビデオダウンロードもできないし、ネット小説を読むことも出来ない)。奇跡のような話だけれど、Service Workerはブラウザウィンドウが閉じた状態でも、必要とされた場合は「起きている」ことができる。ただし、ウェブページ製作者はService Workerがいつ起きているかといったライフサイクルのコントロールはできない。(だからちょっとエイリアンっぽいと私は思っている。)

3. 前述したとおりService Workerはウェブサイトの外に住んでいるので、**ブラウザ星内部に触ることが出来ない。** Service Wroker からは`window`も`document`アクセスできないし、DOMをいじることも出来ない。


## じゃぁService Workerはどんなことが出来るの？

### 1. キャッシュをいじる

Service Workerは`fetch`イベントの仲介人の役割をしてくれる。
Service Workerに特定のファイルをキャッシュするよう頼んだり、キャッシュされたファイルが存在する場合は外部へHTTPリクエストを送る前にキャッシュを返すように頼むことが出来る。キャッシュが存在する限り、インターネットに接続していなくてもブラウザはページを表示出来る。
![cache](https://cloud.githubusercontent.com/assets/4581495/20799984/e27ff98e-b7b1-11e6-9b2a-85ac02836abd.png)

### 2. プッシュ通知送信
「Service Workerはブラウザウィンドウが閉じていても起きている」のでプッシュ通知送信といったことが出来るようになる。
![push notification](https://cloud.githubusercontent.com/assets/4581495/20799987/e28169c2-b7b1-11e6-9046-bba5d576d2c6.png)

### 3. バックグランド同期
「ブラウザウィンドウが閉じていても起きている」ということはつまり、ユーザーが見ていないところで働いてくれたりもする。
例えばユーザーがブラウザオフライン状態のときに、ファイルアップロードを行ったとしよう。Service Workerはデバイスがオンラインになった時点で、バックグラウンドで（ユーザーが気づかないうちに）ファイルアップロードをしてくれる。
![background sync](https://cloud.githubusercontent.com/assets/4581495/20799985/e2802d14-b7b1-11e6-944b-2054dcaf6885.png)


---
Service Workerってちょっとワケがわからないと思っていた人が、この記事を読んでちょっとでも解った！と思ってくれたらうれしいです。さっそくコードを書いてみたくなったなら、Jake Archibaldの[offline-cookbook](https://jakearchibald.com/2014/offline-cookbook/)をオススメします。

_この記事は　クリエイティブコモンズBY-NC-SA 4.0 ライセンスで公開しています。_