別のIssueにした方がいい? - 分けた方がいいですね。
Maybe worth queuing this as another issue / pull request?
Yes, fitting for a separate issue / pull request.
一つのpull requestに複数の変更を混ぜるのは微妙なので、別のpull requestで追加した方がいいかを聞くケース。
9 anti-patterns for node.js teams
9 anti-patterns for node.js teams
9 anti-patterns for node.js teamsでは node.jsにおける9つのアンチパターンを紹介しています。
Baggage from your previous technology
過去の技術は置いてnodeに向きあおう。
Monolithic applications
モノリシックなアプリにするな。 一つの共有モジュールではなく、それぞれのモジュールで構成しよう。
Googling "How to do x in JavaScript"
"JavaScript"でどうやるのかについてググるな。 検索結果はjQueryが多く含まれるので、まずはES5を理解しよう。
Handling error
文字列じゃなくてエラーオブジェクトを使おう。 Programmer errorsに対してはthrowしよう
エラーを無視しないようにしよう
Wrapping everything in promises
何でもPromiseにするな。 モジュールはコールバックを提供しよう。 PromisesはCPUを使うので節約しよう。
コールバックを使おう。
Git URLs in your package.json
依存関係に直接gitのURLを使わない。 semverに対応できないし、キャッシュの挙動が変な時があったりする。
npm に公開しよう
Sloppy async code
コントロールフローのパターンを利用して、 狂ったウォーターフローを作ったりしないようにしよう。
Promiseやasync等の非同期処理のパターンを使おう
Having node do everything
SSLの末端はnginx等に任せた方がいい。 nodeには重たい暗号化処理等は向いてない。
その仕事にあったツールを使って何でもnodeでやろうとしない。
Ignoring the node ecosystem
npmは沢山のコード資産を持ってる、そのエコシステムは無視しない。 Node Security ような情報に目を向けよう。
コミュニティに向きあおう。
Pioneerのお試しステップ
pioneer.js - javascript integration testing
pioneer/getting_started.md at master · mojotech/pioneer の補足的なファーストステップ
- インストール
chromedriver が必要なので入れる。
npm install chromedriver -g npm install pioneer --save
- スケルトン作成
以下で、tests
にスケルトン的なの作れる
$ ./node_modules/.bin/pioneer --scaffold
features
はシナリオファイル
steps
でシナリオに対する挙動をJavaScriptで書く感じ。
テストに必要なWidgetをwidgets
以下に入れておくと、steps
から読めるらしい。
Acorn-cspのできた流れ
RReverser/acorn-csp についての話
- Not working for web workers · Issue #90 · marijnh/acorn
- acornが
new Function
を使うので、CodeMirror経由でacorn使ってる人等がひっかかる - Chrome Appとかも同じ問題
- @RReverserさんがAST変換をしたCSP対応バージョンを作る - Not working for web workers · Issue #90 · marijnh/acorn
RReverser/acorn-csp は recastを使ってAST変換をしてる。
アプローチ
new Function
はmakePredicate
という関数のみで使ってるので、
これを置き換えた関数に一度書き換えてる。
acorn/acorn.js at a246bf83d00f6888268997dbf55533bb33e66bd3 · marijnh/acorn
'function makePredicate(words) {' + ' var generatedFn = _makePredicate(words);' + ' makePredicateCache[words] = generatedFn.toString();' + ' return generatedFn;' + '}'
書き換えた関数は、オリジナルのmakePredicate
の実行結果をキャッシュにいれていくだけ。
(元コード見てないけど、多分これでnew Function
によって展開されたものを回収してそう)
書き換えたものをnodeのvmモジュールを使って、 evalを展開した中身を回収してる。
var makePredicateCache = {}; // makePredicateCache[words] に値をnew Functionの結果を入れていってる vm.runInNewContext( recast.prettyPrint(ast).code, {makePredicateCache: makePredicateCache} );
最後、展開した中身をもう一度AST変換して、最初に書き換えていたmakePredicate
が、
先ほど作った展開済みの値を返すように書き換えてる。
properties: Object.keys(makePredicateCache).map(function (key) { var fnNode = esprima.parse('(' + this[key] + ')').body[0].expression; fnNode.id = null; return { type: 'Property', kind: 'init', key: {type: 'Literal', value: key}, value: fnNode }; }, makePredicateCache)
vmモジュールを使ってインライン展開チックな事やってるのが面白い
この変更を含んだバージョンは何時頃リリース予定ですか?
Nice, great job! What are your plans on releasing a version with these changes
引用元: Support ES6 SpreadElement · 2e3ce60 · Constellation/escodegen.
私の理解では〜
My understanding is that
引用元: Sequencing of promise resolution not being tested · Issue #61 · promises-aplus/promises-tests.
自分がどういう風に解釈してるか述べる時
JavaScript Memory Management Masterclass のメモ
JavaScript Memory Management Masterclass // Speaker Deckのメモです。
Q. メモリリークはどうやってチェックするの?
A. DevToolsでSnapshotsを取って比較
Hidden Classes
V8にはHidden Classesがあるので、delete
するのは最適化を逆に妨げる。
Closures
循環参照によるリーク
DOM Leak
DOMツリーは親を消しても、子のどれかを保持してる場合は、
そのツリーはGCによって回収されないので、
子もちゃんとnullなどして回収されるようにしないといけない。
Timers
ES6 WeakMaps
WeakMapsはメモリリークを避けるために必要。
普通にオブジェクトを使うと強参照になるので、GCで回収されない。
Memory Checklist
- 不必要なDOM elementへの強参照を避ける
- 循環参照を避ける
- 適切なスコープを使う
- 必要なくなったevent listenersは解除する
- ローカルキャッシュを管理する
- 管理する事で古いオブジェクトを捨てる
メモリ管理の基礎
Core Concepts
- 値の型は何?
- メモリ上で値はどうやって管理されてる?
- garbadgeって何?
- leakって何?
garbadgeって何?
Garbageとはroot nodeから辿りつけない値達の事
garbage collection はそれらのgarbageをシステムに伝える事
memory leakって何?
JavaScript DOM node
JavaScriptからDOM nodeへの参照を持っていると、
そのnodeをDOMから消しても、JavaScriptの参照があるためリークする
(JavaScript側からの参照を消せば回収される)
V8 memory management
new
や暗黙的にメモリをallocationする- Memory poolを使い切るとGCが走る
- GCにはmillisecondsかかる
- メモリのallocation気をつけないとGCによるフリーズが起きる
V8は世代別GC
- Young valueとOld Valueに値は分けられる
- 一定時間経つとyoung valueはoldに送られる
young generation
- fast allocation
- fast collection
- よくcollect(GC?)される
old generation
- fast allocation
- solower collection
- たまにcollectされる
なぜ、young generationは fast collection なのかというのは、
GCのコストはlive objectsの数に比例するため、
live obejctsが多いyoungのcollectionは早くないといけない。
Performance Tools
performance.memory
jsHeapSizeLimit
: heap sizeのlimittotalJSHeapSize
: 今使ってるheap sizeusedJSHeapSize
: allocated,free spaceを含んだsize
DevToolsの解説
Closures には名前付き関数式を使ったほうが見やすい
どうやってメモリリークを見つけるか
- Open DevTools
- Snapshot #1
- 操作
- Snapshot #2
- 操作
- Snapshot #2
- #1と#2のallocatedを比較する
Object Allocation Tracker
Allocation Stack Traces
JavaScriptの処理のビジュアライズ
ProfileをChartで見るとFlame Chart Viewで見られる
リソース紹介
- Overview - Google Chrome
- v8-perf
- Writing Fast, Memory-Efficient JavaScript | Smashing Magazine
- Fix two memory leaks + subtle bugs in Edit's JS (discovered by working on the Backbone upgrade in the D7 backport) [#2159965] | Drupal.org
- Tech Tuesday: Avoiding a memory leak situation in JS – Imgur Blog
- StrongLoop | Node.js Performance Tip of the Week: Memory Leak Diagnosis