efcl’s blog

GitHub英語のメモや引用が中心です。

別のIssueにした方がいい? - 分けた方がいいですね。

Maybe worth queuing this as another issue / pull request?

引用元: Add minimal support for lazy evaluation to chaining syntax #274 by FilipZawada · Pull Request #678 · lodash/lodash

Yes, fitting for a separate issue / pull request.

引用元: Add minimal support for lazy evaluation to chaining syntax #274 by FilipZawada · Pull Request #678 · lodash/lodash

一つの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 の補足的なファーストステップ

  1. インストール

chromedriver が必要なので入れる。

npm install chromedriver -g
npm install pioneer --save
  1. ケルトン作成

以下で、testsにスケルトン的なの作れる

$ ./node_modules/.bin/pioneer --scaffold

f:id:efcl:20140908211807j:plain

featuresはシナリオファイル stepsでシナリオに対する挙動をJavaScriptで書く感じ。 テストに必要なWidgetwidgets以下に入れておくと、stepsから読めるらしい。

Acorn-cspのできた流れ

RReverser/acorn-csp についての話

  1. Not working for web workers · Issue #90 · marijnh/acorn
  2. acornがnew Functionを使うので、CodeMirror経由でacorn使ってる人等がひっかかる
  3. Chrome Appとかも同じ問題
  4. @RReverserさんがAST変換をしたCSP対応バージョンを作る - Not working for web workers · Issue #90 · marijnh/acorn

RReverser/acorn-csprecastを使ってAST変換をしてる。

アプローチ

new FunctionmakePredicateという関数のみで使ってるので、 これを置き換えた関数に一度書き換えてる。

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モジュールを使ってインライン展開チックな事やってるのが面白い

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のlimit
  • totalJSHeapSize : 今使ってるheap size
  • usedJSHeapSize : 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で見られる

リソース紹介