現代のウェブブラウザの目指している方向性について紹介する モダンブラウザで使える最新の面白便利APIを紹介する ちゃんと仕様に入りそうなもの(Googleの力技で…も含む) (前半の各ベンダの話は
個人の見解を含みます) Ecma InternationalにてECMA-262という規格番号 Array、Number、ES modules、async-await、class、globalThis等々JS自体の言語機能の仕様はここにある 今はwhatwgのLiving Standardなものが標準仕様 JavaScriptに含まれていないFetchやStorage、WebRTCやその他諸々はこっちで策定 FetchはAbort出来るが、PromiseはAbort出来ないのはAbortはFetchの仕様だから DOM側のPromiseに入れようとしてたが、ESと乖離するので回避された結果 Web Incubator Community Group Web標準に新しいAPIを取り入れるための議論、仕様提案から普及の支援を目的にしたコミュニティ 現在のChromeで使える先進的な多くのAPIはここで議論され草案が作成されている段階のものが多い Webブラウザが内包しているHTMLエンジンやJavaScriptエンジンはそれぞれこれらの仕様を基に機能を実装している V8に実装されたESの機能はnodeでも当然使える 一方で、commonjsのrequireはESで標準化されたりはしなかったし、今ブラウザに載っているStreamsの仕様はwhatwgにある(つまりnodeとは異なる) 現在のWebまたはウェブブラウザの立ち位置について Appleは正直よく分からないが、あんまりやる気は無さそう ServiceWorker / PWAへの追随の遅さ いくつかのAPIのSafariへの搭載は拒否している(後述) Chrome (/w MSEdge) が結果的にWebが持つ機能と仕様、その実装を牛耳っている WICGで提案されているものの多くがChromiumチームからの提案でChromiumには載っていて、Origin Trialなどでフィールドレビューされているものが多くある それらはWebを勿論快適にするだろうとは思うものの、Chromiumの先進的なプロセス分離とサンドボックスを利用したPortalsなど他のブラウザが本当に追随できるのかという点で懐疑的でもある 実際この資料で紹介する最新のAPIも全てChromeに載っているものである… WebUSB / Web NFC / Web Bluetooth AppleとMozillaはユーザートラッキングの拒否/プライバシー保護に積極的 Safari: ITP / Storageの7日間キャップ Firefox: ETP (ITPのFx版。ブラックリストに載っているドメインからはUAが取れない等) Googleはアドセンスやアナリティクスとの上手い兼ね合いを成立させたそう Cookieの代替を探す方向がありつつも足並みは揃ってない Safariは3rd をParty Cookie保存しない chrome://flags/#storage-access-api 3rd Partry Cookieに代わる取り組み 実際にNotaで使えそうなブラウザのAPIをいくつか紹介します 事前アンケートからペンタブレットやCSSなどのキーワードがあったのでその辺からも拾っています 今日は主に既に勧告になっているものやWICGで議論されていて、1つ以上のブラウザで実装されているもの(一部例外を除く)について話します Promise が返ってくるので、非同期に使えるクリップボードAPI navigator.clipboard.readText() navigator.clipboard.read() navigator.clipboard.writeText() navigator.clipboard.write() モダンブラウザで共通して書き込めるのは image/png と text/plain ReadableStream / WritableStream / TransformStream ReadableStreamは全てのモダンブラウザで利用可能 例: Fetchの Response.body はReadableStream Fetchで受けたReadableStreamの前後に新たなReadableStreamを合成する const startFetch = caches.match('/shell-start.cbd594dfa81d.inc'); const endFetch = caches.match('/shell-end.cbd594dfa81d.inc'); const middleFetch = fetch(url).then(response => { if (!response.ok && response.status != 404) { return caches.match('/error.ba6821d4f751.inc'); }).catch(err => caches.match('/offline.d989ddb2d13b.inc')); function pushStream(stream) { const reader = stream.getReader(); return reader.read().then(function process(result) { controller.enqueue(result.value); return reader.read().then(process); .then(response => pushStream(response.body)) .then(response => pushStream(response.body)) .then(response => pushStream(response.body)) .then(() => controller.close()); const stream = new ReadableStream({ interval = setInterval(() => { let string = randomChars(); controller.enqueue(string); if (Math.random > 0.95) controller.close() HTMLCanvasElement.captureStream TextEncoder で Uint8Array を得る Workerとのやり取りに使う(Chrome flag: enable-experimental-web-platform-features) Streamsを postMessage 出来るようにする目論見がある 改行区切りとかでWorkerにメッセージを送り続けることが可能 ChromeではFetchの Request.body にもReadableStreamが使えるようになった(Chrome 85b /w flag: enable-experimental-web-platform-features) HTTPのレイヤで使えるので、Proxyとかも考えるとちょっと楽 主にSurface上のMSEdgeを意識してVirtual Keyboardを適切に扱うためのAPI提案 上手くいくとiOSのキーボードも同じように扱える期待は高い window.navigator.virtualKeyboard.overlaysContent = true; navigator.virtualKeyboard.addEventListener("geometrychange", (evt) => { let { width, height } = evt.boundingRect; if( width !== 0 && height !== 0 ) { console.log('virtual keyboard is now visible!') document.querySelector(".search-box").style.bottom = `${height + 15}px`; bottom: env(keyboard-inset-bottom); TouchEvent.touches: Touch[] Touch.azimuthAngle / Touch.altitudeAngle : 向き Touch.force : 圧力(0 - 1) float PointerEvent.touchType === 'pen' : ペンかどうか PointerEvent.pressure : 圧力(0 - 1) float PointerEvent.twist : 角度(0 - 359) Surface Pro penやApple Pencilなどのペン自体のイベントを扱えるようにするAPIの提案 penbuttonclick , penbuttondblclick penbuttonpressandhold : ボタンが押したままのときは消しゴムにするとか pendockchange : dockに格納されたらお絵かきのモードを切り替えるとか content-visibility: auto を指定して要素をchunk分割することでレンダリングを最適化できる contain の layout , style , paint が当たってるのと同じになり、画面外のものは size も含む contain-intrinsic-size でplaceholderのようにサイズを指定できる display: none : rendering stateが破棄されるので、再度表示する際には新規にレンダリングするのと同じコストがかかる visibility: hidden : rendering stateは維持されるが、子要素含めてドキュメント上に残り、またblockスペースは維持される content-visibility: hidden-matchable ざっと名前だけだと60以上のブラウザで使えるAPIを紹介しました この中のもののいくつかが全てのモダンブラウザで使えるようになるかは… モダンブラウザだと色々出来るので積極的に使っていきましょう UAで判別せずにfeature detectionしよう Slackの#frontendで常に紹介したりしているので覗いてみてください "Web API"はGoogle Maps APIなどのようなウェブサービスが提供することでJavaScriptのAPIのことは指さないのではないか 例えば、MDNでもWeb APIsとしてここで紹介したようなJavaScriptやCSSなどで利用可能なAPIの一覧が記載されています。まぁややこしいという意見は受け入れますが、そう呼ばれているので仕方ないですね…