3. Webとなめらかなインタフェース
次世代Webプラットフォーム論
増井俊之
慶應義塾大学 環境情報学部
masui@pitecan.com
2019年10月7日
Scrapboxで自炊本を読む実験中
なめらかなインタフェースとは
直接的
可逆的
連続的
直感的
直接操作インタフェース
“Direct Manipulation”の訳
Ben Shneiderman氏
Ben Shneiderman
University of Maryland
高名なユーザインタフェース研究者/啓蒙家
http://masui.org/23a7bab8adfcf991a4df9bf69d0b1711.png
Shneiderman氏のUI教科書
https://www.amazon.co.jp/dp/013438038X https://gyazo.com/860a375b9adc72c3a29d7609998c9153
http://amazon.co.jp/dp/0321537351 http://masui.org/a9d600e21b1814d54f2305be49ce90cc.png
直接操作の例
スライダ
スクロールバー
ウィンドウのドラッグ
動的検索
(Drag & Drop)
動的検索
“Dynamic Query”
これもBen Shneidermanの造語
検索条件を変化させるとすぐに検索結果も変化
e.g. インクリメンタル検索
インクリメンタル検索
文字を入力するたびに検索を行ない結果を表示
文字を削除すると前の位置に戻る
Demo: Emacsのインクリメンタル検索
Demo: 乗換案内のインクリメンタル検索
Demo: ブラウザのインクリメンタル検索
直接操作でないもの
ウィンドウの開閉
突然ウィンドウが消える
ブラウザのリンククリック
突然違うページが出る
メニューによるコマンド選択
ジャンプする方法と戻る方法が異なる
実世界のインタフェース
大抵の操作はなめらかである
水道の蛇口
車のハンドル
ネジ
スイッチ
...
例: なめらかなインタフェース
WING
LensBar
Demo: WING
Demo: LensBar
https://gyazo.com/b74441574d4e34c4bbd18017c52d71fc http://masui.org/i
なめらかなインタフェースの特徴
直接的
連続的
可逆的
ユーザ操作に対してすぐ反応が必要
Webで多い操作
ナビゲーション
Googleなどの検索
⇒ ページ移動が発生する!
ページ移動の何が駄目か
時間がかかる
突然何が起こったのかわからない
ハイパーテキストの迷子問題
自分がどこにいるのかわからなくなる
大きな問題だと思われていた
実はそれほど問題ではなかったかも
Backボタンのおかげ
ブラウザの基本動作
1. ユーザが何らかの操作を行なう
2. サーバに要求を送る
3. サーバからの返事を受け取る
4. 受け取ったデータを新しいページとして表示
ブラウザとWebサーバの通信
http://masui.org/4fe5e73511ea1909e61e437e06a50056.png
問題になるところ
サーバの返事でページ表示が更新される
ユーザが操作しない限り何も起こらない
直接操作がほとんど不可能
Webのインタフェース
ページ移動はなめらかではない
クリックによるページ移動
検索実行によるページ移動
メニュー選択によるページ移動
Backボタンによりなんとか可逆性を確保
ブラウザで最も多用されるボタン
リッチインターネットアプリケーション (RIA)
普通のアプリケーションのようなGUIをブラウザ上で実現
なめらかなインタフェースも実現
最近はこれがとても多い
というかこれが常識
RIAの要件
ユーザの入力は常に受け付ける
画面を適宜更新する
サーバとの通信時に画面更新を行なわない
必要に応じて裏側でサーバと通信
なめらかなインタフェース
Web上でなめらかなインタフェースを実現する方法
似たページを利用して遷移する
ページを動的に書き換える
プラグインを利用
似たページを利用して遷移する
たとえばこのページ
似たページを利用して遷移する
たとえばこのページ
e.g. ディスク容量視覚化
http://gyazo.com/a431385b0e8493d92414f753f401f8be.png
ページ内容の一部を動的に書き換える
JavaScriptでHTMLを書き換える
DOMを書き換え (jQueryなど利用)
Virtual DOM (React)
クリックで同じページ内に遷移
「アンカー」を利用
ソース
code:html
<body>
<a href="#link1">リンク1にジャンプ</a>
<a href="#link2">リンク2にジャンプ</a><p>
<img src="../../gyazo/64855089b9daa7895fbe425636c3ead7.png"><p>
<a name="link1">リンク1</a><p>
<img src="../../gyazo/c151b36a2eeb9bb66f1b7ffd49cc9219.png"><p>
<a name="link2">リンク2</a><p>
<img src="../../gyazo/4b2727cf2de661d4ab2ad5f07dc762f3.png"><p>
<img src="../../gyazo/6ba052c2a1dc2cee67b2a3feb33cedc4.png"><p>
<img src="../../gyazo/f56f996b1f21cc6d245c21c2e2015cd4.png"><p>
</body>
ページ内移動時のURL指定
URL内の「#」を利用
ページ内操作に対応してURLを変える
場所移動するとURLが変化
JSで内容書き換え
ソース
code:javascript
addEventListener('mousemove', mousemove, true);
function mousemove(event){
var el = document.getElementById('number');
el.innerHTML = event.pageX;
</script>
<center>
マウスのX座標は<span id="number">0</span>です。
</center>
LensBarのJavaScriptでの実装
http://masui.org/i http://i.gyazo.com/833001a09ebc5ac6d9d4699ebe98c8d1.png
データはJavaScriptの配列
なめらかなインタフェースの実現
できる限りJavaScriptでアプリをすべて書く
必要なとき裏でサーバと通信
SPA
Singe Page Appication
ひとつのページですべての動作を行なう
JavaScriptのみ利用
Ajax
Asynchronous JAvaScript + XML
JavaScriptを最大限に利用
ユーザ操作取得
HTML書き換え
サーバと非同期XML通信
必要なければ通信やXMLは不要
最近はJSONを使うのが普通
AJAX
https://gyazo.com/fdf8ce76ac0be4b1b75d7e88fbe4c9da.png
非同期通信とは
何かの完了を待たずに通信を行なう
ユーザ操作を待たない
サーバの計算終了を待たない
ユーザの待ち時間を最小化
同期通信
ユーザとシステムが交互に情報をやりとり
コマンドシェル
電卓
HTTPは同期通信
インタフェースと並列性
インタフェースに並列性は必須
システムの反応とユーザ操作
音声とキーボード
突然発生するエラー
複数ユーザ
非同期通信により並列性が生じる
半二重通信 = 極端な同期通信
常に1方向の通信
データのやりとりは交替で行なう
昔の大型機の端末
システムの仕事中は入力できない
大きなリセットキーというものがある
激しく使いにくい!
大型計算機のキーボード
https://gyazo.com/b8ae4735ce94e8abdecc5f1364ef34a3.png
現在の端末
全二重通信
常にユーザは入力可能
先行入力可能
処理は順番に行なわれる
全二重通信
複線の電車のようなもの
半二重は単線
最低限の並列プログラミングが必要
e.g. ターミナルエミュレータ
ユーザ入力とシステム出力を両方監視
Ajaxの原理
JavaScriptの非同期呼び出し機能を利用
XMLHttpRequest()
サーバに要求を送った後すぐに終了する
データが得られるとコールバック関数が呼ばれる
データが得られるまで終了しないようにすることも可能<br> (この場合は同期通信になる)
返ってきたデータを利用して画面書き換えなどを行なう
簡単なAjaxの例
画像の位置をサーバに記憶
mouseMoveイベントで画像をドラッグ
mouseUpイベントで新しい位置をサーバにセーブ
ここでXMLHttpRequest()呼ぶ
非同期的にサーバに画像位置を通知
code:javascript
function sendposition(el) {
// CGI呼び出し
xmlhttp.open("GET", "setpos.cgi?image=" + el +
"&x=" + getLEFT(el) + "&y=" + getTOP(el),true);
// 完了時のコールバック定義
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4) {
dummy = xmlhttp.responseText
}
}
xmlhttp.send(null)
複雑なAjaxの例
Google系サービス
GoogleMaps
GMail
Ajaxを簡単に扱う
ライブラリを利用
jQueryなど
Ajaxの問題点
非同期通信プログラミングはわかりにくい
並列プログラミングは難しい
異常動作が起こりやすい
ネット上では例外が発生しやすい
ブラウザによってJavaScriptの仕様がかなり違う
if(IE)...
if(Mozilla)...
プラグインを利用する
Flashプラグイン
Javaアプレット
プラグインによるなめらかなインタフェース
プラグイン内は普通のアプリケーションのように動作可能
Java, Flash等のイベントモデル、表示モデル
ローカルファイルを扱うことはできない
データやりとりが必要な場合はサーバとの通信が必要
Flashによるなめらかなインタフェース
マウスやキーボードはActionScriptで処理
URLLoader() などの関数でサーバと通信
非同期処理可能
Demo: Flash版LensBar
Demo: Canvas版LensBar
サーバからの非同期データ受信
ユーザが何かを行なわないとサーバはデータを返さない
サーバから突然送られてきたデータは処理できない
非同期的にデータを受け取る方法が必要
例: チャットシステム
いつ相手からデータが送られてくるかわからない
ブラウザが常にデータ待ち状態になっている必要がある
受け取ったデータはJavaScriptで処理
Comet
ブラウザをサーバのデータ待ち状態にしておく
サーバはデータを返さない
ブラウザとサーバが接続中の状態が続く
準備できたらデータを返す
サーバの実装
普通のWebサーバは使えない
同時接続できるクライアント数の制限
解決法
特殊プロキシを利用
Comet専用サーバを利用
Nginxのような新しいサーバを利用
AJAXとComet
https://gyazo.com/fdf8ce76ac0be4b1b75d7e88fbe4c9da.png
https://i.gyazo.com/8ec3aa8e75a2916dd28fd1a1765060a1.png
WebSocket
Web上の汎用通信
HTTPを利用しない
自由なサーバ/ブラウザ間通信可能
2011年12月 RFC6455 proposed standard
現在ほとんどのブラウザで利用可能
Node.jsを使う実装が人気
Socket.io
WebSocketを利用
サーバ上のNode.js
ブラウザ上のクライアントJavaScript
socket.on(event,callback);
サーバでもブラウザでも同じ記述
様々なイベントを利用可能
WebSocketの制限
古いサーバ(e.g. Apache)で利用し辛い
新しいサーバ(e.g. nginx)なら大丈夫
React.js
最近人気のJavaScriptライブラリ
FacebookのUI
「コンポーネント」を並べて画面を生成
なめらかな画面遷移が可能
MagicTV
React.js + Electron
まとめ
ブラウザのJSでなめらかなインタフェースが実現可能
ブラウザとサーバで役割分担
使いやすさは大きく改善
しかしプログラミングは苦痛
素直なプログラミングができない
jQuery, Reactなどを使うと多少楽になる
Node.js, WebSocket, nginxなどの動向に注目必要