新春特別企画

2019年のWeb標準

あけましておめでとうございます、@1000chこと泉水翔吾です。2018年に続いて、2019年のWeb標準技術の動向も予測していきます。

Microsoft EdgeへのChromiumプロジェクトの採用

2015年7月にMicrosoft Edge(以下、Edge)が発表されてから早3年が経ちます。Microsoftは、古くなったアーキテクチャの刷新とWeb標準技術へより高速に追従することをゴールに、レンダリングエンジンEdgeHTMLの開発をゼロベースで進めてきました。

ところが2018年12月、MicrosoftはEdgeのレンダリングエンジンにChromiumプロジェクトを採用することを発表しました。公式ブログの記事には「Chromiumというオープンソースソフトウェアへのコラボレーションを通じて、Webプラットフォームをより良いものにしていく」と、あります。この決定に至るまでにどんな経緯があったかは知る由もありませんが、EdgeHTMLの開発が断念されてしまったことは事実です。

Operaも2013年にレンダリングエンジンPrestoの開発を中止し、Chromiumを採用しています。それ以来、主要なブラウザエンジンは、ChromeとOperaに採用されているChromium、FirefoxのGecko、SafariのWebKit、そしてEdgeのEdgeHTMLという状況でした。今回EdgeがChromiumを採用することで、現存する主要なブラウザエンジンは、Chromium、Gecko、WebKitの3つに絞られることになります。

今やWeb標準技術は非常に大きな仕様です。大きくなりすぎたが故に、ブラウザをゼロから作るのは現実的に難しい状況にあるでしょう。Webプラットフォームを支えるブラウザは、これらの巨大な仕様を実装し続けなくてはなりません。ブラウザを作ることへの投資とそこから得られる利益などプロプライエタリな側面を含めて様々な理由があるとは思いますが、長らくブラウザを開発しインターネットを支えてきたMicrosoftという巨大な企業がこの選択に至ったのは、感慨深いものがあります。

EdgeHTMLというレンダリングエンジンが失われることで、Webの多様性が失われる懸念もあります。現在、W3CにおけるWeb技術の標準化プロセスではドラフトの提案に始まり、2つのブラウザによる参考実装が行われ、初めて仕様として勧告されます。例えば過去にGoogleから提案されたHTML Importsは、先行してChromiumが実装しましたが、FirefoxやSafariが反対し実装を行わなかったため、仕様として見送られました。このように、各ブラウザベンダーは一定の影響力を持っていますが、EdgeがChromiumを採用した今、Chromiumの影響力はより強まっていくでしょう。実際、このEdgeの発表に寄せて、MozillaもWebの中立性についての声明を出しています

みんなで決めた仕様に沿って、ブラウザやWebページが実装されて成り立っていることが、Webの良さであり、凄さでもあります。EdgeにChromiumを採用した今、MicrosoftがGoogleだけでなくWebプラットフォームに対してどのように関わっていくか、注目したいところです。

Low Level APIとLayered APIs

Low Level APIを定義することで、開発者で拡張できるWebの世界を唱えたThe Extensible Web Manifestoの登場以降、Web標準技術はより低レイヤなAPIの策定が進んできました。例えば、昨年の記事で紹介している技術でいえば、Web ComponentsはCustom ElementsShadow DOMなどの仕様からなる技術ですし、Service Workerについてもキャッシュの機能を実現するにはCache APIFetch APIを使って実装する必要があります。Extensible Webが目指した「拡張できるWebの世界」は、実現されつつあると言えるでしょう。

Low Level APIの策定が進む一方で、High Level APIの需要も見直されてきました。Low Level APIを組み合わせれば確かに大抵の需要は開発者自身で満たせますが、それはページロード時に読み込むJavaScriptファイルのサイズの増加も招きます。これはHigh Level APIが提供されることで解決されるはずです。

だからといって闇雲にHigh Level APIを定義していくと、仕様を標準化してブラウザに実装し、フィードバックを経て、開発者に受け入れられなければ非推奨化する……という、標準化プロセスにこれまでと同じ膨大なコストを払うことになります。そこで、標準化したいHigh Level APIはLow Level APIを前提としようという動きがLayered APIsです。

Layered APIsに沿うことで、提案するHigh Level APIに対してLow Level APIを使ったポリフィルが提供可能になるとともに、より高い需要を満たすAPIを低いコストで標準化できることが期待されます。Layered APIsには、策定候補となるAPIとポリフィルをシームレスに読み込むためのES Modulesの拡張文法も含まれます。こちらもまだ実験段階ですが、実現すれば以下のような記法で、ブラウザ実装が存在する場合はネイティブAPIを、存在しない場合はポリフィルを読み込めるようになるでしょう。

import { ProposedAPI } from 'std:proposed-api|https://cdn.example.com/proposed-api-polyfill.js';

Web標準技術がLayered APIsに沿って標準化されるようになれば、Low Level APIを使っていくだけでなく、便利なHigh Level APIを開発者自身で生み出し易くなるでしょうし、自らで提案していくことの敷居も下がっていきそうです。

HTTP/2の普及とHTTP/3の標準化

HTTP/1.1の後継となるHTTPの新たなバージョンとして、HTTP/2が2015年5月14日にRFC7540 Hypertext Transfer Protocol Version 2(HTTP/2)として標準化されました。GoogleがWebにおける通信の高速化を目指したSPDYが前身となっており、SPDYはバージョンアップを経てHTTP/2の仕様として取り込まれています。

標準化してからおよそ3年半を経て、広く普及が進んでいます。サーバーサイドのソフトウェアとしてはNginxやApacheをはじめ、h2oNode.jsのhttp2モジュールなどもサポートしています。クライアントサイドのソフトウェアとしてはChrome、Firefox、Safari、Edgeなどの主要ブラウザがサポートしており、提供する側とされる側の両方の準備が整っていると言えるでしょう。実際にどの程度普及しているかについては、HTTP ArchiveのState of the Webによると、2018年12月1日時点で、デスクトップではリクエストの49.1%が、モバイルでは48.8%がHTTP/2であるというデータがあります。Webにおけるリクエストのおよそ半分が既にHTTP/2で行われているということです。

HTTP/2の登場から(HTTP/1.1の策定からHTTP/2の策定までにかかった16年に比べると)わずか3年半しか経っていませんが、早くも次のバージョンであるHTTP/3の策定が進められています。HTTP/3はトランスポートレイヤにTCPではなくUDPを採用しており、Webにおける通信のベースを大きく変える仕様となっています。これにはUDPもとい、QUICの存在が大きく関与しています。

HTTP/2はHTTP/1.1との互換性を維持したまま最適化したプロトコルですが、SPDYの時点で下位レイヤのTCPによる制限を課題としていたGoogleは、次のネットワークプロトコルとしてQUICの開発に取り掛かりました。QUICはUDP上でセキュアで多重化された通信を行うトランスポートレイヤのプロトコルで、TCPでは短縮しきれないレイテンシを減らすことを目指していました。QUICはIETFのワーキンググループによる標準化が進められてきましたが、2018年11月に行われたIETF 103 BangkokでQUICを利用したHTTPをHTTP/3とするというコンセンサスが得られました。つまり、次世代のHTTPであるHTTP/3ではUDPベースとなるのです。

トランスポートレイヤとしてのQUICがそのまま採用されるかどうかはわかりませんが、Googleは既に様々なサービスにQUICを実験的に採用していることから、仕様策定も実装も強く推し進めていくことが予想されます。HTTP/3の今後の動向にも注目したいところです。QUICおよびHTTP/3については詳解 HTTP/3が非常に参考になるので、是非読んでみてください。

Webパフォーマンスに関するAPIの拡充

Webアプリケーションの品質に関するトピックとして、Web界隈のパフォーマンスへの関心は以前として高いでしょう。Web標準技術においても、パフォーマンスに関するAPIが増えてきました。

昨年紹介したようなService WorkerやResource Hintsなどを中心に、リソースロードに関する処理性能を改善しやすくなっています。それ以外では、ブラウザのメインスレッドを専有しないことでランタイムの処理性能を改善するoff-the-main-threadが注目されつつあります。

ブラウザの処理は基本的にメインスレッドで実行されるため、例えばJavaScriptの重い処理が実行されている間は他の処理ができなくなり、UIが適切に反応しないなどの事象が起こり得ます。昨今のJavaScriptライブラリを組み合わせて構築している重厚なWebアプリケーションにおいては、こうした問題がより顕著に起こります。off-the-main-threadはメインスレッドとは異なるスレッドに処理を委譲することで、Webアプリケーションの性能を引き出すアプローチです。off-the-main-threadはブラウザの内部実装とWebアプリケーション実装の両方を含みますが、この記事ではWebアプリケーション実装を指すものとします。

スレッド処理と言えば、真っ先にWeb Workerが思い浮かびますが、まさにこれがoff-the-main-threadのアプローチの基本です。メインスレッドで実行している処理をWeb Workerに逃がし、実行結果をメッセージ経由で受け取れば、その間のメインスレッドは他の処理を実行できます。例えば、各種UIライブラリの内部で実行されるVirtual DOMの差分計算はDOM Treeに応じて重くなる処理ですが、これをWeb Workerに移譲できればより効率的に描画できるはずです。

Web Workerにも、APIであるpostMessage()が使いにくかったり、DOMにアクセスできないなど、様々な課題があります。前者については、メインスレッド側のJavaScriptで移譲したい処理をシリアライズしてWeb Workerに渡せるblocksという文法が提案されていたり、使いやすくラップしたライブラリなども登場しています。また、より軽量なWeb WorkerとしてWorkletの策定も進んでいるなど、2019年はこうした課題が解決されて、off-the-main-threadのパラダイムがより強まっていくことが予想されます。

性能の改善の他には、PerformanceObserverを中心に様々な指標を計測できる準備が整いつつあります。既に安定してきた仕様としては、ページロードまでの各種タイミングを取得するNavigation Timing APIWebアプリケーションにおける任意のタイミングを取得するUser Timing APIダウンロードしたリソースのダウンロードにかかった時間などを取得するResource Timing APIサーバーの処理時間などを取得するServer Timing APIなどがあります。また、現在策定が進められているものでは、イベントループ中のフレームの情報を取得するFrame Timing APIや、描画タイミングに関する情報を取得するPaint Timing APIユーザーのインタラクションで発生するイベントの情報を取得するEvent Timing APIがあります。

これらを使って実装やサービスの性質に合わせたパフォーマンス指標を取得し、より柔軟にWebアプリケーションのパフォーマンスを俯瞰していけるでしょう。

パフォーマンスについては、2019年1月13日(日)に開催される「次世代Webカンファレンス」でも議論する予定で、著者らが担当するセッションの#nwc_perfは10:00開始です。当日の様子は収録され、後日公開されるようなので、カンファレンスに参加されない方はそちらをご覧ください!

おすすめ記事

記事・ニュース一覧