2024.10.10
将来は卵1パックの価格が2倍に? 多くの日本人が知らない世界の新潮流、「動物福祉」とは
ServiceWorker Side XXX(全1記事)
リンクをコピー
記事をブックマーク
mizchi氏(以下、mizchi):では「ServiceWorker Side XXX」ということで発表させていただきます。mizchiです。よろしくお願いします。
(会場拍手)
ちょっと自己紹介とかはする気ないんですけど、最近本を書いたので、その紹介だけさせてください。
『WEB+DB PRESS Vol.106』。最近、仮想DOM芸人みたいになってるんですけど、書いたのでよろしくお願いします。
最近趣味でnedi.appというエディタを作っていて。これはブラウザで独立して動くエディタで、Gitが動くんですけど、全部IndexedDBで動いています。
いろいろブラウザで完結してGitクローンからプッシュまでいけるというもので、Patreonでちょっとお金を集めたら月2万円ぐらいになってます。
これを作っててちょっといろいろ発展があって。開発環境のためにServiceWorkerをいろいろ酷使して、いろいろできそうだけど、いろいろできなかったという話をします。
ServiceWorkerって、今はこういうステータスなんです。
Opera Miniのことはみなさんたぶんどうでもいいと思っているので、一番左のIE11ですよね。これさえ無視すればもう動きます。ほぼ動きます。
実際使ったことある人?
(会場挙手)
仕事で使ったことある人?
(会場挙手)
まぁ、意外といる感じですね。
ServiceWorkerとはなにかというと、ただのすごいローカルプロキシなんですよね。
クライアントがなぜかクライアント内でクライアントサーバモデルを取れるという。これは一番上が呼び出す例で、下がfetchを掴んでなにかログを吐くってだけの例です。
ServiceWorkerは開発者向けにはもう使ってOKだと思っています。
ただ、一般向けには2020年ぐらいにWindows 7が終わると、Windows 8……まぁWindows 10はEdgeを積んでいるので一応使えると言えるようになるので、ビジネス向けにはWindows 8も見ないといけないから2023年ぐらいなんですけど、今から作り始めるアプリはどうせリリースが2020に近い時期なので、もうやっていいと思います。
ServiceWorkerにはいろいろな使い方はあるんですけど、2つ、僕が勝手に名前をつけたんですが、透過的なServiceWorkerと積極的なServiceWorkerの2つがあると思っています。
一番上のやつがよくPWAとかで使われるやつですよね。既存の振る舞いを拡張する。だから、キャッシュ構築したり、投機的先読みしたり、消極的にオフライン化するという感じです。
例えば、これは『dev.to』の記事引っ張ってきたんですが、マウスを乗せるだけでfrom ServiceWorkerとなって、裏側で引っ張ってきている。
投機的にキャッシュをためています。いろいろ先読みしたりして、裏側にキャッシュためておくみたいな。
あと、Google製のWorkboxというプラグインがあって、これがすごく便利です。
一応webpackのworkbox-webpack-plugin突っ込むだけでそれっぽくキャッシュレイヤーが挟まってくるので、すごく便利ですね。
これにWorkbox Strategyという概念があります。
Workboxではどういうキャッシュパターンがあるか、いろいろキャッシュパターンを選べるんですね。
1つがCacheFirstといって、とりあえずキャッシュ見にいってダメだったらネットワークから返すよとか。
これはおもしろいですね。StaleWhileRevalidate。
とりあえずいったんキャッシュを返しておくんだけど、裏側でネットワークのデータを返して裏でアップデートしておく。次見たら更新するというやつです。
表向き透過なだけでもいろんなキャッシュパターンがあって。全部トレードオフがあって、わからないと嵌まるので気をつけてください。
さっきも言ったように、今すぐ使えます。レガシー環境では振る舞いが透過なので単に無視される。使えるブラウザではすごい賢くなる。プログレッシブなんですね。Progressive Web AppsのProgressive。
ただ、これにはちょっと弱点があると僕は思っています。ServiceWorkerって、その他リソースは並列で初期化されます。sw.jsというよくServiceWorkerで名前つけられるやつと、なにかほかのアセットは実は並列で読み込まれるので、どこからキャッシュされるか実は自明じゃないんです。
ちょっと簡単な図を作りました。
sw.jsがreadyになるタイミングとfoo.jsとbar.jsを読んだ段階で、foo.jsがServiceWorker Readyになる前にキャッシュが返ってしまうと、これServiceWorker通らずに返ってきてしまいます。
ServiceWorker、たぶん普通に使うと全部こうなります。だから、ServiceWorker使う人はだいたい3回リロードするんですけど。1回目でServiceWorker変えて、2回目でキャッシュ捨てて有効化して、3回目で保証された状態で見るみたいな、すごいだるい感じになります。
これは対策のしようはあります。例えば、コメントアウトされているのが本来のscript src="./main.js"だったら、開発環境だけではこのように書き換えてしまう。
navigator.serviceWorkerをregisterして、readyして、終わったらimportする。dynamic importですね。開発環境だけこうすればいいので、本番ではdeleteして上のやつを読むイメージです。
ほかにも、ServiceWorkerが更新するのも問題になるので、裏側でsetIntervalで、これはregistrationというオブジェクトが入るんですけど、registrationを毎秒更新する。
更新があったら、このcontrollerchangeが来るので、windowをreloadして無理やり入れ替える、みたいなことができなくはないです。
ただ、現実としてベストプラクティスとかはとくになくて。これらは僕が勝手にやっているだけで、ちょっと時代が早いという感じですね。よく壊れます。ポートが壊れたり、serviceWorker.readyが来なくなったりします。だから、chrome://serviceworker-internalsという開発者ツールで chromeの内部状態、内部のオブジェクトを無理やり見て破壊したりします。
ここまでが透過的なんですけど、積極的PWAという概念があると思っていて。「それってServiceWorkerじゃないとそもそも動かない機能も、たくさん使ったらなんでもできるじゃん。だってただのクライアントサーバモデルのローカルプロキシでしょ?」ということですね。
この弱点はすごく明確で、モダンブラウザでしか動かないということと、ServiceWorkerが初期化されていないとなにもかも見れないので、SEOは完全に壊滅します。
ただ、使い道はあると思っていて。例えばサーバサイドで、今回webpack疲れというのが話あったじゃないですか。webpackをインストールせずにBabelとかTypeScriptをサーバサイドでコンパイルしたりとか、Express serverをそのままServiceWorkerに放り込んじゃってそこで動かすとか、できると思います。
例えばServiceWorkerインストール後に、これは全部壊れるのでやっちゃいけないコードなんですけど、fetchですべてのオブジェクトが「event.respondWith(new Response("console.log('hello world')"))」ってやると、index.htmlですらこれになるので、2回目のリロードから壊れるのですが、まぁHello Worldにできます。
あと、これはBabelでawait fetchでevent.requestを、とりあえずサーバサイドに取りにいってオリジナルソースを取ってきて、それをbabel.transformで変換して返すということができますね。
「だったらServiceWorkerでWebpackのエミュレーションすればいいんじゃないかな?」ってちょっと思って。なんでかというと、WebpackってES Modulesのエミュレータ+αなんだけど、でも、プラスαのところがいま重点にされてしまっています。
例えば、JSXとか絶対に将来にわたってサポートされない……まぁほぼサポートされないはずなので、なんだかんだでそれに近い機能が必要と考えると、将来的にも捨てられない可能性が高いんだったら、ServiceWorkerでWebpackをエミュレートすればいいんじゃないか? やってみました。こういうモジュールを作ったので……ええと、見ておいてください。
(会場笑)
先にデモしますが、これが動いているやつです。
ネットワークがどうなっているかというとjspm.ioというCDNがあって、そこからすべてReactのソースをその場で全部構築して。これReact Reduxが動いています。Babelの変換もこの場でやっています。
例えばこういうコードが動いています。
これはなにかというと、import React 、ReactDOM、App "./components/App"、ReactDOM.render。
これはWeb標準では動かないんですけど、これを無理やり動くようにするためには、まずはBabelでコンパイルしてnpmのモジュールをCDNの、このモジュールパスを書き換えたCDNに指し直す。拡張子がさらにApp.jsみたいに省略されてるのを復元します。これ「.js」「 .ts」「/index」とか全部探索して取れたやつを返してるんですけど。あとは、外部モジュールの相対パスの解決をしたり。
ES Modulesのimportを通る際はServiceWorker.onfetchという機構を通って変換されるので、それを変換できるというやつです。外部ライブラリのコードはバージョンごとに変わらないはずなので、それをServiceWorkerでキャッシュしてしまえばいいと。
やってみました。そして、動いた。React Reduxまで動いたんですけど、実際にはいろいろ問題はあって。
これはnpmモジュールのCommonJSからES Modulesに無理やり変換してる。通常の逆をしないといけないんですね。
webpackで、npmのモジュールはCommonJSなんですけど、CommonJSをES Modulesに再変換しないといけないという処理をやっているんですが、やっぱり手がかりが少なくて、しかも可逆じゃないので、やってみたけどできなかった。
じゃあES Modulesのソースを直接参照できればいいじゃんと思ったんだけど、そもそもES Modulesのソースをそのまま公開してくれているライブラリなんて少数で、あんまりダメ。できそうにない。あと、そもそも今回使ったCDN、jspm.ioというCDNが頻繁に落ちているという。Jspm.ioはnpmのモジュールをESMに変換してくれているというやつですね。
上のコードは動くんですけど、下のコードが動かなくて。
module.exportsをESMのexport defaultとして返してくれるんですけど、それ以外のエクスポートされたオブジェクトは取れないということになっちゃいました。
なので、可逆なコンパイラを自分で書くしかないなと思ってるんですけど。本当に使いたければ。
みんながrollupを使えばES Modulesも提供することになるので動くんじゃないですかね。
あと、ほかにもいろいろできると思っていて。例えばExpressのServiceWorker。
これはモックサーバで使えると思っていて、一部のルーティング、まぁ、モックを作るのにほしいのはルーティング処理で。APIエンドポイントだけモックして、なにかJSON、適当なオブジェクトをモックサーバで返すとか。
あと、そもそもサーバでServiceWorker動かすみたいな。
これはなんとなぜかCloudflareが実装しているんですね。Cloudflare Workersといって、CDNでServiceWorkerを実装して、それを返す。
これは公式のコードで、ServiceWorkerのあのfetchでrespondWith(fetchAndApply)みたいな感じ。
これはなんでServiceWorkerなんだろうって、いまいちよくわからないです。
あとはServiceWorkerでServer Side Renderingする。
もうサーバなのかなんだかよくわからないですけど。
(会場笑)
まぁ、できます。ServiceWorkerでindex.htmlを構築して返す……これSEOにはなんの役にも立たないんですけど、First Meaningful Paintを最適化したければ、サーバサイドの中でReactDOM.renderToStringして、initialStateもembedして実行しちゃえば動きます。
ある程度いろいろ考えてみたんですけど、いろいろ変えたら開発ツールには使える。現状はまだ早いので、みなさんがんばってこれ開拓してください。僕はちょっと疲れました。
(会場笑)
あとはある種の開発者ツール。クライアントでBabelを動かす必要があるような開発者ツールとか、そういうときにServiceWorker Side Babelみたいものが便利かなという気がします。
まとめは、IEが死んだあとに動的ローダーとして使えるので。本当はIEのためにこれを利用したいのですが、IEじゃ動かないんですね。なので、デッドロックしてるんですけど、まぁIEは死ぬんで忘れましょう。
今のうちに経験値貯めておけば使えるように、2020年ぐらいにちょっと使えると思います。以上、お疲れ様でした。
(会場拍手)
関連タグ:
2024.11.13
週3日働いて年収2,000万稼ぐ元印刷屋のおじさん 好きなことだけして楽に稼ぐ3つのパターン
2024.11.11
自分の「本質的な才能」が見つかる一番簡単な質問 他者から「すごい」と思われても意外と気づかないのが才能
2024.11.13
“退職者が出た時の会社の対応”を従業員は見ている 離職防止策の前に見つめ直したい、部下との向き合い方
2024.11.12
自分の人生にプラスに働く「イライラ」は才能 自分の強みや才能につながる“良いイライラ”を見分けるポイント
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.11.11
気づいたら借金、倒産して身ぐるみを剥がされる経営者 起業に「立派な動機」を求められる恐ろしさ
2024.11.11
「退職代行」を使われた管理職の本音と葛藤 メディアで話題、利用者が右肩上がり…企業が置かれている現状とは
2024.11.18
20名の会社でGoogleの採用を真似するのはもったいない 人手不足の時代における「脱能力主義」のヒント
2024.11.12
先週まで元気だったのに、突然辞める「びっくり退職」 退職代行サービスの影響も?上司と部下の“すれ違い”が起きる原因
2024.11.14
よってたかってハイリスクのビジネスモデルに仕立て上げるステークホルダー 「社会的理由」が求められる時代の起業戦略
2024.11.13
週3日働いて年収2,000万稼ぐ元印刷屋のおじさん 好きなことだけして楽に稼ぐ3つのパターン
2024.11.11
自分の「本質的な才能」が見つかる一番簡単な質問 他者から「すごい」と思われても意外と気づかないのが才能
2024.11.13
“退職者が出た時の会社の対応”を従業員は見ている 離職防止策の前に見つめ直したい、部下との向き合い方
2024.11.12
自分の人生にプラスに働く「イライラ」は才能 自分の強みや才能につながる“良いイライラ”を見分けるポイント
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.11.11
気づいたら借金、倒産して身ぐるみを剥がされる経営者 起業に「立派な動機」を求められる恐ろしさ
2024.11.11
「退職代行」を使われた管理職の本音と葛藤 メディアで話題、利用者が右肩上がり…企業が置かれている現状とは
2024.11.18
20名の会社でGoogleの採用を真似するのはもったいない 人手不足の時代における「脱能力主義」のヒント
2024.11.12
先週まで元気だったのに、突然辞める「びっくり退職」 退職代行サービスの影響も?上司と部下の“すれ違い”が起きる原因
2024.11.14
よってたかってハイリスクのビジネスモデルに仕立て上げるステークホルダー 「社会的理由」が求められる時代の起業戦略