このサイトの記事更新は2019年11月に終了されました。過去記事アーカイブを公開しています。
投稿されたすべてのトピック
Firefox 49 アドオン互換性情報
[これは Mozilla Add-ons Blog の記事 Add-on Compatibility for Firefox 49 の翻訳です]
Firefox 49 が 9 月 13 日 [日本時間同日深夜] リリース となります。Firefox 49 の変更点でアドオンの互換性に影響を及ぼす可能性のあるものを以下にまとめました。Firefox 49 for Developers により詳しい情報が載っていますので、こちらも併せてご覧ください。
一般
- ドアハンガー通知のアンカー ID とクラス名重複が一掃されました。これはポップアップ通知を使用しているアドオンのスタイル付けに影響する可能性があります。
window.open()
を通じて開かれたウィンドウが初期設定でスクロール可能となりました。String.prototype.search
、match
、replace
から非標準のフラグ引数が削除されました。- HTML Microdata API が削除されました。
XPCOM とモジュール
- 子プロセスに送られる設定値のサイズが制限されました。改めて注意しておくと、巨大なデータを保存するのに設定サービスを使ってはいけません。小さな値 (4 KB 以下) にのみ留めるべきです。今回の変更により、プロセス間通信にこの制約が適用されました。
protocol.js
が移動されました。今後このモジュールにアクセスするにはrequire("devtools/shared/protocol")
を使ってください。今のところ、古いパスでも使えるよう過渡的措置が取られています。nsFaviconService.cpp
に廃止警告が追加されました。お気に入りアイコンを操作するアドオンを作っている開発者は このバグのコメント に書かれた変更点を確認してください。今のところ、適切なプリンシパルを渡さなかった場合に警告が表示されるだけですが、ゆくゆくは意図した通りに動作しなくなります。
この一覧に載っていない変更点や間違いを見つけたらコメント欄でお知らせください。もしあなたのアドオンが Firefox 49 で動かなくなった場合は、筆者の方でも調査したいと思います。
AMO に登録されているアドオンの 自動互換性テストと対応バージョンの更新 は数週間以内に行われますので、AMO に Firefox 48 対応のアドオンを登録している方は後日メールをチェックしてみてください。
JavaScript エラーを簡単に調べられるようになりました
この記事は Helping web developers with JavaScript errors の抄訳です。
プログラミングをしていてとてもイライラするのがエラーです。エラーを表す短いメッセージがコンソールに出ると、それまでの午後全て、いやその日 1 日、ひょっとするとその週全てが台無しになってしまいます。例えば “undefined is not a function” と表示されたら、イライラを鎮めにコーヒーを淹れにいくといいかもしれません。
真に正しくそして唯一の JavaScript のエラー処理を実現していたとしても、また神速で $search_engine にコピペができたとしても、エラーに関する役立つ情報を探すことは面倒なものです。
本当はそんなことをする必要はないんです。いくつかのプログラミング言語、例えば Rustなどは、ただエラーが起きたことを報告するだけではなく、それ以上の情報をエラーレポートとして表示します。
このたび MDN コミュニティの力を借りて、Firefox の コンソールにそのエラーを解説するページへのリンクを表示する機能を追加しはじめました。
この機能をつかえば、より高速にデバッグができ、知識が少なくても JavaScript のエッジケースについて多くのことを学べるようになります。とくに JavaScript 初心者の方にとって役立つ機能になれば、そして解決策がわからないままコーヒーブレークを取りつづけることが減れば、と思っています。
JavaScript、DOM、その他のエラーについて、全て解説するのは量も多く、とても大変な作業です。そのため、いまのところは最も良く見るエラーのみ注力しています。この機能の充実に助力いただける方は、ぜひ MDN のコミュニティをご覧になってください。エラーに関する解説を書くことは、JavaScript の興味深い側面に詳しくなる良い機会となるでしょう。
この機能は Firefox の Nightly ビルドでご利用になります(訳注:Developer Edition の最新版でもお使いになれます)。また MDN の JavaScript エラーのページでも、エラーに関する説明をご覧になれます。
Florian Scholz について
Florian は MDN のテクニカルライター兼、WiKi を直す小人です。2010 年に Mozilla に参加。ドキュメンテーションとオープン Web 技術を広く届ける活動に従事。ドイツのブレーメン在住。
- Web サイト:florianscholz.com
- Twitter:@floscholz
Morgan Phillips について
Morgan は JavaScript エンジンのハッカーで、自称インターネットフーリンガン。オレゴン州ポートランド在住。コンパイラ、OS、linuxpoetry.com にできの悪い詩を書くことに興味がある。
- Web サイト:mrrrgn.com
- Twitter:@mrrrgn
Developer Edition 49:ネットワークモニタでのスタックトレース表示、など
この記事は Developer Edition 49: Network Request Stack Traces and more の抄訳です。
今週(訳注:2016/06/15 の週)Firefox Developer Edition 49 がリリースされました。この記事では、このリリースに含まれる大きな変更点について解説します。
ネットワークモニタでのスタックトレース表示
ネットワークモニタには新しく “Cause” 欄が追加されました。ここには、そのリクエストの種類が表示されるとともに、送出したドキュメントがツールチップで表示されます。またリクエストが JavaScript によって送出されている場合、そのスタックトレースが吹き出しとしてポップアップ表示されます。
スタックトレースが最も有用なのは XHR に対してですが、JS による script 要素 や img 要素 のページへの挿入といった直接的でないものに対しても表示されます。
この機能は、特定の HTTP リクエストが送出される理由と、そのリクエストを送っている箇所の発見に有用です(bug 1134073 を参照してください)。
インスペクタでのアニメーション性能情報の確認
インスペクタを利用すると、CSS アニメーションと DOM アニメーションを詳細に調査できます。Firefox 49 では、アニメーションのパフォーマンスに関する情報が詳細に表示されるようになりました。ハードウェアアクセラレーションを使用できない場合が典型例ですが、アニメーション属性がコンポジターで処理できない場合、そのアニメーションには下線つきで展開されたアニメーションビューに表示されます。またその理由はツールチップに表示されます。
下記の例では、transform と width の属性に対して、同時にアクセラレーションが効かせられないことが示されています。このように性能の低いアニメーションを観察し、パフォーマンスを向上するために何をすれば良いのかを知ることができます。
アニメーションの Gecko 内部における最適化に関しては、David Baron のブログ記事に詳細が述べられています。そちらをご覧ください。また bug 1254408 には、より詳しい記述があります。こちらもご参照ください。
マークアップビューで使えるコンテキストメニューの再構成
インスペクタ中で利用できるコンテキストメニューからは、いろいろな機能を呼び出せます。その結果、メニューが長大で使いにくいものとなっていました。Moaaz Sidat の貢献によって、メニューがいくつかのサブメニューを持つように再構成され使いやすくなりました。
インスペクタに対するその他の変更
今バージョンより #rrggbbaa と #rgba 文法が利用できるようになりました。これにあわせて、インスペクタでもこの文法が利用できるようになりました。詳細は bug 1271191 をご覧ください。
CSS ルールエディタの補完機能も改善され、スクロール可能なリストに従来よりも多くの候補が表示されるようになりました。これにより使いたい属性を簡単に探せるようになりました。また馴染みのない属性をを見ることで、それらについて学ぶ良い機会ともなるでしょう。この変更に関する詳細は bug 1260419 をご覧ください。
マークアップビューにも変更点があります。<br> のようなから要素は、doctype が XHTML の場合にのみ <br></br> のように表示されるようになりました。HTML の場合は、より正確で冗長性の少ない書式で表示されます。詳しくは bug 820926 をご覧ください。
コンソールに表示される JavaScript のエラー表示から MDN へのリンク
コンソールに馴染みのないエラーが表示された時、これまではエラーメッセージをコピーして、そのメッセージで検索することで、そのエラーに関する解説を探していたと思います。このバージョンからは、そのエラーについて解説する MDN のページへのリンクがコンソールに表示されるようになりました。この機能の詳細は @floscholz と @mrrrgn の記事をごらんください。同記事には、この機能を改善するための方法についても解説されています。また bug 1179876 もあわせてご覧ください。
シンタックスハイライトのカラースキームの追加
シンタックスハイライトに利用している色が少しばかり古めかしく感じていました。そのためカラースキームを、よりコントラストが高く、可読性が高いものへ更新しました。 Developer Edition の light-theme および dark-theme の両方のカラースキームが変更されています。
アクセシビリティの向上
アクセシビリティに関しては、いくつかの重要な改善が行われました。開発ツールの UI のほとんどで、フォーカスがより分かりやすくなりました。またキーボードでの操作ができるようになり、インスペクタパネルのアクセシビリティも向上しています。詳しくは、bug 1242694、1242715、1242851 をご覧ください。
その他の特記すべき変更点
上記に以外の変更点で、特記すべきものをはこちらになります:
- プライベートブラウジング、もしくは設定によって service worker が無効になっている場合、about:debugging に警告が表示されるようになりました(bug 1266415)
- ストレージインスペクタで編集できる項目が増えました。今回のリリースでは、IndexedDB のデータベースをコンテキストメニューから削除できるようになりました(bug 1205123)
- ネットワークインスペクターで、1 KB より小さい場合でも正確なレスポンスサイズが表示されるようになりました(bug 1263945)
- インスペクタパネルで、’h’ のキーを押すことで選択している要素を非表示にできます。このときマークアップパネル中の該当要素もグレーアウトされます(bug 1127572)
Developer Edition のリリースにご貢献いただいたすべての方に感謝します。最新版をインストールして、フィードバックをお寄せください。
Jarda Snajdr について
Firefox への貢献者。ブラウザの内部構造を学ぶことと、複雑な問題を解くことを好む。
Twitter: @jsnajdr
Web 向けの 3D ゲーム作成の基礎
この記事は “Basics of building 3D games on the Web” の抄訳です。
「3D ゲームは、2D ゲームよりも作るのは難しい。だって管理しなきゃいけない次元が 1 つ増えているし。」
そう考えている人もいるでしょう。実際のところ、3D のゲームは私たちが想像しているよりも簡単に作れます。私たちは最近 MDN のゲームに関するコーナーを更新し、3D ゲームに関するチュートリアルを追加しました。このチュートリアルはフレームワークの利用に焦点をあてており、WebGL に不案内な Web ゲーム開発初心者でも 3D ゲームが作れるような内容になっています。
WebVR と 3D ゲーム開発
ブラウザ上での VR コンテンツは、今年に入って大きな進歩を遂げています。また WebVR として知られる JavaScript API の開発も進み、その仕様は バージョン 1.0 に向けての策定が行われています。これはブラウザ上での VR 技術にとって、大きなマイルストーンとなるでしょう。WebVR API が成熟してくると、コンテンツのレベルも「実験的なデモ」から商用ゲームや商用アプリケーションなどの「製品レベル」へと変わってくるでしょう。
Three.js を利用して作られている WebVR フレームワークである A-Frame も大きく進化しています。Cardboard Dungeon や SECVRITY のような興味深いケーススタディも行われ、またフレームワーク自身もバージョン 0.2.0 がリリースされ、コミュニティから早くも興味を寄せられる存在となっています。マークアップによってプラットフォームやデバイスで利用可能な VR コンテンツを作成する、という A-Frame のアプローチは単純ながら強力です。その結果として、チュートリアルやデモ、プラグインが毎日のように制作されるようになりました。
現在は、最先端の VR を実験するにはとても良い時期です。しかし私のような 2D ゲームのファンにとっては、3 次元へと飛び出すのは、とてもハードルが高く感じられることでしょう。だから 3D の基本を一緒に学び、フレームワークを使えば印象に残るゲームやデモを作成するという目的を、より素早く達成できることを確認しましょう。
3D の Web ゲームは、リッチで、インタラクティブなアニメーションを Canvas へ、いかに ハードウェアアクセラレーションの効かせて WebGL でレンダリングするかにかかっています。それには作成物の情報を管理し、画面上への描画を行っているレンダリングパイプラインについて理解する必要があります。基本理論ではそのレンダリングパイプラインの動作について概観しています。
3D ゲーム開発のためのフレームワーク
ゲーム開発を全て生の WebGL によって行うこともできますが、フレームワークを使うことで開発を簡単に、高速に行え、ゲームのアイディアに集中できるようになります。MDN に掲載されているチュートリアルでは以下のフレームワークを紹介しています:
- Three.js を利用した基本的なデモの作成
- PlayCambas を利用した基本的なデモの作成
- Babylon.js を利用した基本的なデモの作成
- A-Frame を利用した基本的なデモの作成
- GLSL シェーダー
Three.js は最も有名な WebGL アニメーションを作成ツールです。PlayCanvas はゲームエンジンである PlayCanvas Engine だけを利用することもできますが、オンラインエディタを利用して開発をすることも可能です。Babylon.js は強力な機能をもったシンプルな API を提供します。A-Frame は仮想現実における 3D 世界のプロトタイプ作成を高速に行うためのフレームワークです。またシェーダーの基本的な概念を理解するためのチュートリアルも用意しました。フレームワークの裏側で行なわれている勝利を理解することで、フレームワークによる処理が行われた後の結果を、より思い通りにコントロールできるようになります。
フレームワークを利用することの利点
ゲーム開発におけるフレームワーク利用の利点は何でしょうか?それは時間の短縮です。どのように短縮されるかを、見てゆきましょう:
まず、アセットのロード、シーンやスクリーンの描画といった、ゲーム制作の他の部分と比べて退屈な作業を減らせます。カメラ、光源など、それぞれ個別に設定が必要なものの管理もしなくてよくなります。ジオメトリを作成して、アニメーションを追加するだけで、後のことは何もしなくても、作品をすぐに見られるようになります。
ブラウザ実装の違いについても気にする必要がなくなります。ただフレームワークの提供するハイレベルでシンプルな API だけ知っていればよくなります。
フレームワークは多くのものを抽象化するので、開発者が書かなくてはならないコード量は少なくなり、また作業量も減ります。その結果、ゲームの核となる仕組みに注力できるようになるでしょう。フレームワークでは数行のコードで実現できる機能を JavaScript だけで実装しようとすると、最悪の場合は何十行にもわたることもあります。
フレームワークが変わると、体験も変わります。Three.js はアニメーション作成によく用いられる一方、Babylon.js はゲーム開発に向いており、アンチエイリアスも行います。どちらもゲーム作成に耐えます。好みとプロジェクトのゴールにあわせて使い分けてください。
いくつかのフレームワークは機能レイヤーを追加し、物理エンジンや、衝突判定、パーティクルシステムが組み込まれているものがあります。このようなインフラを利用することで互換性に悩まなくてすみ、プラグインをカスタマイズしたり、一から書いたりする必要もなくなります。
シーンのプロトタイプ作成も簡単になります。複雑なコードを書かなくても、複雑なものを作成できるからです。こちらに JavaScript だけで実装されたシンプルなブロック崩しゲームがありますが、Phaser を利用して作成されたものと比べると、随分複雑になっていることがわかります。フレームワークを使うことで、時間が節約され、その時間を個性を出すために利用できるようになるのです。
まとめ
フレームワークがどのように作成されているかを学ぶことは、良いプログラミング言語の学習になります。そしてフレームワークを拡張し、自分の望むように振舞わせることができるようになります。フレームワークには流行り廃りがありますし、フレームワーク固有の文法を追加で学ばなくてはなりません。結局、JavaScript だけで単純な機能を実装できるようになっているべきです。それは強力なスキルです。
それぞれのツールでシーンをどのように作るのかについては、私の GitHub レポジトリをみてください。これらの動作しているデモも公開しています。
これだけは覚えておいてください。特定のフレームワークを使わなければゲームを作れない、ということはありません。同じことを JavaScript と WebGL だけで実現できます。紹介したデモは、現在よく使われているツールの使い方を示すためのものです。足りないツールがある場合は、ぜひデモを作成して GitHub の方へ追加してください。いつでも歓迎します。またデモに含まれないツールがあれば、こちらにコメントを残すか、紹介を書いてください。多くの人知ってもらえるようになるでしょう。
上記で紹介したソースコード、ば新しい 3D ゲームのテンプレートにするといった感じで、自由に使っていただけます。使ったら、作ったものを教えてください。こちらにコメントをする形でも、GitHub のレポジトリにコメントする形でも、フィードバックはいつでも歓迎です。
Andrezej Mazur について
HTML5 ゲーム開発者で、Enclave Games のファウンダー。Gamedev.js という週間メルマガの発行人で、HTML5 ゲーム開発者向けのコーディング大会である js13kGames の発起人。新しいオープン Web 技術について技術講演を行い、WebVR に夢中になっている。
Unity で作ったインディーゲームの WebVR 出力
この記事は “Exporting An Indie Unity Game to WebVR” の抄訳です。
ツールをダウンロードしたりインストールをすることなく VR コンテンツをすぐに楽しめる WeVR は、未来における VR コンテンツアクセスの鍵を握っています。少なくとも、私たちはそう考えています。私たちは Jump と呼ばれるマルチプラットフォームなデジタルゲームの定額サービスを構築しています。Jump では、デスクトップやモバイル、ゲーム機、そして VR デバイスに向けた Web 技術のみで作られ「Web ネイティブ」ゲームを配信しています。私たちはビジネスを Web ネイティブな技術、HTML5、WebGL、JS、そして早晩リリースされる WebAssembly に賭けたのです。そしてWeb がバーチャル・リアリティに対して、いかに強力な存在であるかを示すことにしました。そのために Oculus Rift の WebVR ゲームを Jump に向けて作成しました。作成したゲーム SECCVRITY の開発期間は 1 月でした。短期間での開発だったため、WevVR API を深く理解して Web ネイティブなものとして作成することはできませんでした。そこで Unity 5 を利用して開発を行いました。
SECVRITY はコンピュータウィルスをモチーフにした、モグラ叩きゲームです。コンピュータセキュリティの専門家として、たくさんのモニタを監視しつつ、次々にやってくるコンピュータウィルスの侵入を阻止します。推測されている通り、スクリーンを見つめて、クリックすることでウィルスを無効化してゆきます。首がむち打ちになる可能性も非常に高いゲームですが、楽しさも非常に高いものになっています。その証拠に GDC Mozilla ブースでの試遊には多くの人が押し寄せました。
技術の話題に戻りましょう。Unity は WebGL と VR の両方に対応していますが、その 2 つへ同時に対応できるようにはなっていないことに気づきました。また WebVR は彼らの直近のロードマップには載っていません。このギャップを埋める方法を探すこととしました。Unity の WebGL 出力を利用することでゲームを Web サイト向けに出力できるため、WebVR API と Unity のゲームエンジンとをつないで、WebVR をゲームエンジンから利用することもできるにちがいありません。調査とゲーム作成を 1 月で行うことにならないよう、強く願ったものでした。
幸いにも、gtk2k によってこのブリッジの開発が 1 年前に開始されていました。彼のやり方は極めて直裁的なものでした:WebVR からの入力を API 経由で受け取る JS ファイルを含む Unity のWebGL テンプレートを作成しました。そのコードと Unity とは、 1 つのシンプルなスクリプトによって接続されます。スクリプトを Unity 上で適切に実装するために、通常の Unity カメラである standard view カメラと、視野角と X 座標が合うように調整され、隣り合って表示される画面用のステレオカメラの 3 つの異なるカメラを持つカメラプレハブが作成されました。 開発者はシーン内のメインカメラをこのプレハブに置き換え、StereoCamera.cs をアタッチするだけで、ゲームを WebVR 対応させられます。gtk2k のブリッジは、ユーザーが テンプレートに含まれる “Enter VR” ボタンを押すと standard カメラをステレオカメラに置き換えます。
Unity WebVR プロジェクトのサンプルか、UnityPackage をダウンロードすることで、必要なファイルをプロジェクトにインポートできます。
テンプレートの利用方法は以下の通りになります:
- Oculus Rift を手に入れます。外部からのアプリを実行できるようにしておきましょう。
- Firefox Nightly をダウンロードし、インストールします。
- WebVR enabler をインストールします。
- サンプルプロジェクト全体か、UnityPackage 単体をダウンロードします。
- Unity 5 をインストールして、”WebGL Build Support” と “Windows Build Support” を有効にします。
- サンプルプロジェクトか、UnityPackage を追加した自信のプロジェクトを Unity で開き、MainCamera を WebVRCameraSet プレハブに置き換えます。
- StereoCamera.cs がプレハブの親ノードにアタッチされていることを確認します。
- File から Build Settings を開き、WebGL をビルドプラットフォームに設定します。なお Development Build にはチェックしないでおきましょう。
- Edit → Project Settings → Player を開き、Player 設定を開きます。Resolution and Presentation で、WebGL テンプレートを WebVR に設定します。
- 同じ Project Settings で、WebGL Memory Size を最低でも 512 MB に設定します。これは out-of-memory エラーを避けるためです。SECVRIY では 768 MB に設定しています。
- ビルドして、Firefox Nightly で起動します
- 手元で、もしくはWeb サイトにアップロードして、テストできます。
Unity で WebVR ビルドを試してもいいと思っていただければ幸いです。エディタ内でテストするには、デスクトップ VR ビルドのための標準機能を有効にします。Edit → Project Settings → Player を開き、Standalone タブ(下向き矢印アイコンのタブ)を選択します。Resolution and Presentation が表示されていますが、Other Settings まで移動し、Stereoscopic Rendering と Virtual Reality Supported にチェックを入れます。これらは WebVR ビルドそのもには必要ありませんが、エディタ内でテストするためには設定しておく必要があります。
デザインの点でテンプレートを補完するために、ブラウザウィンドウを VR モードにするための手順を追加しました。また VR もしくはマウスでの操作を選択できるようにもしました。これは物事をややこしくすることとなりました。
ブラウザの中で動作するのだから、VR を利用しないデスクトップ環境のユーザにも SECVRITY をプレイして欲しいと考えていました。VR をサポートする以前より、マウスによる操作ができるようになっていたため、マウス操作自身は単純でした。しかし VR からの入力が可能な状態でのマウス操作は、非常に悪い結果をもたらしました。マウスの動きと VR ヘッドセットの視点とは、本質的に何の関係もありません。そのため A:ユーザが完全に迷子になり、B:とても酔ってしまうこととなりました。そのため VR を使用しているかどうかを検知し、マウス操作を on / off する必要がありました。
メインメニューで明示的にマウス操作が選択されない限り、VR からの入力の有無に関わらず、マウス操作を無効にすることが私たちの解決策です。プレイ前に、ユーザに矢印キー、もしくはジョイスティックで入力方法を必ず選択させるようにしました。ちなみに WebGL/WebVR 出力は Gamepad API をサポートしています。そのため通常のビルドに追加して行わなければならない作業はありません。もしユーザが VR ヘッドセットを利用した状態でのマウス操作を選択した場合、酔いが誘発される問題が発生します。プレーヤーにはこのように警告します:このゲームは 1 月でつくられました。将来追加されるであろう、自動検知によってこの問題は解決します。
Unity で WebVR コンテンツを作るための価値ある知見を得ました。主には VR / 非VR を組み合わせた場合の体験に関するものでした。トラブルの多くはエンジンが WebVR に正式対応することで解決されるべきです。しかし正式対応されたとしても、ユーザが何をすると、もしくは何をしないとゲームが楽しめないかという点、特に操作方法が大きく違う場合についての理解が重要であることは変わりません。最近行われた Firefox Nightly の変更に対応するため、gtk2k のテンプレートに対して若干の修正を加えましたが、その点を除けばうたわれている通りに動作し、ゲームの移植に必要な作業はほとんどありませんでした。まさに彼はヒーローです。
Web はゲームにとっての未来であり、SECVRITY のようなゲームを持つ Jump はそれを世界に証明しようとしています。デスクトップ、モバイル、ゲーム機、VR ヘッドセット、他のデバイスでも、Web ゲームはユーザにゲームのインストールをさせなくても、すぐにプレイしてもらえるようになります。動作スピードもネイティブに迫るものがありますし、WebGL 2.0 や WebAssemmbly も実用に近づきつつあります。近い将来のグラフィックスも見えはじめています。Jump は Web の革命を進めて、どの端末のゲームでも Web が究極のホームとなるのを後押ししたいと考えています。Jump の進捗にご興味をお持ちの方は、http://www.jump.game からニュースレター配信にご登録ください。また SECVRITY のライブデモは mozvr.com にて公開されています。信じてください。Web はゲーム業界に変革をもたらすでしょう。そしてブラウザを使って美しい仮想現実へすぐにアクセスできるようになる、WebVR は Web の力を開発者とユーザに対して示す重要な役割を担うことになるでしょう。
Anthony Palma について
2016 年にローンチされたデジタルゲーム配信サービスである Jump の CEO。ベータ版へのユーザ登録や、ゲームをサービスに登録されたい場合は、ご連絡ください。
- Web サイト:http://www.jump.game
- Twitter:@JumpDotGame
Popup ALT AttributeアドオンにおけるXUL/XPCOMからWebExtensionsへの移行
今日の投稿はPopup ALT Attributeや40 other add-onsを 開発しているpiro氏の記事からの投稿です。彼はXUL/XPCOMアドオンからWebExtensionに移行するための考えを共有し、彼がどのよう にPopup ALT Attributeを移行したかを私たちに見せてくれました。彼のブログで全文を読むことができます。
***
こんにちは、アドオン開発者のみなさん。私の名前は結城洋志、ニックネームはPiro、そしてFirefoxアドオンの開発者です。私はとても長い期間、個人的に、またビジネスで、XUL/XPCOMベースのFirefoxアドオンやThunderbirdアドオンを開発してきました。
私 は最近アドオンたちをWebExtensionに移行するために必要となるAPIのリサーチを始めました。Mozillaが”XUL/XPCOMベースの アドオンを2017年の終わりまでに廃止する”と告知したからです。私は、いくつかのアドオンが現在使用可能なAPIだけでけしか移行できることに気づきま した。Popup ALT Attribute もそれらのアドオンの中の一つです。
これは私がどのようにWebExtensionに移行させたのかを綴った物語です。
このアドオンについて
Popup ALT Attribute は2002年からスタートしているとても古くからあるアドオンで、これはwebページのimg
HTML要素の alt
属性に書かれている内容を表示するものです。通常、Firefoxはtooltipに title
属性のみ表示します。
最初に、このアドオンはFirefox自身の FillInHTMLTooltip()内部関数を置き換える機能が実装されています。
2016年1月、私はこのアドオンを e10s に対応させました。このことはあなたのアドオンの状態によって価値が変わるでしょう。もしあなたが直接WebExtensionに移行するなら、WebExtensionはデフォルトでe10sに対応しているからです。
WebExtensionスタイルに再フォーマッティング
私は移行する前に、どのように1からWebExtensionベースのシンプルなアドオンを作るかのチュートリアルを読み、WebExtensionはブートストラップ型拡張に似ていることに気が付きました。
- 両者は動的にインストール、再インストールされる
- 両社は主にJavaScriptコードがベースでいくつかの静的なマニフェストファイルを持っている。
私はすでにこのアドオンをbootstrapped型アドオンに移行していたため、容易にWebExtensionに再構成することができました。
これは私が書いた初期のバージョンの manifest.json
です。これはlocalizationやオプション用のUIがありません
<code>{ "manifest_version": 2, "name": "Popup ALT Attribute", "version": "4.0a1", "description": "Popups alternate texts of images or others like NetscapeCommunicator(Navigator) 4.x, and show long descriptions in the multi-row tooltip.", "icons": { "32": "icons/icon.png" }, "applications": { "gecko": { "id": "{61FD08D8-A2CB-46c0-B36D-3F531AC53C12}", "strict_min_version": "48.0a1" } }, "content_scripts": [ { "all_frames": true, "matches": ["<all_urls>"], "js": ["content_scripts/content.js"], "run_at": "document_start" } ] }</code>
私 はすでにmain scriptをフレームスクリプトとloaderに分けていました。一方、 manifest.json
はどのようにロードされたかを述べるための いくつかのマニフェストキーを持ちました。これはパッケージに自作したカスタムloaderを何も追加する必要のないことを示しています。実際、上記のサ ンプルに含まれている content_scripts
ルールによってどんなwebページにもスクリプトをロードすることができます。 content_scripts
の詳細はドキュメントをご覧ください。
そして最後には、3つのファイルにすることができました。
Before:
<code>+ install.rdf + icon.png + [components] + [modules] + [content] + content-utils.js</code>
And after:
<code>+ manifest.json (migrated from install.rdf) + [icons] | + icon.png (moved) + [content_scripts] + content.js (moved and migrated from content-utils.js)</code>
そして、私はまだ、XPCOMから自分のフレームスクリプトを分離する必要があります。
- scriptは
nsIPrefBranch
やXPConnectを通していくつかのXPCOMとつながっています。そのためそれらを一時的にコメントアウトします。 - ユーザープレファレンスは使用不可になり、値を固定し、デフォルト設定のみ使用可能になります。
Ci.nsIDOMNode.ELEMENT_NODE
のように、いくつかの定数のプロパティにアクセスされるXPCOMコンポーネントをNode.ELEMENT_NODE
のような形に置き換えました。webページから mousemove
eventsを取得するリスナーはフレームスクリプトのグローバル名前空間にアタッチされますが、しかしこれはそれぞれのページのdocument自身に
再アタッチされます。なぜなら現在 scriptはwebページで直接実行されるからです。
ローカライズ
xpcomアドオンのinstall.rdfでは、説明をローカライズしていました。webextensionでは異なった方法でローカライズする必要があります。詳細はhow to localize messagesをご覧ください。以下で簡単な説明を行います:
ローカライズした説明を記述するためにファイルを追加します
<code>+ manifest.json + [icons] + [content_scripts] + [_locales] + [en_US] | + messages.json (added) + [ja] + messages.json (added)</code>
en_US
はinstall.rdf
のバージョンのen-US
と異なることに注意してください。
English locale, _locales/en_US/messages.json
です:
<code>{ "name": { "message": "Popup ALT Attribute" }, "description": { "message": "Popups alternate texts of images or others like NetscapeCommunicator(Navigator) 4.x, and show long descriptions in the multi-row tooltip." } }</code>
日本用のlocale, _locales/ja/messages.json
もまた含まれています。そして、manifest.json
をローカライズされた言葉を埋め込むために修正する必要があります。
<code>{ "manifest_version": 2, "name": "__MSG_name__", "version": "4.0a1", "description": "__MSG_description__", "default_locale": "en_US", ...</code>
__MSG_****__
文字列変数は自動的にローカライズされたメッセージに置き換えられます。default_locale
キーを通して、手動でデフォルトロケールを設定することが必要です。
残念ながら、firefox45ではローカライゼーション機能はサポートされていません。そのためlocalizationを行うには Nightly 48.0a1以上のバージョンが必要になります。
ユーザープレファレンス
現在、WebExtensionsはnsIPrefBranch
と互換性 を持っている機能を提供していません。しかし、代わりに、シンプルなストレージAPIを持っています。これはuser preferencesをset/getするための nsIPrefBranch
の代わりに使えます。このアドオンはUIの設定をもっていません。しかし拡 張的な機能をコントロールするためにいくつかのsecret preferencesをもっています。そのため私の他のアドオンの移行のために試験的に挑戦しました。
そして私は大きな壁にぶつかります。ストレージAPIはコンテンツスクリプトでは使用可能ではないのです。私はストレージにアクセスするだけのため にバックグラウンドスクリプトを作成することが必要で、さらに内部サンドボックスメッセージシステムを通してコンテンツスクリプトとコミュニケーションを とる必要があります。(更新情報: bug 1197346はNightly 49.0a1では修正されています。そのためコンテンツスクリプトからストレージシステムにアクセスするようなハックはもう必要ありません。現在、私はネイティブなストレージAPIの代わりに設定値に簡単にアクセスできるようなライブラリ(configs.js)を提供しています。)
最後に私はそれを行うために小さなライブラリを作成しました。私はここでは説明しませんが、もしあなたが詳細を知りたいなら、ソースコードをご覧ください。177行のライブラリがあります。
私は二つのバックグラウンドスクリプトやコンテンツスクリプトを使用するために、自分のmanifest.jsonを更新する必要がありました。
<code> "background": { "scripts": [ "common/Configs.js", /* ライブラリ自身 */ "common/common.js" /* ライブラリを使用するコード */ ] }, "content_scripts": [ { "all_frames": true, "matches": ["<all_urls>"], "js": [ "common/Configs.js", /* ライブラリ自身 */ "common/common.js", /* ライブラリを使用するコード */ "content_scripts/content.js" ], "run_at": "document_start" } ]</code>
同じセクションに記載されているスクリプトはセクションの名前空間を共有しています。他からscriptをロードするためにrequire()のようなも のは必要ありません。代わりに、私は各リストのscriptの並び順に気を付け、ライブラリを必要とするスクリプトが、必要とされるライブラリ自身の後に なるように書く必要があります。
そして最後の障害に当たります。about:cofigやMCDに当たる動作を実現するにはどうすればいいのか・・・一般的な方法はアドオン全体にわたる秘密のプレファレンスを制御することです。
私は仕事の顧客に対し、大抵アドオンを提供して、彼らの設定をロックするためにMCDを使用しま した。(Firefoxをビジネスで使用するためにいくつかの共通の要件があるため、アドオンとMCDの組み合わせは、それぞれの顧客用に異なった設定の Firefoxプライベートビルドを作成するよりもかけるコストが少なくて済みます。)
私はまだこの当たりを探る必要があると考えました。
Options UI
WebExtensions はアドオンに対してオプションページを作成する機能を提供しています。これも同じく、Firefox45ではサポートされていません。そのため現在あなた はNightly 48.0a1を使用する必要があります。前に私が言った通り、このアドオンはコンフィグ用にUIを持ちません。しかし私は勉強用に試してみました。
XUL/XPCOMアドオンでは、<checkbox>
, <textbox>
, <menulist>
や他にもリッチなUI要素が使用可能です。しかしこれらは来年末までに使用不可能になります。なので私は純粋なHTMLとJavascriptベースのカス タム設定用UIを実装する必要がありました。(もしあなたがもっとリッチなUIの要素を必要とするならWebApplication用のライブラリなどが 助けてくれるでしょう。)
このステップで私は2つのライブラリを作成しました。
- A helper to bind configurations to UI elements.
- A helper to apply localized messages to a static HTML.
終わりに
私は自分のPopup ALT AttributeアドオンをXUL/XPCOMからWebExtensionsに移行することに成功しました。現在ここのブランチにありますが、Firefox48が使用可能になってからリリースしようと思っています。
これが私が移行することのできた理由です。
- これがブートストラップ型拡張でした、そのため既にアドオンに破壊的な変更を行う必要がありませんでした。
- このアドオンの中心の実装はシンプルなユーザースクリプトに似ていました。アドオンの中心的な動作は、コンテンツスクリプト中で動作します。そしてこれを行うために、特権を必要としていません。
しかし、これは珍しいケースです。私の他の40以上のアドオンはいくつかの特権を必要とし、コンテンツエリアの外側で動作します。私のアドオンのほとんどは、このような非典型的なアドオンです。
私は複数の新しいAPIをリクエスト、分類、計画などを立てたりすることが必要があります。これは私だけではなく、他のアドオン開発者も同じでしょう。
読んで頂きありがとうございます。
Firefox 48 アドオン互換性情報
[これは Mozilla Add-ons Blog の記事 Add-on Compatibility for Firefox 48 の翻訳です]
Firefox 48 が 8 月 2 日 [日本時間同日深夜] リリース となります。Firefox 48 の変更点でアドオンの互換性に影響を及ぼす可能性のあるものを以下にまとめました。Firefox 48 for Developers により詳しい情報が載っていますので、こちらも併せてご覧ください。
一般
- セカンダリ UI 内の読み込みインジケータが更新されました。あなたのアドオンで
loading_16.png
あるいはloading.png
を使っている場合は、新しいパスとなるchrome://global/skin/icons/loading.png
あるいはchrome://global/skin/icons/loading@2x.png
(HiDPI) を指すようコードを更新してください。 - 開発者ツールのトップレベルメニュー項目が動的に追加されるようになりました (Bug 1258987 も参照)。開発者ツールの UI を変更するオーバーレイ、ブロードキャスターあるいはコマンドを使用している場合、これらの変更がアドオンの互換性に影響する可能性があります。
__defineGetter__
と__defineSetter__
のレガシーなthis
自動補完の挙動が廃止されました。
XPCOM とモジュール
- 廃止予定となっている
newChannel
API がnsIIOService
へ戻されました。あなたのアドオンでnewChannel
、newChannelFromURI
あるいはnewChannelFromURIWithProxyFlags
を使用している場合、これらはすべて廃止予定となっているため、それぞれ末尾に「2」の付いたメソッドへ移行しなければなりません。詳しくはnsIIOService
のドキュメント を参照してください。 DownloadIntegration
モジュールのカスタマイズ用インタフェースが追加されました。これはアドオンがDownloadIntegration
モジュールを拡張できるようにするものですが、一方でモジュールをDownloadIntegration.jsm
から直接インポートしてはいけなくなるということです。nsICertTree.isHostPortOverride()
が削除されました。ViewHelpers.L10N
とMultiL10N
がそれぞれモジュールへ移されました。
新機能
- 一時アドオンの再読み込みが可能となりました。一時アドオンの詳細は Andy のブログ記事 を参照してください。
この一覧に載っていない変更点や間違いを見つけたらコメント欄でお知らせください。もしあなたのアドオンが Firefox 48 で動かなくなった場合は、筆者の方でも調査したいと思います。
AMO に登録されているアドオンの 自動互換性テストと対応バージョンの更新 は数週間以内に行われますので、AMO に Firefox 47 対応のアドオンを登録している方は後日メールをチェックしてみてください。
B2G OS の貢献者募集
この記事は “B2G OS: Call for contributors” の抄訳です。
B2G OS とは何か?
Boot to Gecko (B2G) プロジェクトは、2011 年に、オープン Web のための完全なスタンドアロンのオペレーティングシステムを構築するために開始 [1] されました。B2G は、コミュニティにより維持され、Linux カーネルと Gecko 描画エンジンをベースにしたオープンソースプロジェクトであり、商用の Firefox OS スマートフォンやスマートテレビ製品の基盤として使用されています。
2015 年 12 月に、Mozilla Corporation により、プロジェクトの焦点をスマートフォンから他の形式のコネクテッドデバイス [3] にシフトすることが発表 [2] されました。その時から、B2G を現代化して仮プラットフォームを作り、その上でスマートテレビや他の潜在的なコネクテッドデバイス製品を構築するための移行プロジェクト [4] が水面下で進められてきました。この移行プロジェクトの一環としてボランティアの Mozilla コミュニティが B2G のスマートフォン固有部分の所有権を引き継いだため、Mozilla の従業員は努力を別のところへ向けられるようになりました。
この移行プロジェクトは、Mozilla の古いアプリランタイムを新しい標準ベースの Web アプリに置き換え、コア B2G システムを Firefox Web ブラウザのアーキテクチャに近づけることを目的としており、複雑性と保守コストを減らし、新興の Web 標準をベースにした未来のプラットフォームを作ることを目指しています。
なぜあなたの助けが必要なのか?
オペレーティングシステムの保守は巨大なプロジェクトであり、私たちがスマートフォンのフォームファクタで実行される B2G を維持するには、多くのボランティアのコミュニティが必要とされます。このコミュニティには、OS のビルドやテスト、バグの報告や修正、新機能の開発、新端末への対応、文書化とローカライズ、ただ使ってみる、B2G プロジェクトについて話すなど、多くの貢献する手段があります。
移行プロジェクトでは、コアのシステム機能を動作させたり、スマートフォンアプリを新しいアーキテクチャに対応させたり、変更された部分をすべて文書化することに、いつでも助けが必要です。移行が完了したら、私たちは、B2G の前進を助けるためのより大きな貢献者のコミュニティを構築することを望んでいます。
もしあなたが、完全なスタンドアロンのオープン Web のためのオペレーティングシステムの保守を助ける挑戦に興味があるなら、ぜひご意見を聞かせてください! B2G は、コミュニティのためにコミュニティが作り、あなたの助けを必要とするプロジェクトです。
参加するには
B2G コミュニティには多くの方法で参加できます。メインフォーラム [5]、dev-fxos メーリングリスト [6]、リアルタイムチャットのための #fxos IRC チャンネル [7]、全般的な非公式の議論のための telegram グループ [8] があります。私たちは毎週、Vidyo で公開ミーティング 9. https://wiki.mozilla.org/IRC
を行っています。このミーティングでは、最新ニュースを入手したり、チームの他のメンバーに会ったりできます。
あなたの興味に応じて参加する方法のリストは、MDN サイトの B2G OS のページ [10] をご覧ください。
1. https://wiki.mozilla.org/Booting_to_the_Web
2. https://blog.mozilla.org/blog/2015/12/09/firefox-os-pivot-to-connected-devices/
3. https://wiki.mozilla.org/Connected_Devices
4. https://wiki.mozilla.org/B2G/Transition_Project
5. https://discourse.mozilla-community.org/c/firefox-os-participation
6. https://lists.mozilla.org/listinfo/dev-fxos
7. https://wiki.mozilla.org/IRC
8. https://telegram.me/B2GOS
9. https://wiki.mozilla.org/B2G/Meeting
10. https://developer.mozilla.org/en-US/docs/Mozilla/B2G_OS
JavaScript の並列処理機能を味見してみる
この記事は “A Taste of JavaScript’s New Parallel Primitives” の抄訳です。
まとめ:複数の Worker と共有メモリを利用して、本当の意味で並列アルゴリズムの JavaScript 実装を可能にするために、JavaScript の基本機能を拡張しようとしています。
複数コアを用いた計算
JavaScript (JS) は成熟しました。モダンな Web ページのほとんど全てで、大量の JavaScript が利用され、それらが動作するのは当たり前のことになっています。また JS の適用領域も拡大しています:クライアントサイドでは、Facebook や Lightroom が行っているように画像処理が JavaScript で実装されていますし、Google Docs のようなブラウザで動作するオフィススイートも JS で実装されています。PDF ビューワ(pdf.js)のような Firefox のコンポーネントや言語分類器も JS で実装されるようになっています。それらのうちの幾つかは、C++ コンパイラによって出力される単純化された JavaScript サブセット、asm.js を利用しています。例えば C++ で書かれているゲームエンジンも JS にリコンパイルされ、asm.js のプログラムとしてブラウザ上で動作させられます。
これらに代表される JS の適用範囲の拡大は、パフォーマンスの驚異的な改善によって可能となりました。それは JS エンジンに実装された Just-in-Time(JIT) コンパイラや、より高速な CPU によってもたらされました。
しかし、JIT による実行速度向上のスピードは低下しつつあります。また CPU 速度の改善はほとんど頭打ちになっています。CPU の高速化に代わる手法として利用されているのは、複数の CPU(実際は CPU のコア)の利用です。これは携帯電話からデスクトップにいたるまで広く利用され、ローエンドの環境を除けば、最低でも 2 つ以上の CPU が利用できるようになっています。このような状況でプログラマがプログラムの性能を向上させたいなら、複数のコアの並列利用を選択するでしょう。これは Java、Swift、C#、C++ のようなマルチスレッドプログラミングが可能な言語で書かれたネイティブアプリの話ではありません。Web Worker と、その遅いメッセージパッシング機構、そしてデータコピーの回避手段がほとんどないという、複数の CPU を利用するには極めて制限された機能しか持たない JavaScript での話です。
つまりは JS には問題があるのです:Web 上の JS アプリケーションが、ネイティブに代わる有力な選択肢であり続けるためには、JS を複数 CPU の上で動作させられるような機能を JS に持たせなければなりません。
JS の並列計算:共有メモリ、不可分性、Web Worker
これまでの 1 年程度、Mozilla の JS チームは標準化活動を主導して、並列計算を可能にする機能を JS に加えてつづけてきました。他のブラウザベンダの協力を得て、私たちの提案は JS の標準化プロセスへと進みました。Mozilla の JS エンジンになされたプロトタイプ実装は、並列計算を可能にする機能に関して情報を得るのに役立ちます。また Firefox のいくつかのバージョンでは利用可能です。ここではそれらを利用した実験をおこなっていゆきます。
Extensible Web の精神に基づいて、可能なかぎりプログラムを書かずに利用できる低水準な機能を用意することで、複数の CPU を利用可能にすることを選択しました。用意されたのは、新しい共有メモリ型、共有メモリ上のオブジェクトに対する不可分操作、そして共有メモリ上のオブジェクトを標準的な Web Worker に受け渡す方法です。これらの考えは目新しいものではありません。これらの高レベルな背景と歴史に関しては、Dave Herman のブログポストを参照すると良いでしょう。
SharedArrayBuffer
と呼ばれる新しい共有メモリ型は、ArrayBuffer
とよく似ています。大きな違いは、SharedArrayBuffer
として表現されているメモリは、複数のエージェントによって同時に参照されうる点です(ここでのエージェントとは、Web ページのメインプログラムや、Web Worker のことを指します)。SharedArrayBuffer
は、あるエージェントから他のエージェントへと postMessage
を通じて受け渡されることで共有されます:
let sab = new SharedArrayBuffer(1024) let w = new Worker("...") w.postMessage(sab, [sab]) // Transfer the buffer
Worker は、メッセージから SharedArrayBuffer を取得します:
let mem; onmessage = function (ev) { mem = ev.data; }
上記のプログラムにより、メインプログラムと Worker とが同じメモリを参照するようになります。この状況を図示すると以下のようになります:
共有された SharedArrayBuffer
に対して TypedArray
を作り、そのビューに対して配列操作を行うことで、共有メモリ領域に対するデータの読み書きが可能になります。操作例は以下のようになります:
let ia = new Int32Array(mem); ia[0] = 37;
これでメインプログラムは、Worker によって書き込まれたデータを参照できるようになります。上記の例では、Worker の書き込みが終了していれば、37 を得られます。
この「Worker がデータを書き終わるまで待つ」というのは、メインプログラムにとっては実に難しい問題です。複数のエージェントが同じ領域に対して調整することなく読み書きを行うとすると、その結果は悲惨なことになるでしょう。新しく追加した不可分操作によって、操作が割り込みによって中断することなく、予期した順番で処理されるようになり、上述のような協調動作が可能になります。この不可分操作は、新しく追加されたトップレベルオブジェクトの Atomics
の静的メソッドとして実現されています。
速度と応答性
Web の性能に関して、複数コア計算によって向上が見込まれるものには 2 つあります。それは計算速度と応答性です。前者は単位時間当たりの仕事量であり、後者は計算中のブラウザに対してユーザが可能な操作の範囲です。
仕事を複数の Worker に割り振り、並行に実行すると速度を向上させられます:1 つの計算を 4 つに分割し、それぞれを 4 つの Worker に割り当て、それぞれの Worker に 1 つずつコアを占有させることができたら、計算が 4 倍速くなることが期待されます。また仕事をメインプログラムから Worker へと移動させることで、応答性を向上させられます。これにより計算途中であっても、UI イベントに対してメインプログラムが応答できるようになります。
共有メモリは 2 つの理由から、並列計算の基本要素となりました。データコピーのコストを削減できることが、1 つ目の理由です。描画を複数の Worker に任せていて、その結果をメインプログラムから表示しなくてはならないといった場合、描画されたシーンはメインプログラムに対してコピーされます。このコピーの分だけ描画時間が増加し、メインプログラムの応答性は低下します。処理の調停コストが低いことが、そして postMessage
と比較すると相当低いことが、2 つめの理由です。通信に必要な時間と、エージェントが処理をしないで待っている時間を短縮できます。
良いことだけでなく、悪いこともある
複数の CPU コアを利用することが、簡単でない場合もあります。シングルコアを仮定して作成されたプログラムを複数コアで動作させる場合、大きな変更を余儀なくされる場合がとても多くあります。また変更後のプログラムが正しく動作していることを検証することも難しなります。また Worker 間の調整が頻繁に必要になるようなプログラムは、複数コア利用による計算スピードの向上は難しくなります。すべてのプログラムが並列計算の恩恵を被れるわけではありません。
付け加えるなら、並列プログラムには新しい種類のバグが発生します。プログラムのミスから 2 つの Worker が、お互いの仕事が終わるのを待ってしまった場合、それ以上プログラムが進まなくなります。このような状態をデッドロックと呼びます。複数の Worker が調整なしに同じメモリセルを読み書きした場合、その結果は正しくないものとなるでしょう。このことをデータ競合と呼びます。データ競合のあるプログラムは不正確で、信頼性に欠けるものとなってしまいます。
利用例
注意:以下のデモを実行するためには、Firefox 46 以降が必要です。また Firefox Nightly を利用していない場合は、about:config
で javascript.options.shared_memory
を true
に設定する必要があります。
複数コアを利用して並列に計算してスピードを向上させるために、どのようなプログラムを書けば良いかを見てゆきましょう。例として単純なマンデルブロー集合のアニメーションを利用します。これはピクセルの値をもとにグリッドを計算し、そのグリッドを拡大率を上げながら canvas に描画します。なおマンデルブロー集合の計算は「驚異的並列」として知られています。つまり簡単に高速化が行える種類の計算なのです。他の例ではこれほど簡単には高速化できないのが通常です。また、ここでは技術的に深入りはしません。詳しくは文末にある関連情報を参照してください。
Firefox で共有メモリ機能が標準で利用できないのは、この機能が JS 標準化団体での議論の途中にあるからです。標準化は、その団体のプロセスに則って行われ、その過程で機能が変更されることもあります。そのような API に依存したコードを書きたくはありません。
並列化されていないマンデルブロー集合
最初に全く並列化されていないマンデルブロー集合の計算を見てみましょう。計算はメインプログラムの一部分として実行され、その結果は直接 canvas に描画されます。なおデモは途中で止められますが、後のフレームほど描画が遅くなって行きます。信頼できる結果をえるなら、最後まで実行してください:並列されていないマンデルブロー集合アニメーション
ソースコードはこちらで参照できます:
並列化されたマンデルブロー集合
並列化されたバージョンでは、ピクセルの計算が共有メモリと Worker を利用して並列に行われます。元のプログラムに対する適用は、概念的にはシンプルです:mandelbrot 関数を Web Worker に移します。そして複数の Web Worker を動かし、それぞれの Worker で出力の横一列の計算を担当します。メインプログラムは canvas への描画を担当します:並列化されたマンデルブロー集合アニメーション
使用するコア数とフレームレート(Frame per Second, FPS)との関係をグラフすると、次のようになります。測定に使用したのは、hyperthreading が有効になったコアを搭載した MacBook Pro late-2013 上の Firefox 46.0 です。
1 コアでは 6.9 FPS でしたが、4 コアでは 25.4 FPS へと、プログラムはほぼ線形に高速化しています。その後は新しいコアではなく、すでにプログラムが動作しているコアでの hyperthread 上でプログラムが動作するようになったため、速度の伸びは緩やかになっています。同じコアで動作する hyperthread は、コア上のいくつかのリソースをきょうゆうします。そのためそれらの間での競合が発生しているのではないかと推定されます。それでも hyperthread を追加するたびに、3・4 FPS 高速になり、Worker 数を 8 にした場合は 39.3 FPS となりました。これはシングルコアに比べて 5.7 倍の高速化を達成しています。
この種類の高速化はとても明らかに良い結果になります。一方、並列化されたバージョンは、そうでないものと比べて極めて複雑なものとなっています。この複雑性は様々なものに起因しています:
- 並列化バージョンを正しく動かすためには、Worker とメインプログラムとを同期させる必要があります:メインプログラムは各 Worker に何を計算するべきか伝えなくてはなりません。また各 Worker はメインプログラムに、計算結果をいつ描画するべきかを伝える必要があります。どちらの場合も、
postMessage
を利用してデータが渡されますが、通常は共有メモリを通じて渡したほうが良い(つまり高速)です。正しく、効率的にこれを行うは極めて複雑です - 性能を向上させるためには、各 Worker に対して計算を分割し、ロードバランスを行って効率的に Worker を利用するための戦略が必要です。その結果、例として利用したプログラムでは、出力される画像は Worker の数よりもずっと細かく分割されています
- 共有メモリが整数値のフラットな配列であることも、複雑さを増す要因となっています。共有メモリ上の複雑なデータ構造を手動で管理しなくてはならないためです
同期について考えてみましょう。新しい Atomics
オブジェクトは、wait
と wake
の 2 つのメソッドを持っています。どちらも Worker 間でシグナルを送るために利用できます:ある Worker は Atomics.wait
を呼ぶことで、シグナルが送られてくるのを待ち受けます。そして他の Worker は Atomics.wake
を呼んでシグナルを送れます。これらは柔軟だが低水準の要素です。同期を実現するためには、Atomics.load
や Atomics.store
、Atomics.compareExchange
といった、共有メモリ中の値を読み書きするための機能が必要となるでしょう。
また Web ページのメインスレッドは Atomics.wait を呼ぶことができないことも、複雑さに拍車をかけています。これはメインスレッドを block してしまうのは良くないためですが、Worker 間は Atomics.wait と Atomics.wake を利用して通信を行っているのにも関わらず、メインスレッドを起こすためには postMessage を利用してイベントを送出しなくてはなりません。
これらの機能を試そうと考えているなら、Firefox 46 と Firefox 47 では wait と wake のことを futexWait、futexWake と呼んでいることを知らなくてはいけません。詳しくは MDN の Atomics のページを参照してください。
複雑性の大部分を隠蔽するような良いライブラリをつくることは可能です。またプログラム、通常はプログラムの重要な部分、を複数のコア上で動作させて性能が非常に向上するなら、複雑になっても並列化する意味はあります。それでも並列化は性能を向上させる特効薬ではありません。
上記のディスクレーマーを踏まえた上で、下記の並列化バージョンのコードを参照してください:
より詳しくは
利用可能な API に関しては、提案されている仕様を参照してください。大部分は安定しています。またこの提案を収めた GitHub レポジトリ上での議論も有用です。
また Mozilla Developer Network (MDN) にも SharedArrayBuffer と Atomics に関する文書があります。
Lars T Hansen について
Mozilla の JavaScript コンパイラエンジニア。以前は Adobe で ActionsScript3 の、Opera で JavaScript とブラウザ開発に携わる。
Web サイト:https://github.com/lars-t-hansen
Developer Edition 48 – Firebug 由来の機能、ストレージの編集、インスペクタの改良、etc
この記事は “Developer Edition 48 – Firebug features, editable storage, inspector improvements and more…” の抄訳です。
Firefox Developer Edition 48 がリリースされました。このバージョンでは、Firefox のマルチプロセス化と Firebug の統合のため、Firebug の機能が開発ツールに組み込まれました。これ以外にも小さな変更がありました。それらをまとめてお伝えします。
Firebug テーマ
Firebug 統合の一環として、Firebug のテーマが選択できるようになりました。Firebug を使ってきた方には馴染みある見た目になることと思います。このテーマにはまだ改善の余地がたくさんあります。バグやご要望などありましたら、こちらまでご連絡ください。テーマを利用すると以下のような画面になります:
DOM パネル
Firebug から移植した機能の 2 つ目は DOM パネルです。これはページの DOM の構造を可視化することで、ページの調査を助けてくれる機能です。利用イメージは次のスクリーンショットをご覧ください:
ストレージの編集
ストレージインスペクタに保存内容の編集機能が追加されました。今回のリリースでは、Cookie、ローカルストレージ、そしてセッションストレージの編集と削除が可能になっています。ストレージ中の要素ををダブルクリックすることで、その要素を編集できます。削除はコンテキストメニューから行います。
ジオメトリエディタ
絶対的、もしくは固定的に配置された要素の調整を助ける機能も追加されました。このツールを使うと top、left、bottom、right それぞれの属性値を、その結果を確認しながら編集できます。ジオメトリエディタを利用するには、インスペクタのボックスモデルタブをクリックした後に、 をクリックします。
メモリツールの改善
メモリツールには、ツリーマップ表示が追加されました。このビューでは、メモリの使用状況を素早く、そして直感的に理解できます。オブジェクトを種類に基づいてグループ化され、「canvas 上の線を描いている配列」や「スクリプトのロードが遅い Web サイト」のような、同じような要素のメモリ使用量が確認できるようになっています。また使用されているメモリのバイト数に応じて、それぞれの要素の大きさは決まるため、メモリを多く使用しているものは何か一目でわかるようにもなっています。
総計表示でもオブジェクトの種類ごとにメモリ使用量を表示させられますが、今回のリリースから ⁂ アイコンをクリックしてそれぞれの要素を別のビューで表示できるようになりました。以前のバージョンではGC ルートからの保持パスで表示されていた、それぞれのオブジェクト間の参照関係も表示できます。この機能を使うと、メモリリークの原因となっているオブジェクトをピンポイントで見つけることができます。
スナップショットを個別に削除する機能も追加されました。サイドバーに削除用のボタンが追加されています。
インスペクタの改良
インスペクタも改良され、よりスムーズに、より簡単に使えるようになりました。ルールビューでルールを変更する際に、良く使う属性が自動補完の最初の候補として表示されるようになりました。例えば backface-visibility
ではなく、background
が最初の候補となっています。これにより高速に調整ができるようになります。
また長い値の取り扱い方も改善されました。編集する値を簡単に選択できるようにするため、長い値は複数行で表示されるようになりました。
マークアップビューでは、DOM ツリーの親子関係が強調して表示されるようになりました。選択されている要素の子要素を強調するために、線が引かれるようになりました。これでマークアップが複雑でも、子供の要素が何かがわかりやすくなりました。
角度の単位を切り替える機能も追加されました。色の表示を切り替える機能と同じように、角度の横に表示されているスウォッチをクリックすることで、単位を切り替えて表示できます。この機能は貢献者である Nicolas Chevobbe によって実装されました。
マークアップビューの検索結果を見るためのキーボードショートカットも追加されました。Shift+Enter で 1 つ前の検索結果へとジャンプできます。また Ctrl/Cmd+G と Ctrl/Cmd+Shift+G も追加されました。これは Enter と Shift+Enter と同じ振る舞いをします。このショートカットは Steve Melia によって追加されました。
コンソールの改良
コンソールもいくつかの点で改良されました。いずれも開発を楽しくするものです。最初の改良点は、Firebug の機能移植です。これによって、通信ログを開いて詳細を Firebug のフォーマットで見られるようになりました。
Map や Set オブジェクトを利用している場合、サイドバーで個別の要素を確認できるようになりました。この機能は Jarda Snajdr によって追加されました。
console.clear()
も実装されました。これを呼ぶことで、コンソール出力を消去できます。
about:debugging
WebExtensions のリリースを見据えた機能として、アドオン開発者向けの機能を追加しました。それは about:debugging の画面から、
アドオンの再読み込みです。これを利用すると、アドオンを再インストールすることなく開発を続けることが可能です。
また ServiceWorker を開発する際に有用な、ここのワーカの削除機能も追加されました。
その他の主な変更点
上記以外の変更点の中で、主要なものを以下にあげます:
- ::before と ::after の疑似要素におけるアニメーションがインスペクタで調査できるようになりました (Bug 1206420)
- パンくずリストがインスペクタパネルの下部へ移動しました (Bug 1256422)
- 新しくノードを作成するボタンがインスペクタに追加されました (Bug 1261781)
- デバッグするファイルの切り替えが高速になりました (Bug 1233927)
- ストレージインスペクタで、巨大な値を選択する際の性能が向上しました (Bug 1156720)
- ブレークポイントの表示方法が改善され、よりわかりやすいものとなりました (Bug 1245030)
- タブバーのアイコンが更新されました (Bug 1225184)
- 消去アイコンが更新され (Bug 1251256)、ツールごとに異なっていた表示位置が同じになるよう変更されました (Bug 1220208)
Developer Edition 48 に貢献いただいた皆様に、感謝します!ぜひ最新のものを試して、その感想や考えを共有してください。移植された Firebug の機能面での違いに関する建設的なフィードバックも歓迎します。こちらへまでご提案、コメントをお寄せください。
Tim Nguyen について
Firefox の開発ツールのコントリビュータ。Web 開発と Web デザインに情熱を持つ。
Brian Grinstead について
Firefox の開発ツールを開発するエンジニア。
- Web サイト:briangrinstead.com
- Twitter アカウント:@bgrins