* JavaScriptプログラマのための
全方位的完全武装ガイド
ma.la
----
高度なWebアプリケーション開発にはもちろん、スマートフォンやPC向けのネイティブアプリやサーバーサイドでの利用など、JavaScriptの利用シーンが広がっている一方で、良いJavaScriptプログラマは浮気性であり他の言語を学ぶことを好みます。主にブラウザ上でのUI開発を軸にJavaScriptを学んだ発表者が、JavaScriptの経験が異なる言語、異なる分野でどのように役に立つのか、他の言語で学んだ知識がどのようにJavaScript開発に役に立つのかを語ります。
----
** テーマ
- 自己紹介・UIエンジニアとは何か
- 必修科目としてのJavaScript
- 非同期処理・分散処理のアーキテクチャ
- これから先JavaScriptで出来ることは何か
----
- 1. 自己紹介
----
** 自己紹介
- ma.la
----
- ホムっペ
- http://ma.la/
----
- twitter @bulkneets
- #followmejp
----
** 肩書き
- livedoor
- UIスペシャリスト
----
** 個人的な肩書き
- 最速インターフェース研究会
- 主任研究員
----
** 肩書き重要
- 自分に対するプレッシャー
- そのようにあろうとする意志
----
** livedoor
- 主にJavaScriptが書ける人として入社
- 色々あって退社 / 京都旅行
- 再び入社
----
** 何やってる人か
- 一般的にはプログラマ
- Webアプリケーションエンジニア
- livedoor Readerとか作ってます
----
** 仕事
- JavaScript / Perl
- UI設計と実装
- 負荷分散・高速化
- API設計
- 自社サービスのセキュリティ監査
- etc
----
** 自分の考えるUIエンジニア
- エンジニアの視点でUIデザインが出来る人
- プログラマとデザイナーの中間
- どちらかというとプログラマ寄り
----
** 今の自分
- 必要であればクローラ書いたり
- MySQLチューニングしたり
- メッセージキューサーバー書いたり
----
** 反省
- ずいぶん色々やってきました
- orz
----
** 何でも屋 vs 専門家
- 「何でも屋」としてのUIエンジニア
- プログラミングもできるしデザインも出来る
----
** 何でも屋 vs 専門家
- 「何が出来るのか」を知らないと良いデザインが出来ない
----
** なんでも出来るメリット
- 異なるレイヤーの知識が生かせる
----
** デメリット
- 器用貧乏になりがち
- ほんとはやりたくない仕事振られる
- 例: 障害対応
----
** プログラマとデザイナの境界線
- 狭義のデザインとは
- 見た目? 色合い? 雰囲気?
----
** 広義のデザイン
- Webサービスにおけるデザイン
- サービスの企画自体
- DBスキーマ設計
- 必要なもの全て
----
** なぜUIエンジニアなのか
- CPUやネットワークの高速化に対して
- 人間に対する最適化が不十分
----
** なぜUIエンジニアなのか
- 最も効率の良い箇所を「チューニング」する
- HotSpotの最適化
----
** クライアント側の最適化
- livedoor Reader
- クライアントサイドでの検索
- 画面遷移なしでの継ぎ足しスクロール
- Google AutoPager (Autopagerize, AutoPatchworkの原型)
----
** クライアント側の最適化
- キーボードショートカット
- 先読み Prefetch
- etc.
----
** 直接・間接的な影響
- 良いUIは競争力になる
- 良いUIは伝搬する
- 良いUIは真似される
----
** ジレンマ
- 良いUIが普及しなければならない
- UIが競争力ではなくなることが理想
- 自分の価値を落とすために働く
----
** プログラマの宿命
- 機械にできることは機械にやらせる
- 最終的に自分の仕事が無くなっても良しとする覚悟
----
** 2005年
- Ajax
- サーバーサイド / クライアントサイドの密な連携
----
** なんで今まで出て来なかったの?
- ブラウザの進化?
- Googleがやりはじめたから?
----
** やろうと思えば色々できた
- CGIでJavaScriptのコード動的に作ったり
- iframeを使った差分ロード
- scriptタグの逐次出力によるストリーミング
----
** 境界線に立つ
- 今でこそ概念が理解されているが
- サーバーサイド / クライアントサイド
- 両方の面倒を見れないと作れない
----
** 境界線に立つ
- イメージ:
-- コウモリ・天邪鬼・トリックスター・キメラ
- 一人で何でもやる / 出来るようなひと
- 自宅サーバーで一人でWebサービス作るような人
----
** どんな人が向いているのか
- 友達がいないひと
- 一人で何でも出来るようになる!!
----
** 2011年
- JavaScriptの高速化
- 同じ領域のエンジニアが増えた
-- フロントエンドエンジニア
----
** フロントエンドエンジニア
- 彼らはキメラですか?
-- もしかして: jQueryエンジニア
- 彼らは孤独ですか?
-- もしかして: リア充
----
** フロントエンドエンジニア
- もしJavaScriptしか書けないのなら
- 良いデザインのためにサーバーサイドの知識も必要
- 何が出来るのかを知るために
----
** 最近思うこと
- ボトルネックはどこに?
----
** 昔
- ボトルネックはクライアントサイドだ!!
- もっとこの領域に人が来ないと駄目だ!!
- ちまちまチューニングしててアホか!!!!
----
** 今
- 全部遅い!!
----
** 今
- 全部やらねーと駄目だな
----
** というと
- あまり現実的ではないですが
- あらゆるレイヤにボトルネックの存在
----
** 昔
- JavaScriptしか書けない
- 出来ることをやるしかない
- Perlは10年前レベルだった
----
** 全部ボトルネック
- ハードウェア?
- 言語?
- アルゴリズム?
- データベース?
- 開発速度?
- セキュリティ?
----
** どこに身を置くか
- 複数のレイヤーを理解した上で
- 自分が得意なことをやる
- 楽しいと思うことをやる
- 必要とされることをやる
- 他の人にできないことをやる
----
** 全方位とは
- どうせならオール5を目指す
- 異なる分野の知識は無駄にならない
- 今まで見えなかったものが見えてくる
----
- 自己紹介終わり
----
- 2. 必修教科としてのJavaScript
----
** とりあえず覚えておけという言語
- 昔: C ?
- 今: JavaScript
----
** プログラミング遍歴
- 大体10歳の頃からプログラミングを始める
- N88-BASIC → Perl + JavaScript
----
** なつかしのBASIC
- その場で書いて、その場で実行
- 実行途中で書き換えて、再開
----
** 原始的プログラミング体験
- Try and Error
- インタプリタ言語脳
- 人のソースいじれるのが当たり前
----
** Webへの傾倒
- 低レイヤーに没頭する人
-- バイナリアン・コンピューターサイエンス
- 高レイヤーに行く人
-- CGI・Perl・PHP / お手軽プログラミング
----
** どこに身を置くのか
- ちゃんと勉強してこなかったコンプレックス
- 低レイヤーには低レイヤーの
- 高レイヤーには高レイヤーの
----
** 今プログラミングを始める人に
- JavaScriptをすすめる理由
----
** メリット
- 大抵の環境で最初から入ってる
- ネイティブアプリでも何かとHTML + CSS + JavaScriptは使われる
- 日常の手頃なハックに
- ブラウザの拡張機能やuserscripts
----
** 何でもJavaScriptで出来る?
- できることが増えるようになった
- ネイティブアプリ開発
----
** WebアプリケーションにおけるJavaScript
- 昔: 第二の言語としてのJavaScript
- 今: 必修言語としてのJavaScript
----
** JavaScriptライブラリ
- 手馴れた言語に似せた設計
- Prototype.js / Ruby, Rails
- MochiKit / Python
- dojo / JAVA ?
----
** JavaScript
- prototypeベースのオブジェクト指向
- 標準的な書き方は有る
----
** にもかかわらず
- 著名JSライブラリの多くは
- 「JavaScriptを俺好みにする」実験
----
** jQueryの普及
- jQuery / JavaScriptらしい?
- もはや独自の言語とも言える
----
** サーバーサイドjs
- クライアントサイドとのノウハウの共有
- メリット「覚える言語が一つで済む」
----
** サーバーサイドjs
- デメリット「覚える言語が一つで済む」
----
** フロントエンド → バックエンド
- Ajax / XMLHttpRequest
- イベント駆動 / 状態遷移の管理
- JavaScriptの経験がクローラ開発に役に立ったり
- サーバーサイドでの非同期I/Oの活用
----
** 良いJavaScriptプログラマは
- イベント駆動スタイルのコードに親しみがある
- 無名関数を平然と使う
- クロージャ、高階関数の概念を自然に身につける
----
** JavaScriptを学ぶこと
- お手軽 なのに 奥が深い
- 異なる言語から得られる知見
----
** 第二言語
- Perl / Ruby / PHP / Python ?
- Lisp / Haskell / Erlang / Go ?
----
** JavaScriptで他の言語を学ぶ
- 2005年 関数型言語への傾倒
- beyond.js 奇妙なライブラリ
----
** 浮気相手としてのJavaScript
- 浮気相手ゆえ俺好みに調教されたJavaScriptが
- 大量に存在
- JavaScriptを通じて他言語のエッセンスを学べる
----
** プログラマの成長促進剤
- もちろんJavaScript以外も覚えたほうがいいけど
- JavaScriptの(キモい)ライブラリを読むだけでも
- 他の言語の勉強になる
----
- 必修科目としてのJavaScript
- 終わり
----
- 閑話休題・セキュリティ的なことの話
----
** セキュリティ的なことの話
- WebアプリケーションエンジニアがJavaScriptを学ぶ必要性
- JavaScriptに起因するセキュリティホール
- キリがないのでざっくりと
----
** よくある脆弱性
- JAVAでJavaScriptのコードを生成
- PerlでJavaScriptのコードを生成
- PHPでJavaScriptのコードを生成
- JavaScriptでJavaScriptのコードを生成
----
- これがメタプログラミングか ・・・
----
** JavaScriptのコードを動的に作る
- オススメしない!! でもみんなやってしまう
- みんな間違える
- 他言語に関する知識不足が要因の一つ
----
** JavaScriptのコードを動的に作る
- JavaScriptをちゃんと理解してないと
- 間違える → 危険
----
** JavaScriptのデータだけ出力する
- じゃあJSONにしましょう
- JSONの中に </script>が入ってると
- scriptタグ閉じちゃう!!
----
** JavaScriptのデータだけ出力する 2
- じゃあscriptタグの中に書くのやめましょう!!
- → jsonを出力するだけのAPI
----
- URLに ?.html って付けたらIE6がHTMLとして勘違い・・・
- → XSS
----
-
----
** 複数言語の混在が当たり前
- Webアプリケーションの常
- HTML + CSS + JavaScript
- 異なるコンテクストで解釈される可能性
----
** Webアプリケーションを安全にするには
- とにかく広範な知識が必要
- 覚えておかないといけないことが多すぎる
----
** 最低限覚えて欲しいこと
- js動的生成するな
- 10年速い
----
** ソニーの事例
- store.playstation.comのXSS見つける → Twitterに書く
- たまたま同じタイミングで海外ニュースサイトに取り上げられていたのを知る
- 緊急メンテ + XSS直して再開
----
** ソニーの事例
- onclick="location.href='[query parameter]'"
- 指摘されたパターンのみ修正してる
- JavaScriptに詳しい人であれば、抜け穴がある状態
-- バックスラッシュ通る
----
** そして
- まだ直ってないと書く
- → 関連会社の人からコンタクトが来る
- 再びメンテ突入
- お礼を言われる
----
** その後どうなったか?
- まだメンテ中
----
- 俺のせいみたいで気分よくない・・・
----
- なんか悪いことしましたね・・・
----
** Evernoteの事例
- JavaScript動的生成によるXSS
- 直したよ → 直ってない
----
** Evernoteの事例
- 日本人で使ってる人、そんなにいねーだろと思ってたら結構使ってる人いた・・・
- たまたま来日してたCEOに呼び出される
- 刺身
----
** Evernoteの事例
- 「直りました、もう安全です」と勝手に広報する人
- 実際のところ、その後も3,4回ぐらい継続的にXSS報告
- ※よくあることです
----
** Evernoteの事例
- 1匹いたら10匹はいると思ったほうが
- 美味しい刺身が悪用される可能性を減らす
----
** LastPassの事例
- データベース漏洩したタイミングで色々調査
- ただしハッシュ化されたパスワード
- PHPでJavaScript動的生成
- JSONのcontent-typeがtext/html => HTML混入
----
** はてなの事例
- はてなカラースター(個人的に)
- 飯おごってくれるって
----
** みんな使ってても大丈夫とは限らない
- 見えてる人には見えている穴
- 実装方法自体にリスクがあるケース
- ユーザーが増える → 一度出したら直せない
----
** 修正困難なケース
- 例えば
- iframe埋め込み前提のコンテンツ + クリックジャッキング
- ブログパーツ(第三者提供のスクリプト実行)
----
** 直せばいいだけ?
- 既に普及してる機能とのトレードオフ
- 初期にリスクを評価できていれば・・・
- ブラウザの仕様や、JavaScriptについての知識が必要
----
** 今なんのためにJavaScriptを使うのか
- クライアントサイド技術を使った高速化
- クライアントサイド技術を使った暗号化
----
** Evernoteの場合
- インライン暗号化
- クライアントサイドのJavaScriptで復元
----
** クライアントサイドでの暗号化
- LastPassのパスワード
- Evernoteのパスフレーズ
- JavaScriptが使える前提であれば可能
-- サーバーサイドではパスワードを一切知らない、という実装
----
** クロスドメイン・メッセージパッシング
- ローカルストレージ
- サーバーを介さない通信が可能
----
** 昔
- IE独自仕様: UserData
- サーバーに送られないCookieみたいなもん
- location.hash
- URLの#以降の部分
----
** 今
- HTML5による標準化
- localStorage, postMessage
- サーバーにデータを送らないで実装する
- バッドノウハウ必要なし
----
** UIの改善だけではない
- JavaScriptで出来ること・すべきこと
- サーバーでできないことをやる
- サーバーが信頼できない前提でのAPI設計
----
** これから必要とされるポリシー
- バグがあっても安全にするアプローチ
- Sandbox
----
** これから必要とされるポリシー
- Don't be evil
-- 我々を信用して
- よりも
- If we are evil
-- 悪意があっても、あなたのデータは安全
----
** ぶっちゃけ
- インターネットそんな安全じゃないですよ
----
- セキュリティの話2
- ライブラリレベルでの問題
----
** ライブラリや拡張機能に問題があるケース
- jQuery / jQuery Mobile
- 不適切な設計 / 何回かに分けて書いた
- http://subtech.g.hatena.ne.jp/mala/
----
** 大事なこと
- サーバーサイドでこういうコードあったらマズイでしょ?
- といったことが
- クライアント側では平然と行われている
----
** 例えばJSONP
- JSON with Padding
- コールバック関数を指定したJSONデータ
- 外部URLから取ってきたjavascriptを実行
----
** 例えばJSONP
- サーバーサイドでこういうコードあったらマズイ
- eval( fetch_url( http://... ) )
- ブラウザ上では平然と行われている
----
** jQuery
- CSSセレクタだと思ったらHTML要素作成
- http://ma.la/jquery_xss/
- → 任意のJavaScript実行
- jQuery 1.6.3で修正予定
----
** jQuery
- 仕様じゃね → 驚き最小の原則に反する
----
** UI設計 | API設計に共通の哲学
- フールプルーフとか
- フェイルセーフとか
- ユーザーが何も知らなくても安全にする
- バグがあっても深刻なことが起きないようにする
----
** jQuery Mobile
- 外部ドメインのURLでも読み込んで表示可能だった
- → 任意のJavaScript実行
- 修正されたけど。。
----
** 著名ライブラリの脆弱性
- 検証する人が少ない
- 赤信号みんなでわたってみんな死ぬ
----
- セキュリティの話
- 終わり
----
- 3. Webアプリケーションのための
- 並列・分散処理
- アーキテクチャ
----
** JavaScriptから見たとき
- サーバーサイドで非同期処理は余り普及してない
- 特殊なケースだけ
----
** サーバーサイドから見たとき
- JavaScript シングルプロセス
- 重い処理やらせるとブラウザごと固まるJavaScript
-- UIスレッドの分離 | Web Workers
----
** マルチプロセス
- たくさんプロセス立ち上げる
- 単純にFork
----
** 協調スレッド
- Perl / Coro
- Ruby / Fiber + NeverBlock
- 透過的なI/O多重化 イベント駆動の隠蔽
- コルーチンを利用した1プロセス内の軽量スレッド
----
** メッセージパッシングによる分散処理
- アクターモデル Erlang, Scala
- シェアードナッシング
- CPUコア数に合わせて性能が向上する
----
** メッセージパッシングによる分散処理
- 関数型言語 = 副作用がない
- 「同じ関数」に「同じ引数」を渡せば同じ結果
-- ネットワーク越しの別のノードで動作してても関係ない
- 分散処理の隠蔽が可能
----
** 「協調動作」か「分散」か
- CPUのコア数が増加
- 今後も「シングルプロセス + イベント駆動」の利点はあるのか?
----
** 複数の方式の組み合わせ
- CPUコア数に比例した少数のワーカープロセス + イベント駆動
- Nginxとか
----
** 複数の方式の組み合わせ
- 重い処理だけ別プロセスにやらせる
----
** 考慮すべき項目
- 必要な同時接続数
- 1リクエストあたりの処理時間
-- 処理時間が予想可能かどうか
- 単位時間あたりのリクエスト数
----
** Webアプリケーション本体
- 1つのプロセス内で共有できるリソースの割合がキモ
- 基本的には単純なマルチプロセスが楽
- 殆どの場合、複数リクエストにまたがった協調動作が必要ない
- 共有リソースはデータベースやKVSにある
----
** シングルプロセス + イベント駆動が適したアプリ
- 複数リクエストにまたがって
-「状態を共有すること」に強い意義があるケース
- 共有する情報が
- シリアライズが困難 / 巨大 / 排他制御が困難
- 普通のWebアプリケーションでは、あまりない
----
** シングルプロセス + イベント駆動の問題点
- ブロッキング処理が入ると他のリクエストも処理できない
- 全部非同期I/Oで
- CPU使う処理は別プロセスに
- 気を使うことが多い
----
** じゃあ?使いどころは
- AnyEvent / Coro / Node.js etc
- 目的特化のサーバー / ミドルウェア
----
** シングルプロセス + イベント駆動のメリット
- 今まで出来なかったことが出来る
- 黒魔術 / 継続 in Web Application
----
** Perlの場合
- AnyEvent / Coro の補完関係
- AnyEvent イベントループの抽象化
- Coro コルーチンの実装
----
** AnyEvent → Coro
- AE: イベント駆動 / コールバックスタイル
- Coro: 従来の手続き型スタイル
----
** AnyEvent
- AE::timer 0, 1, sub { ... }
- 発生するイベントに対する関数を記述
----
** Coro
- async で囲むだけ
- async { Coro::Timer::sleep 1; ... }
- 内部的にはAnyEventを多用
- sleepやI/O waitが発生するタイミングで自動的にyield
----
** AnyEvent → Coro
- コーディングスタイルの変化をもたらす
----
** JavaScriptの場合
- 最初からcallbackスタイルのイベント駆動に慣れている
- setTimeout(func, 1000)
- sleep 1000って書きたいか
----
** JavaScriptの場合
- 言語自体に手を入れないと無理
- DSL? CoffeeScript
----
** JavaScriptの場合
- 遅延評価によるcallbackの直列化
- Deffered, Promise
- 内容が未確定のままオブジェクトを引き回す
----
** サーバーサイドjs
- 使ってる?
- あんまり・・・
- Perlでもできるので
----
** サーバーサイドjsの今後
- コールバック地獄
-- 慣れてるで解決?
- シングルプロセス + イベント駆動
-- マルチコア時代にどうする?
----
** シンクロニティ / 共時性
- どの言語でも通る道
- みんな似たようなことを考えている
- 他の言語から学ぶ
- JS独自の事情: 慣れてる
----
** 美しいアーキテクチャはどこに?
- 意識しないで使える 非同期I/O や 分散処理
- そこらへんはディスカッションで
----
- 並列・分散処理アーキテクチャの話
- 終わり
----
- まとめとか
----
** 最適なアーキテクチャの選択とは
- やり方はたくさんある
- 「選択肢」を増やそう
- 「最適解」を選ぼう
----
** マルチコア時代の並列処理、分散処理アーキテクチャ
- コア数が増加、マルチコア、メニーコア
- シングルプロセス内での協調動作を取るか
- 複数サーバーにまたがった分散処理を取るか
- アプリケーションの性質によって最適解が異なる
----
** 協調動作や分散処理を透過的に行う
- 他の言語やライブラリに学ぶ
- 今まで出来なかったことを出来るように
----
** 異なる言語を行き来する
- 複数の言語を行き来しないと
- 安全なコードや
- いい感じのAPIが書けない
----
** UIエンジニア的視点
- クライアントサイドでしかできないことの積極活用
- ユーザーのブラウザですら「使えるCPUの一つ」
- ブラウザが分散コンピューティングのノードの一つ
----
** 良いUI / 速いUI
- まだ充分じゃない
- まだまだ競争力になる
- 競争力にならなくなるまで
----
** クライアントサイドへのシフト
- 強大なサーバーリソースを持たなくても戦える
-- クラウドもいいけど
- 巨大企業による独占やロックインからの回避
- 世の中をハックしやすいように保つ
----
** 以上
- ご清聴ありがとうございました
----
** 宣伝
- livedoorでは
- エンジニア
- デザイナー
- 募集しています