View
1.107
Download
1
Embed Size (px)
DESCRIPTION
taiga.jp
Citation preview
JavaScript 実践講座
Framework, Tool, Performance
taiga.jp Taiga Hirohata
About
Freelance engineer (Flash, Flex, AIR, JavaScript etc)
Principle Classmethod, Inc.
Adobe Community Professional
http://taiga.jp/
@taiga
© 2013 taiga.jp 2 / 54
Practical JavaScript http://tv.adobe.com/watch/max-2013/practical-javascript/
Original
© 2013 taiga.jp 3 / 54
Agenda
Framework
Tools
Performance
© 2013 taiga.jp 4 / 54
当セッションにおける要素
問題 解決策 将来
© 2013 taiga.jp 5 / 54
Frameworks
© 2013 taiga.jp 6 / 54
ブラウザ対応
一貫性のないブラウザ API
Ex : 9 以前の IE は attachEvent() 9 以降は addEventListener() を使用
ブラウザ機能の矛盾
Ex : <input type="data">
© 2013 taiga.jp 7 / 54
JavaScript Libraries
Utility
jQuery(event listeners, XHR, etc.) http://api.jquery.com/category/events/ http://api.jquery.com/Types/#jqXHR
Underscore(collections, etc) http://underscorejs.org/#collections
© 2013 taiga.jp 8 / 54
JavaScript Libraries
Polyfills 古いブラウザでもモダンブラウザと同等の機能を提供
html5shiv / html5shim
selectivizr
es5-shim
Mozilla Developer Network samples
© 2013 taiga.jp 9 / 54
JavaScript Libraries
Feature detection 特徴検出
Moderinizr http://modernizr.com/
YepNope http://yepnopejs.com/
© 2013 taiga.jp 10 / 54
JavaScript Libraries
Ease of library use
Library bundles (HTML5 Boilerplate)
Package managers (Bower)
Scaffolding generators (Yeoman)
© 2013 taiga.jp 11 / 54
非常に積極的にリリースされている
これまで以上に速く近代化している
今まで以上に標準に従っていく
ブラウザの改善
© 2013 taiga.jp 12 / 54
依存関係分かりますか?
本当にすべてのファイル使ってますか?
これらは正しい順序でロードされていますか? <script src="script3.js"></script>
<script src="script1.js"></script>
<script src="script11.js"></script>
<script src="script21.js"></script>
<script src="script30.js"></script>
…
依存関係、スパゲッティ
© 2013 taiga.jp 14 / 54
http://requirejs.org/
Module Pattern
RequireJS Pattern
RequireJS
© 2013 taiga.jp 15 / 54
Logger.js
RequireJS
define(...) { ... function print(msg) {
console.log(msg);
}
// Define public API
exports.print = priint;
});
define(function(require, exports, module) { var Logger = require("pkg/Logger"); function sayHelloWorld() {
Logger.print("Hello, world!");
}
// Define public API
exports.sayHelloWorld = sayHelloWorld;
});
© 2013 taiga.jp 16 / 54
Modules in ES6 Harmony
module "foo" { import "pkgLogger" as Logger; function sayHelloWorld() {
Logger.print("Hello, world!");
}
// Define public API
export sayHelloWorld;
}
© 2013 taiga.jp 17 / 54
非同期プログラムは難しい
コールバックは悪くない …が改善の余地がある
非同期コード
© 2013 taiga.jp 18 / 54
非同期処理完了のリスニング
リスナーにはオブジェクトが返される
Promises
var options = … ; var promise = beginSomeAsyncOperation(options); promise.done(function(result) {
console.log("Operation finishes with result:" + result); }); promise.fail(function(errorCode) {
console.log("Operation failed. Error:" + errorCode); });
© 2013 taiga.jp 19 / 54
内部的に、非同期 API は処理完了後に 遅延オブジェクトを生成して返します
Promises
function beginSomeAsyncOperation(options) { var result = new $.Deffered(); sendNetworkRequest( function(response) {
if(response.error) result.reject(response.error); else result.resolve(response.data); });
return result.promise(); //req still pending here }
© 2013 taiga.jp 20 / 54
「ピラミッド」を回避 Callbacks authenticate(userName, password,
fucntion () { findRecord(itemId,... function(item) {
applyUpdates(item);
saveRecord(item,
function (result) {
indicateSucess();
}
);
}
); }
);
Promise chaining authenticate(userName, password) .then( function() {
return findRecord(itemId);
})
.then( function(item) {
applyUpdates(item);
return saveRecord(item);
})
.then( function(result) {
indicateSucess();
});
© 2013 taiga.jp 21 / 54
ES6 Harmony "yield" Promise chaining
authenticate(userName, password) .then( function() {
return findRecord(itemId);
})
.then( function(item) {
applyUpdates(item);
return saveRecord(item);
})
.then( function(result) {
indicateSucess();
});
ES6 "yield" + task.js spawn(function() {
yield authenticate(userName, password);
var item = yield findRecord(itemId);
applyUpdates(item);
var result = yield saveRecord(item);
indicateSucess();
});
© 2013 taiga.jp 22 / 54
将来は非同期実行のフローを ツールが理解して教えてくれる…はず
より良いデバッギング
© 2013 taiga.jp 23 / 54
手作業によるスパゲッティ化
限定的な UI 更新
$("project-title").text(filename);
$(".dialog .validation-error").toggle(isError);
$(".modal-overlay ul.songs li:eq(" + i + ")").addClass("selected");
dialog.appendChild(document.createElement("div"));
dialog.firstCihld.innerHTML = "<input type='text' value='"
+ htmlEscape(imte.name) + "'>";
$("#help-sidebar .main-content").html(newContent);
© 2013 taiga.jp 24 / 54
View
Underscore
Mustache
Handlebars
Templating & MVC F/W
© 2013 taiga.jp 25 / 54
Model
Backbone
Templating & MVC F/W
© 2013 taiga.jp 26 / 54
Controller
Knockout
Batman
Ember
Angular
Knockback
Templating & MVC F/W
© 2013 taiga.jp 27 / 54
JavaScript F/W Popularity
© 2013 taiga.jp
from GitHub Archive
28 / 54
プレーンなモデルの使用
Ember, Backbone name = model.get("songName");
model.set("rating", 5);
ES5 Getters/Setters
© 2013 taiga.jp 29 / 54
プレーンなモデルの使用
Knockout name = model.songName();
model.rating(5);
ES5 Getters/Setters
© 2013 taiga.jp 30 / 54
プレーンなモデルの使用
Serenade name = model.songName;
model.rating = 5;
ES5 Getters/Setters
© 2013 taiga.jp 31 / 54
Web1.0 アプリは常に C/S 往復
サーバ上のクラッシュ
サーバ上の遅延
モダンアプリはクライアント処理が主流
どのようにクライアント端末上の クラッシュや遅延を知ればよい?
サーバログ
© 2013 taiga.jp 32 / 54
var errors=[]; window.onerror = function(msg, fileUrl, lineNum) { errors.push({msg: msg, file: fileTrl, line: lineNum}); };
setInterval(function() { sendToServer(errors);
errors = [];
}, 5000);
Error Logging
© 2013 taiga.jp 33 / 54
Open bugs in …
WebKit
Chrome
Firefox
フルスタックトレース…?
© 2013 taiga.jp 34 / 54
<html>
<head>
<script>
function onLoad() {
var now = Date.now();
var pageLoadTime = now - pertformance.timing.natigationStart;
sendToServer(pageLoadTime);
}
</script>
</head>
<body onload="onLoad()">
...
Performance APIs
© 2013 taiga.jp 35 / 54
Tools
© 2013 taiga.jp 36 / 54
(![]+[])[+[]]+(![]+[])[+!+[]]+([![]]+[][[]]) [+!+[]+[+[]]]+(![]+[])[+!+[]+!+[]]
シートベルトなし運転
© 2013 taiga.jp 37 / 54
型チェックなし
変数の型が動的に変更可能 凸(゚皿゚メ)
暗黙の型変換
構造化不足
繰り返される決まり文句の表記
シートベルトなし運転
© 2013 taiga.jp 38 / 54
コンパイルなし ≒ IDEの文法チェックなし
Linting は安全性を与える
統合解析 / Linting
© 2013 taiga.jp 39 / 54
統合解析 / Linting
ex :
Brackets Continuous Compilation extension
https://github.com/JoachimK/brackets-continuous-compilation
© 2013 taiga.jp 40 / 54
ヒントを超えた情報
完全にインタラクティブな編集
コンテキスト スニペット
© 2013 taiga.jp 41 / 54
型推論
© 2013 taiga.jp 42 / 54
型推論
© 2013 taiga.jp 43 / 54
型推論
© 2013 taiga.jp 44 / 54
クロスコンパイラ
© 2013 taiga.jp 45 / 54
ソースマップ
© 2013 taiga.jp 46 / 54
履歴デバッグ
振り返りデバッグ
統合的ビュー実行
Code/Test/Debug Cycle 融合
© 2013 taiga.jp 47 / 54
Performance
© 2013 taiga.jp 48 / 54
var start = Date.now(); //... Do do stuff ... var end = Date.now(); console.log((end - start) + "ms"); //CSS style calculation //Layout //Repaint //User sees update->Date.now()==???
評価が難しい
© 2013 taiga.jp 49 / 54
Timeline panel (http://goo.gl/Vim9r)
パフォーマンスツール
© 2013 taiga.jp 50 / 54
Timeline demo (http://goo.gl/1Z7Jp)
パフォーマンスツール
© 2013 taiga.jp 51 / 54
FPS counter (chrome://flags)
パフォーマンスツール
© 2013 taiga.jp 52 / 54
CSS selector profiling
Repaint rectangles
Render layer borders
→ Session Web Dev2
パフォーマンスツール
© 2013 taiga.jp 53 / 54
Resource Timing ページ上の各リソース読み込みタイミング
Async Scroll スクロールのパフォーマンスをテストする
Display Performance フレームレート関連 API
Programmatic APIs
© 2013 taiga.jp 54 / 54