ブラウザにおけるバックグラウンド動作の歴史

Tumblr で以下のような記事を見つけた。2008年当時のウェブ技術、および Chromium ブラウザにおけるバックグラウンド動作の開発状況が分かる。

自分はフロントエンド開発が好きで、Cordova でハイブリッドアプリを作ったこともあったが、PWA や Service Worker といった技術はあまり得意な分野ではない。そのため理解が浅い部分も多いと思うのだが、この記事を見てこうした技術開発が10年以上続いていたんだなぁと再認識したので、自分なりにその歴史を振り返ってみようと思う。

Web周辺のクライアントサイド技術を使っている人は多いと思いますが、サーバーサイドプログラムのおまけとして、またデザインやエクスペリエンスの一部として付属的にしか扱われないことが多いようです。

近年、AJAXキーワードとともにWeb周辺のクライアントサイド技術は盛り上がってきましたが、複雑なものを作ろうとしたときに以前と同じような扱い方では限界があります。特に、AJAXを使って動作が複雑になったり、JavaScriptやCSSが複雑に絡み合って、デバッグに苦労する機会が増えてきました。

一方で、最近のWeb周辺のクライアントサイド技術の進歩により、苦労せずに欲しい機能を取り入れることが出来るようになってきています。知っていればちょっと加えるだけで劇的な効果や生産性の向上が得られるのですが、知らなければ同じことをするために倍以上の時間と労力がかかることがたくさんあります。ポイントは情報へのアクセスの仕方をちょっと変えるだけです。

ところが入手できる情報は多いのですが、今度はいろいろな書き方や「答え」がありすぎるために、どれが一体正しいのか悩んでしまうようになります。実現したいことと「答え」が結びついているため、なぜそういう「答え」なのか、また複数の「答え」からどれを選択するべきか、そのような判断する情報やノウハウは簡単には手に入りません。一応動いてはいるものの、本当にそれで正しいのか、一人で考えていても不安に思うことが多いです。

その先に進むためには、クライアント技術であるJavaScript/HTML/CSSの能力についてもう一度見直して、正しく理解し、考えながら使うということを繰り返して経験をつむ必要があるようです。つまり、クライアント技術を単なる付属品ではなく、サーバーサイドのプログラムと同レベル、もしくはそれ以上の主役として扱うべく、本格的に勉強する必要がありそうだということです。

ちょうど1週間くらい前にchromeのベースになっているchromiumの開発者グループChromium-devにDesign doc: Background Browser Taskというのがポストされました。

ウェブアプリケーションでブラウザの中でメールを見たりカレンダーに予定を入れたりできるようになったけれど、ウェブアプリケーションの命はユーザがブラウザを終了したらそこでおしまい。サーバからユーザに登録してもらったメールアドレスにメールを送るくらいしかユーザに何かを伝える方法がなくなります。時間のかかる処理、たとえばカレンダーに入っている予定の時間まで待つ、オフラインになる前にサーバとローカルのデータを同期しておく、写真を500枚アップロードする、そういった処理をしている途中に、ユーザがなんとなくウインドウを閉じたら、予定の時間にアラートが出ない、データがちゃんと同期されてない、写真が5枚だけしかアップロードされてなかった、みたいなことになります。

そこで彼らが考えたのがだったらブラウザ閉じても裏でブラウザ動かしとけばいいんじゃないの、という解決策。HTMLに

<bb type="makebgtask" name="event sync" href="http://ido.nu/kuma/eventsync" />

と書いておくと、バックグラウンドで動かすことのできるタスクとして認識されて、ユーザがOKを出してくれたらページがロードされてきて、ブラウザが閉じられても裏でずっと動きますよ、というアホみたいに単純だけど効果絶大なしくみです。さらにPCを起動したときに一緒に起動するようにもしていいですよ、と書いてあります。詳しくはBackground Browser Taskを。個人的には、普通のブラウザウインドウを単に非表示にすれば実装できるよ、と書いてあるところにうけました。

よく考えれば機能的にはWindows VistaのGadget, OSXのDashboardみたいなもんですが、前者がデスクトップアプリケーションをスクリプト言語で作ろうという発想のKonfabulator(いまのYahoo! Widgets)から来ているのに対して、chromiumのbackground taskはおそらくGearsの発想、デスクトップアプリケーションにしかできなかったことをウェブアプリケーションでできるようにする、という発想からきています。そういうのはおいといて、とにかくbackground taskによって、Windowsの常駐アプリとまったく同じようにコンピュータ上で常にjavascriptのアプリケーションを動かすことができるようになります。

コンピュータ上でブラウザが開いているとか開いていないとかを気にせずjavascriptのアプリケーションを動かせるとなれば、それをウェブアプリケーションのおまけとして使う以上のこともできるようになります。

これまでC/C++で書かれていたプログラムが、javascriptで書かれているようになるだけで、ブラウザの持っている制約と同じ制約の範囲の中でならなんでもできるので、ユーザの有り余ってそうなコンピューティングリソースを使ってブログの検索インデックスをクライアントのマシンに作らせたり(サーバ側では検索機能を用意しないでクライアント側に検索させていもいいでしょう)、サーバ側で多数のクライアントマシンを束ねて地球外知的生命体探査をさせるとか、まじめなところではウェブベースのメッセンジャーとか(いつも気がつかない間に閉じていてオフラインになったりしています)、そういうのも作れるようになります。

<bb> なる HTML 要素でバックグラウンドタスクを定義する、という例が書かれている。当時の Chromium-Dev の Design Doc にこの HTML 案が書かれていたのかは不明。このコードで検索してもこの上述の記事しかヒットしないので、このブログの筆者が例としてこしらえたモノなのかもしれない。よく分からない。

コレは2008年11月の記事だが、Chrome (Chromium) の初登場は2008年9月2日で、Google がブラウザ開発を始めた最初期の情報であることが分かる。

ブラウザはウィンドウを閉じてしまうと処理が中止されてしまうのが通常だが、Ajax 技術の発展などにより、ブラウザをネイティブアプリと同様に使いたいという流れは利用者・開発者ともに出てきた頃、というワケだ。2004年から提供されている Gmail が早くからリッチな Web UI を提供しており、Gmail に限っては「Outlook」や「PostPet」や「BlackBerry」や「Thunderbird」といったメーラーソフトを使わなくても十分な UI があったりした。そうなると「メーラを常時起動しておく」のではなく、「Gmail を閲覧する Chrome ブラウザにバックグラウンド常駐してもらいデスクトップ通知を出してほしい」と思うのも自然な流れだ。

それまでも、ブラウザ上でリッチなコンテンツを提供する技術として、Java Applet、CGI、PHP、Macromeia Flash などがあったが、いずれも「そのページを開いた時にインタラクティブな UI を提供する」に留まり、「ネイティブアプリと同等の体験」は得られないモノであった。


Chromium ブラウザが初登場したのと同時期の2008年7月には iPhone 3G が発売され、2008年10月頃からは Android が搭載された携帯電話が登場し始める。ADSL を経て光回線が一般にも浸透してきたこの時代、「スマートフォン」はそれまでの「ガラケー」や「PDA」では体験できなかったリッチな UI が提供され、内蔵ブラウザの処理能力も格段に向上したことで、「デスクトップ PC ブラウザでないと出来なかったこと」が少なくなりつつあった。

それから2015年頃に、Google などが主導で PWA (Progressive Web Application) という概念が提唱され始める。iOS・Android ともに「スマホブラウザ」の機能拡充が進み、スマホの利用頻度やシェア率も上がってきたことで、モバイルファーストでウェブアプリケーションを開発する流れができてきた。

PWA というのは技術の総称であったり、デザインパターンのことだったりで、「コレが PWA です」という実体があるワケではないのだが、基本的には

といった機能が盛り込まれたウェブページ (ウェプアプリ) のことを指す。

この Service Worker という技術が、ページを離れてタブを閉じても、ある程度のバックグラウンド動作を可能にする仕組みである。

…ほとんど自分で組んだことがないので、バックグラウンド動作というのがどういうライフサイクルで、どこまで柔軟にできるのかはよく知らないのだが…。

一方で、2010年頃から発展してきた Chrome 拡張機能は、いわゆる「PWA」よりもローカルな環境で、より OS ネイティブに近い環境で JS が動く仕組みである。

ブラウザウィンドウを閉じたあともタスクトレイにアイコンだけ常駐していて、Gmail や Google ハングアウトの通知を出してくれるような仕組みは、基本的にブラウザ拡張機能によって実現されている。ウェブサービス、ウェブアプリそのものを「擬似ネイティブアプリ化」する PWA とは違い、ブラウザに対して何らかの単機能を追加する仕組みであるところが若干毛色の違うところである。

当然ながら、「ネイティブアプリと同じように常駐して通知を受けたりしたい」ということは、何らかのプロセスが常駐して PC のメモリ・リソースを食うことになる。Chromium ブラウザはその根幹からメモリを食いがちな作りをしているので、リッチな体験と引き換えに PC のリソースが必要になってくる。

Core i5 以上、メモリ 16GB 以上というスペックが未だ得られない環境もあるので、「Google Chrome を閉じた際にバックグラウンド アプリの処理を続行する」チェックを外せ、とよく記事にされていたりして、ブラウザのバックグラウンド処理による体験を活用しているユーザは思ったよりも少ないような気がしている。

少なくとも自分は、ブラウザ終了後もプロセスが残り続ける拡張機能を一切利用していないし、Service Worker による恩恵も受けた気がしないし、PWA のインストールもしたことがない。Windows の UWP (Universal Windows Platform) のように、裏側が PWA なアプリは使っているし、ChromeOS のアプリが大体 PWA だったりするのは分かってはいるが、こう、自分から明示的に PWA の恩恵を受けようと思って活用したことはないな、という。

というかもはや最近は、ブラウザは基本開きっぱなしの生活なので、仕事でも Gmail 通知は「常に開いている Gmail のタブ」から通知されているし、ハングアウト系の通知はあえて切っていて余計な割り込みタスクを発生させないようにしている。Slack はネイティブアプリとしてインストールしているのでブラウザとは完全に別けている (Slack のネイティブアプリが内部的には Electron 製なのは分かっている)。個人的にはまさに

普通のブラウザウインドウを単に非表示にすれば実装できるよ

と同じことをやっていて困っていない、という…。

Web を通じて提供した JavaScript コードが、ブラウザを閉じていてもバックグラウンドで動作していて、そこから OS ネイティブのプッシュ通知が出せたりする、みたいなのって、何か面白そうで憧れるんだけど、よくよく考えると「プッシュ通知ってそのものが鬱陶しいから、普段全部オフにしてるよね?」ってことに気付いて、個人的にはあんまり頑張ってこなかった。

受託開発で作るギョーミーなアプリだと、「社内用途で非公開のウェブアプリなので HTTPS 対応とか関係ありません」「社内 PC には標準外のアプリは一切インストール禁止です」みたいなこともあって、PWA や Electron みたいな技術でもってインストール可能なアプリにするメリットがなかったりする。

せいぜい、Bluetooth 通信みたいなハードウェア側の機能を使いたい時に「Cordova を使えば Swift や Java を書かずに済むよね」ぐらいのことで利用し始めたりするのだが、Cordova も React Native も Flutter も、それはそれでつらみがあるので、本気で作ろうとするとすぐ DMM みたいに「React Native 止めて Swift に移行します」なんてことになる。当たり前な流れ。何のために Web 技術で頑張ってるんだっけ?っていうね。

自分でウェブサービスを運営していたりすれば、また違うのかもしれない。Twitter や Evernote なんかは PWA・UWP で提供しているワケだし。

かつて <bb> 要素?なんかで構想されていた夢が、Service Worker や Browser Extension としてある程度安定した形になってきていることだし、今まで自分がやったことないことに挑戦する意味で、今度勉強してみようかなぁ。