東京Node学園祭2016 アウトラインメモ
東京Node学園祭2016に参加してきたのでメモ
Demystifying JavaScript Engines - Alejandro Oviedo
- a0viedo/demystifying-js-engines: A list of resources about JavaScript engines
- 2006年のJavaScriptエンジン
- インタプリタ
- 遅い
- 最適化しても遅い
- Fortran、Self、Smalltalkの人がより良い方法を考えた
- (Source) -> Parse -> (bytecode) -> executionPhase <-> JIT Compiler
- 何度も実行するコードはJITコンパイラを通すようにした
- プロパティのアクセスの最適化、Hidden Classなど色々な最適化
eval
とtry-catch
が最適化の邪魔になってることがある
- さらに変化して
- execution phase
- <-> unoptimiging compiler (インラインキャッシュとか)
- <-> optimiging compiler
- 何回か実行して、optimizeできるコードとそうでないコードを分別する
- execution phase
- SpiderMonkey
- Interpreter(ParseとExecution) -> JIT <-> Ionmonkey
- Baseline compiler + Ionmonkey
- 数百回動かして super optimize フラグがついたものはIonmonkeyで動く
- bailoutした場合は、FallbackとしてInterpreterじゃなくてJITのコードを使ってる
- Interpreter(ParseとExecution) -> JIT <-> Ionmonkey
- Chakra
- FallbackとしてInterpreterが動く
- V8
- Sourcecode
- -> Ignition
- -> Fullcodegen <- (AST) -> Crankshaft(+ TurboFan)
- V8 JavaScript Engine: Firing up the Ignition Interpreter
- Sourcecode
- JavaScriptCode
- SourceCode
- -> LLInt
- -> Baseline Compiler
- -> DFG Compiler
- -> FTL Compiler
- 今はFTLじゃなくなってる - Introducing the B3 JIT Compiler | WebKit
- SourceCode
- 最適化について
- ループ内で動かない変数はループの外に出す Loop optimization
var sum = 0
for(var i=0; i < 100000; i++){
sum += i
}
- 関数のインライン化
- 関数を呼び出すとコンテキストスイッチが起きる
- なので、関数をインライン化できるとコンテキストスイッチが減って早くなる
var sum = 0;
var fn = () => { return 1; }
for(var i=0; i < 100000; i++){
sum += fn(); // <= インライン化される
}
- Dead code elimination
- ループの中にあっても、外で使ってないものは削除されてしまう
for(var i=0; i < 100000; i++){
1 + 1; // <= 使ってない
}
- GCについて
- Incremental GC
- ちょっとづつやる
- Incremental GC
Debugging Node.js Performance Issues in Production - Thomas Watson
- Thomas watson
- Opbeat
- パフォーマンスモニタリング
- Node.jsアプリのパフォーマンスモニタリングをしてなぜ遅くなったのかを見つける
- プロダクションのアプリをどうやってデバッグするか
- 何が重要か(why production?)
- productionで起きるエラーを見つけるのは難しい
- 開発時と違ってローカルじゃなくてリモートでデバッグするから難しい
- Premature Optimization
- productionに入る前に最適化仕様として間違った部分を最適化してしまうのは危険なところ
- 計測
- パフォーマンスの計測はどうやるか
JSON.parse(req.body)
- 大きなリクエストがきたらJSON parseが遅くなる
console.time
を使うことでシンプルな計測はできる
console.time("json-parse");
JSON.parse(req.body)
console.timeEnd("json-parse");
// json-parse: 154.12ms
- けど、なぜ遅いのかは色々な要因がある
- (Single Threaded)
- CPUをよくつかうコード
- Slow I/O
- Event loopにイベントを突っ込みすぎ
- メモリの使いすぎ
- GC
- Stop the world
- CPU Intensive Code
- Sync I/O
- JSON parase
- RegExp
- Crypto
- Templates
- Demo
- mdb
- 何で動かないのはよくわからないときのデバッグ
- joyent/mdb_v8: postmortem debugging for Node.js and other V8-based programs
- Joyent | MDB and Node.js
--abort_on_uncaught_exception
V8のダンプを出せる- autopsyをつかつと SolarisのVMを動かせるので、そこでmdbをやるのが簡単
サイボウズの開発を支えるKAIZEN文化 - teppeis
- 技術的負債を貯めるデータベースを作った
- 貯めていって時間があるときにやろう
- 貯まるだけでいつまでも減らない
- KAIZEN DAY
- 技術的負債 -> KAIZEN
- リファクタリングだけじゃなくて開発プロセスについても改善
- 一日に終わらないタイプのKAIZENが進まない
- KAIZEN DAYでも割り込みがある
- KAIZEN合宿
- 泊りがけでやる
- 一日で終わらないものもやる
- 終了後にプログラマ以外も呼んで発表会をやった
- KAIZEN
- メインプロダクトで遊びづらい
- B2Bサービス
- サービス停止 = ユーザーの仕事も止まる
- 大規模
- 新しいものを入れにくい
- 短期要件に振り回されることは少ないけど、新規ものが少ない
- B2Bサービス
- 技術的な変遷
- フロントエンドのアンケート
- 3年ぐらいで変化はある
- けど、結果論なので途中ではもっと色々変化ある
- そういう技術的な変化を試す場所が必要
- サイドプロジェクトで試す
- リモートワーク
- テレビ会議をどこでもできるような仕組みが必要
- 振り返り
- 振り返りの振り返り
Keynote
- MS、Apple、Adobe、Oracle
- Webをリプレイスしようとしたけど、失敗
- すべてのソリューションはオープンじゃなかった
- Webはオープン
- Self Project
- architectureはWebとは違うけど、ウェブブラウザで動く
- Public key cryptは使われてる
- CAは信用できないので
seifnode
- cryptographic
- paypal/seifnode
- random(RNG) - 一番大切
- Entropy
- OS、Microphone(音)、Camera
- 強いランダムを作る
- Seif Protocol
- Secure JSON Over TCP
- paypal/seif-protocol: Node.js Implementation of the Seif protocol
- ECC521 as unique = パスワードの代わり
- Seif Handshake
- The Seif Project
Why to Standardize your READMEs - Richard Littauer
- README
- READMEはユーザーへのprotocol
- READMEは一番最初に読む
- ドキュメントよりも大事かも
- READMEを見たときに
- なんて呼ぶの?
- なぜ使うべきなの?
- インストールの仕方
- コントリビューター
- ライセンス
- READMEに必要に必要なもの
- タイトル
- 説明
- インストール
- ロゴ
- バックグランド
- セキュリティ
- API
- などなど
- ドキュメント
- コード見なくても使えるのが100%
- 問題
- いろんなパッケージマネージャー
- npmはパッケージが多い
- READEMEは難しい
- 書くのも難しい
- パースするのも難しい
- Standard
- READMEにもStandard(JS)みたいなものを作ろう
- 考えずに扱えるもの
- Standard README
- A Specification
- A Generator
- A Linter
- A badge
- Example Templete
- RichardLitt/standard-readme: Readme Standard Style
- Require
- Title
- Short Description
- ToC
- Install
- Usage
- Contribute
- License
- Optional
- Badge
- Generator
- Linter
- まだ
- UPTAKE
- Standards.js とかでも使ってる
- Future
- Linter
- ExampleをREPLで試せるようにする
- NLP
- 検索がもっとしやすくなる
- FAQ
- i18n README
- Specなしより簡単にはなる
- Requirementsはどこに?
- i18n README
Vue.js サーバーサイドレンダリング
- Vue.js 2.0
- Progressive Framework
- Virtual DOM
- レンダリングシステム
- ライフサイクル
- テンプレート
- -> AST
- テンプレート言語の部分 = 動的
- テンプレート言語じゃない部分 = 静的なNode
- 静的なNodeを静的なノードツリーを検出する
- レンダリング
- Watcherというものが
render
関数を呼ぶ - render結果をvDOMにしてdiff+patchする
- Watcherというものが
- 仮想ノードツリー
- ダイナミックと静的なノードツリー
- ノードツリーをマージして期待するDOMを生成する
- サーバーサイドレンダリング
- v1は独自のサーバ実装が必要だった
- hydrogenの仕組みとかもなかった
- v2ではvDOMとかあるのでできるようになった
- クライアントとサーバ
- …
React + Reduxを使った大規模商用サービスの開発
- bookingtable.jp
- ウェブ版
- BFF(Backend for Frontend)を用意してやってる
- アプリ版もあるのでそれぞれBFFがある
- React/Reduxのハマりどころ
mapToState
- ハマりどころ
- 画面遷移
- ログインしてない -> ログイン -> replaceState/replaceしないと戻ったときにおかしくなる
- POPならスクロール位置を戻す、PUSHならTOP 0にする
- Stateが集まるまでComonentをレンダリングしない
- loading = true/false をstate管理して
- loading = trueになったときにレンダリングする
- recruit-tech/redux-async-loader: Async data loader for Redux apps.
- iPhoneの画面スワイプでのもどる/すすむ
- 画面スワイプして戻ると一瞬戻る前の画面でてしまう
- 戻って一瞬でてから、表示が更新される
- Monolithic JavaScript
- ビルドすると毎回ファイル変わって再ダウンロードになってしまうのを避けたい
- Before: 一個のjs
- After: webpackJsomp、appX.js、vendor.js
require.ensure
(webpack)とRouterで動的ロード- Hotな画面は scriptタグで事前ロード
- そうでない画面は
require.ensure
で動的ロード - Script Load Error
- webpack 1.xだと
require.ensure
でのエラーが拾えない - 表示 => デプロイ => 遷移仕様とするとエラーになってしまう
- require.ensure error handling · Issue #758 · webpack/webpack
- webpack 1.xだと
- webpackのモジュールID問題
- webpackでmodule一つ一つ idが振られてる
- applyModuleIdsでidを振られてる
- コレの前にidをsortしてあげればidが決まる
- SSR
- checksumで比較して、合ってるならサーバのレンダリング結果を使う
- 一致しない場合は、一度捨ててクライアントでレンダリングする
- サーバサイドの
renderToString
で数百msかかる
- Partial Reandering
- 見えるところだけサーバ、他はクライアントで
- SEOは?
- Google Botsはクライアントサイドレンダリングでもちゃんと認識する
- SSR Cache
- サーバサイドでキャッシュする
- ユーザーの情報を含んでいるとレンダリングできない
- Composite Rendering
- レンダリング方式を動的に切り替える
- 高負荷時はキャッシュを活用するなど
- まとめ
- サーバサイドレンダリングはターンアラウンドタイム的にやらない方がよい
Introducing Now and Next.js - nkzawa
- Now: realtime global deployments
- ZEIT – Next.js
- の話
- Next.js
npm i -D next.js
$(npm bin)/next
# pages/ にコンポーネントを書いていく
- Next.jsは設定必要なし
- Hot ReloadingとかBabelとかそういうのは自動的にやる
- SPA
- 初期表示が遅い
- ページが増えると重くなる
- 解決方法
- サーバサイドレンダリング
- ファイル置くだけでできる
- 【翻訳】リッチなWebアプリケーションのための7つの原則 - from scratch
- コード分割 + 遅延ロード
- ページごとに結合ファイルを生成して分割する
- サーバサイドレンダリング
- CSS
<Link />
- 遅延読み込み + history.pushState
<Head />
<head />
の中身を書ける- next.js/head.js at master · zeit/next.js
- now
- Next.jsをどうやってデプロする
$ npm i -g now
$ now
- nowでの設定
npm start
を定義する
- 特徴
- デプロイするたびに新しいURLを作る
- 古いURLはそのまま残る
- エイリアスを差し替えることで切り替わる
- URLが常に同じアプリの状態表す
- オートスケール
- 自動的にスケールする
- アクセスがない場合は 0 になる
- データの永続化
- オートスケールでインスタンスが消えるのでデータは外部に保存する
- デプロイするたびに新しいURLを作る
- now + micro
- 基本的にHTTPでやり取りするのでlambdaのようにロックインがない
The Evolution of Electron - Cheng Zhao
- 3つの名前を持っている
- ElectronはAtomのために作った
- 5年前
- GitHub CEOが元でCocoaのアプリケーションだった
- AtomのChromium Embbed Frameworkをつかうようになった
- これによりクロスプラットフォームになった
- Atom: Cocoa -> Chromium Embedded Framework -> Atom Shell -> Electron
- Chromium Embedded Framework -> Node-Webkitに移行しようとした
- Atomは結構でかいコードベースだったので、Node.jsのバインでィングに書き換える作業が難航
- 失敗
- node-webkitの改善を続ける -> node-webkitの開発者を雇う = Cheng Zhao
- node-webkitは複数ウィンドウのアプリケーションを扱えなかった
- node-webkitを書き直すこと決意
- Atom-Shellを作ることにした
- node-webkit と atom-shellの違い
- エントリポイントがhtmlとjsが違う
- Chromiumのビルドの問題など
- AtomとAtom-shellはOSSになった
- Atom-Shell -> Electronにリネームされた
- Electron: 37000
- Electron製のアプリは毎日毎日新しいものが公開され、あなたのPCのディスクを食べます
- Electronは個人プロジェクトとして始まったけど、今は外部Contributorが多くなった
- Contributorがいなくなるとプロジェクトが終わる
- Contributorをちゃんとキープするには
- IssueやPull Requestに対してちゃんと反応する
- 開発環境を簡単にセットアップできるようにする
- よりよいコードレビューをできるようにしたり
- リファクタリングをちゃんとやる
- Contributorはそのプロジェクトをちゃんと理解してるわけではないので
Browser is the new server - Gleb Bahmutov
- KENSHO
- Quickly
- CDN
- paralled downloads
- caching
- small image
- などなどできてたけどまだ遅い
- Pivotal Tracker
- リロードしただけなのに数秒かかる
- 開発者ツールを開いて見ると
- 5秒ぐらいJavaScriptの処理に使ってた
HTML = App(DATA)
HTML
とDATA
をキャッシュする
- リロード
- Hydrate Vue Todo
- タイトルはすぐでるけど、内容は一瞬ちらっとする
- ServiceWorker
- そこでServiceWorker
- ブラウザの上で動くProxy
- リクエストをProxyして処理できる
navigator.serviceWorker.register
- Firefox/Chrome/Opera
https
が必須- Androidのモバイルでも既に使える
- ServiceWorkerの中
- オフライン
- ブラウザのアプリはサーバがないと何もできない
- ServiceWorkerの中にサーバを入れる
- サーバをブラウザで
- express.js + middleware を browserifyで変換して、ServiceWorkerの中で動かす
- express service
- bahmutov/express-service: Package ExpressJS server to run inside a ServiceWorker
- オフラインでも動く
- SWのコードはDevToolsのJavaScript無効でも動く
- クライアントサイドのサーバサイドのJavaScript(ServiceWorkerの中のJS)でサーバサイドレンダリングしてる
- 最新のChromeはlinkタグでもServiceWorkerを登録できる
メモ
- 人数が増えたので人口密度高かった
- 会場的に廊下とかで話すスペース場所とかあるとよかったのではと思った
お知らせ欄
JavaScript Primerの書籍版がAmazonで購入できます。
JavaScriptに関する最新情報は週一でJSer.infoを更新しています。
GitHub Sponsorsでの支援を募集しています。