コンテンツへ移動

GoではじめるWebAssebmly その2「JavaScriptイベントハンドリング」

WebAssebmlyはWebブラウザ上でバイナリファイル(テキスト形式もあり)を実行できる環境です。JavaScriptと異なりコードの漏洩がなく、実行速度も高速というのがメリットです。

WebAssebmlyは元々Rustで開発することが多かったですが、最近では様々なプログラミング言語が対応しています。その一つがGoです。Go 1.11からWebAssembly向けにもコンパイルできるようになっています。

一般的なWebAssemblyはDOMやネットワーク操作が行えません。それに対してGo 1.11ではJavaScript APIを使えるようにした syscall/js パッケージを用いることで、DOMやネットワーク操作を可能にしています。

そこで今回はDOMのクリックイベントをWebAssemblyで扱う方法を紹介します。

まずGoのコードです。今回はmain.goとしています。最初に syscall/js をインポートします。

そして、トップレベルのDOMであるドキュメントを作成します。

IDやクラスを使ってDOMを取得します。

取得したボタンに対してコールバックを指定します。

ボタンのクリックイベントにコールバックを指定します。

最後にプログラムが終了しないようにチャネルを待ち受けます。

これで完成です。全体のコードは次のようになります。

HTMLを準備する

HTMLはボタンを貼り付けだけのものです。

JavaScriptファイルを用意する

専用のJavaScriptファイルを設置します。

Goをコンパイルする

最後にGoファイルをコンパイルして WebAssebmly化します。

サーバを立ち上げる

Webサーバは goexec を用います。インストールは go get -u github.com/shurcooL/goexec になります。インストールされたら以下のコマンドでHTTPサーバを立ち上げます。

これで http://localhost:8080/ でアクセスできます。

試す

では実際に試しているところです。ボタンをクリックすると開発者ツールのコンソールにログが出力されます。

このようにしてGoのコードからイベントハンドリングができます。


Goを使うことでWebアプリケーションをまるっとWebAssemblyで提供できる可能性が出てきました。高速、かつコードの隠蔽化も実現しますのでWebアプリケーションの可能性を飛躍的に向上できるでしょう。

ぜひトライしてみてください。

GoではじめるWebAssebmly その1「Hello World」

WebAssebmlyはWebブラウザ上でバイナリファイル(テキスト形式もあり)を実行できる環境です。JavaScriptと異なりコードの漏洩がなく、実行速度も高速というのがメリットです。

WebAssebmlyは元々Rustで開発することが多かったですが、最近では様々なプログラミング言語が対応しています。その一つがGoです。Go 1.11からWebAssembly向けにもコンパイルできるようになっています。

この記事ではWebAssembly · golang/go Wikiに沿ってGoでWebAssemblyを実行するまでを紹介します。

環境

WebAssebmlyはモダンなWebブラウザが対応していますが、Goが提供するJavaScriptコードがSafariでは動きませんでした。以下はGoogle Chromeで試しています。

Goのコード

今回はとてもシンプルなコードです。 main.go として作成します。

このコードをGoでコンパイルします。

これで main.wasm というファイルが作成されます。

HTMLについて

HTMLはテンプレートになっており、以下を使います。

JavaScriptについて

WebAssebmlyを解釈するのにGoが提供しているJavaScriptライブラリを使います。

この3つのファイルで実行します。

goexecのインストール

HTTPサーバを立てる必要があるので、goexecをインストールします。

これで準備完了です。

実行する

HTTPサーバを立てます。

http://localhost:8080/ でHTTPサーバが立ち上がるので、Google Chromeからアクセスします。

開発者ツールのコンソールに Hello, WebAssembly! と出力されれば完成です。


GoでWebAssemblyを書く場合、特別なテクニックが必要という訳ではありません。普段のGoの書き方で、コンパイル方法を指定するだけです。Goであれば、よりモダンな書き方でWebAssemblyが使えるようになりますのでお勧めです。

PWAでWeb APIを使う際の注意点

Webアプリにおいて、Web APIを使わないことはほぼ皆無でしょう。PWAにおいてももちろん同じようにWeb APIを使って実装されるでしょう。しかし、幾つかのハマりどころがあるので注意が必要です。

キャッシュ時にはヘッダー情報などが使われない

キャッシュは以下のようなフォーマットで実装されます。

 

単純にURLをキーとして、そのレスポンスを登録するだけなので、Web APIアクセスする際にヘッダー情報を追加したり、細かなカスタマイズができません。そこで、ネットワークが使える際にコンテンツをWebブラウザ側で取得し、その結果をService Workerで登録します。

例えばレスポンスが req 、結果が body という変数であったならば、以下のように Service Workerを呼び出します。

 

 

そしてService Worker側でコンテンツを保存します。Responseオブジェクトを使ってレスポンスを動的に作るのがコツです。Webブラウザ側のResponseオブジェクトをそのまま渡せないので注意してください。

 

 

 

こうすると、該当URLへのアクセスすると、ヘッダー情報を無視して結果が取得できます。HTTPメソッドも無視されるので注意してください。

ただし、この方法だとオンライン時のキャッシュの更新が必要で複雑になりすぎる可能性があったり、検索のようにクエリーが動的に変わる場合に対応できないでしょう。

navigator.onLineを使う

もう一つはnavigator.onLineを使って、オンラインの場合はWeb APIを呼び出して、オフラインの場合は自作のキャッシュを使う方法があります。キャッシュはネットワークアクセスの結果をlocalStorageやIndexedDBに保存すれば良いでしょう。

この方法の場合はオンライン、オフライン時の条件分岐が増えてしまう問題があります。できればクラスでラッピングし、アプリケーションからはネットワークの状態を気にせずに利用できるようにするのが良いでしょう。

この方法の利点はHTTPメソッドごとの処理を細かく制御できることで、同じURLになりがちな一覧の取得とデータ作成(GET / と POST /)を分けられることです。


PWAにおいてはネットワークの状態をきちんと制御するのが肝になるでしょう。それによってユーザ体験が大きく変わってきます。ユーザが不自然に感じたり、使いづらいと感じないシステムを作るためにも、キャッシュを上手に活用しましょう。

複雑なService Workerを作る際にはimportScriptsを使おう

Service WorkerはWebブラウザ側で実行されるJavaScript(メインスレッド)とは別で実行されます。バックグラウンド処理に使うこともできますし、メインスレッドで行うと画面が固まってしまうような重たい処理を実行させることもできます。

そんなService Workerを活用していく中で、処理が肥大化していくならば別ファイルとして切り出していきましょう。その際に使えるのがimportScriptsです。

importScriptsの使い方

例えばメインスレッド側のJavaScriptでは次のように処理を書きます。

そしてService Worker(sw.js)を以下のように記述します。

self.importScripts という書き方もありますが、どちらも同じ意味です。 import.js は以下のように記述します。

こうすることで、外部ファイルを読み込んでService Workerの中で利用できます。なお、複数ファイルの読み込みも可能です。

読み込みは同期処理

コードを見て分かる通り、importScripts は同期処理で実行されます。読み込み完了時のコールバックもなく、返り値がPromiseな訳でもありません。さらに言えば、インポートされるファイルで最後に return を書いたり、moduleexport は使えません。

読み込まれるファイルの特徴

インポートされるファイルは元ファイルと同じく self が使えます。これは ServiceWorkerGlobalScope であり、IndexedDB も利用可能です。また、インポートされるファイルを編集しても、元になるService Workerファイルが更新されていないとWebブラウザは更新してくれませんので注意してください。


importScriptsを使うことで、メインスレッドとワーカースレッドで同じライブラリを活用できるようになるでしょう。特に重たい計算処理の伴うようなものについては、ワーカースレッドで計算して結果だけメインスレッドで受け取って描画するといった使い分けもできそうです。

Pitalium ExplorerをDockerで動かす

先日Pitaliumがmavenに登録されたことで使い始める敷居がぐっと下がりました。そこで前回はPitaliumがMaven対応したのでDockerと組み合わせて使ってみる | hifive開発者ブログとして、PitaliumをDockerベースで試す方法を紹介しました。

Pitaliumの動作自体はDockerで完結しますが、その結果ファイルを確認するPitalium Explorerはこのままでは使えません。Pitalium ExplorerのためにJavaやTomcatをセットアップするのは面倒ははずです。そこでDockerを使ってPitalium Explorerを簡単に試せるようにしましょう。

Dockerfileについて

最初に答えを書いてしまうと次のようになります。

ベースになるのはlibrary/tomcat – Docker Hubです。公式イメージなので安心です。そしてDockerの中でPitaliumのZipファイルをダウンロードして展開、その中にあるPitalium Explorerのwarファイルを展開して設定ファイルを書き換えます。それをTomcatのwebappsフォルダに配置します。

ビルド

Dockerfileをダウンロードしたら、ビルドを実行します。

$ docker build . -t pitalium-explorer:latest

これで完了です。

使い方

Pitalimの結果ファイルがあるresultsフォルダと同じ階層に移動してDockerを実行します。

$ docker run -it --rm -p 8888:8080 -v $PWD/results:/usr/results pitalium-explorer

これで results フォルダがDockerコンテナの/usr/resultsに配置されます。このディレクトリはPitaliumの設定ファイルで指定しています。

Webブラウザで http://localhost:8080 を開くとPitalium Explorerの画面が表示されるはずです。

Pitalium Explorer

結果の確認も特に問題なく行えるでしょう。

Pitalium Explorerの結果確認


Dockerを使っていますのでローカルの環境を汚すことなくセットアップが行えます。PitaliumをDockerで使う際には、ぜひこの方法でPitalium ExplorerもDocker化して使ってみてください!

Pitalium(hifiveリグレッションテストライブラリ) – hifive

Web Componentsを使いやすくするためのライブラリまとめ

まだ今ひとつ流行りきらないですが、Web Componentsは今後のWebにおいて広まっていく技術の一つです。コンポーネント化することで再利用性を高めるのはもちろん、各コンポーネントの独立性が高くなることでデザインの影響範囲を限定したり、公開されているWeb Componentsを利用しやすくなります。

今回はWeb Componentsを使いやすくするためのライブラリを紹介します。

Stencil

Stencil

StencilはIonicによって開発されています。TypeScriptとJSXを組み合わせているのが特徴になります。ブラウザはIE11からサポートしています。以下のようなTypeScriptを書きます。

import { Component, Prop } from '@stencil/core';

@Component({
  tag: 'my-first-component',
  styleUrl: 'my-first-component.scss'
})
export class MyComponent {

  // Indicate that name should be a public property on the component
  @Prop() name: string;

  render() {
    return (
      <p>
        My name is {this.name}
      </p>
    );
  }
}

そして利用する際のタグは以下のようになります。

<my-first-component name="Max"></my-first-component>

Stencil

MUI

MUI

Googleのマテリアルデザインガイドラインに沿ったCSSフレームワークです。React/Angular/Web Componentsに対応しています。例えばボタンは以下のようなタグになります。

<mui-btn color="primary">Button</mui-btn>

MUI – Material Design WebComponents Framework

Bosonic Web Component

Bosonic

ダイアログやドロップダウン、タブ、ツールチップなど様々なUIコンポーネントをWeb Componentsとして提供しています。実用性の高いコンポーネント集となっています。

Bosonic Web Component

Polymer Project

Polymer

Polymerを使うとShadow DOMやマテリアルデザインを使ったWeb Componentsを手軽に使えるようになります。 Polymer.Element を継承して作ることで、Web Componentsを用いた処理が書きやすくなるようです。

Welcome – Polymer Project

SkateJS

SkateJS

PreactやReact、LitHTMLなどと組み合わせて使えるライブラリになります。コード例は以下のようになります。

import { props, withComponent } from 'skatejs';
import withPreact from '@skatejs/renderer-preact';
import { h } from 'preact';

class WithPreact extends withComponent(withPreact()) {
  static get props() {
    return {
      name: props.string
    };
  }
  render({ name }) {
    return <span>Hello, {name}!</span>;
  }
}

customElements.define('with-preact', WithPreact);

skatejs/skatejs: SkateJS is a web component library designed to give you an augmentation of the web component specs focusing on a functional rendering pipeline, clean property / attribute semantics and a small footprint.

X-Tag

X-Tag

Microsoft社がサポートするWeb Componentsライブラリです。Web Components APIに準拠して使えます。タグをラッピングすることでイベントハンドリングやフラグメント作成なども行えるようになります。

X-Tag – Web Components


Web ComponentsはUIフレームワークでは使われ始めていますが、個々の部品というレベルにおいて提供されることは希なようです。使えるWebブラウザは広まっていますが、レガシーなブラウザへの対応で躊躇してしまうことが多いでしょう。そうした点において、Web Componentsライブラリを採用すれば、IE9あたりから対応できるようになります。

また、素のWeb Componentsでは良い書き方が分かりづらいかも知れません。ライブラリの提示する方法に則っておくことで利用しやすいWeb Compnentsが書けるようになるでしょう。

Webブラウザ上でディープラーニングを体験できるライブラリまとめ

ディープラーニングというと計算量が多く、GPUを使って動作するイメージがあります。WebブラウザにはWebGPLがあり、そこではGPUが使えます。それもあって、Webブラウザ上で使えるディープラーニングライブラリが増えてきました。今回はそれらをまとめて紹介します。

TensorFlow.js

Googleの開発するTensorFlowをWebブラウザ上で実行できるようにしたライブラリです。TensorFlowで作られたモデルを動かすこともできます。

TensorFlow.js

sukiyaki

東京大学内で開発されているディープラーニングライブラリです。サンプルとして手書き認識のデモが公開されています。

mil-tokyo/sukiyaki: Deep Learning Library for JavaScript

Keras.js

KerasのモデルをWebブラウザ上で動かせるようにしたライブラリです。

Keras.js – Run Keras models in the browser

Synaptic

SynapticはJavaScript向けのディープラーニングライブラリで、Node.jsで学習させてWebブラウザ上で利用すると言ったことができます。

cazala/synaptic: architecture-free neural network library for node.js and the browser

WebDNN

Tensorflow、Chainerなどに対応したディープラーニングライブラリです。Keras.jsよりも高速に動作するとしています。

MIL WebDNN

ml5js

TensorFlow.jsをラッピングして、より手軽に使いやすくしたライブラリです。芸術家や学生、クリエイティブな人たちを対象としており、プログラミング能力をそれほど必要とせずに使えるようです。

ml5js · Friendly Machine Learning For The Web.


Webブラウザ上で学習して実行するというのはあまり現実的ではないでしょう。TensorFlowなどであらかじめ学習しておき、そのモデルを利用するのが理想的です。モデルデータがあまり大きいのもまた現実的ではないので、リソースを使いすぎずに使える範囲での利用が求められるでしょう。