Snapshots in Dart（翻訳）


> 原文: https://www.dartlang.org/articles/snapshots/
> 2014/12/23時点のものを翻訳
> ライセンスは[www.dartlang.orgのもの](https://github.com/dart-lang/www.dartlang.org/blob/master/LICENSE)に従います
> 英語難しいので間違いあったらご指摘ください

_著：Siva Annamalai_
_2013年2月_

この記事はDartのスナップショットについてーーそれが何モノかという事と、どのようにDartアプリの起動を高速化しているのかについて話します。コマンドラインのアプリを書いている場合、この記事の例を参考にスナップショットを生成する事で、起動時間を改善する事ができるはずです。

Webアプリを書いているのであれば、何もする必要はありません。ブラウザのDartVMが、自動でアプリのスナップショット行います。そのWebアプリを次に実行した時に、ブラウザはキャッシュからスナップショットを取得し、アプリの起動を高速化するために利用します。

## スナップショットとは何ですか？

スナップショットとは、1つかそれ以上のDartオブジェクトのシリアライズされた形式で表される一連のバイトの事です。つまり、Dartオブジェクトがisolateのヒープメモリでの表現方法に厳密に一致しています。

Dart VMは主に2つの理由でスナップショットを使っています：

* アプリの **初回の起動の高速化** のために使っています。コアライブラリとアプリケーションスクリプトのスナップショットは、通常はコアライブラリとアプリケーションスクリプトのパースしたデータを含んでいます。つまり、起動時にライブラリやスクリプトをパースしたりトークン化する必要が無いという事を意味します。
* あるisolateから他のisolateへ **オブジェクトを渡す** ために使います。

DartVMは次の種類のスナップショットを使っています：

* **フルスナップショット** は、初期化後のisolateのヒープを完全に表現します。これはDartVMがDartのコアライブラリや、他の`dart:uri`、`dart:io`、`dart:utf`、`dart:json`、`dart:isolate`等といったライブラリの高速な起動や初期化のために使います。
* **スクリプトスナップショット** は、アプリケーションスクリプトがisolateにロードされた後、実行される前の、isolateのヒープを完全に表現します。これはDartVMがアプリケーションの高速な起動と初期化のために使います。例えば、dart2js を起動するスクリプトは、事前に作成された dart2js アプリのスクリプトスナップショットを使います。
* **オブジェクトスナップショット** 。あるisolateから他のisolateへのメッセージングは、他のisolateへ送るために、(DartVMでは)Dartオブジェクトのスナップショットを作成する実装になっています。

## ブラウザはどのようにスナップショットを使っているのか

DartVMを持ったブラウザは、メインのDartのisolateの、起動と初期化の高速化のためにフルスナップショットを使っています。このスナップショットには、Dartのコアライブラリと他の`dart:uri`、`dart:utf`、`dart:json`、`dart:isolate`、`dart:html`といったライブラリが含まれます。

また、ブラウザは潜在的にロード済みのアプリケーションのスクリプトスナップショットを生成する事ができ、ブラウザのキャッシュにキャッシュします。キャッシュされたスクリプトスナップショットは、その後のアプリケーションのリロード時の起動高速化のために使われます。

## スクリプトスナップショットを生成し、利用する方法

DartVM (`dart`)を使う事で、スクリプトスナップショットを生成し、利用する事ができます。

> **Note**: たかだか数回しか使わないプログラムのために、スクリプトスナップショットを作成する必要はありません。スクリプトスナップショットは、たくさん起動する事でスナップショット作成のコストを償却できるようなデプロイをされるアプリケーションの場合において価値があるのです。

スクリプトスナップショットを生成するには、`--snapshot`オプションを付けてdart（訳注：dartコマンドのこと）を使ってください。importで使っているパッケージ(`import 'package:...'`)の場所を指定するには`--package_root`オプションを使ってください。


```
dart [--package_root=<path>] --snapshot=<output_file> <dart_file>
```

`--snapshot`オプションは`dart-script-file`（訳注：`<dart_file>`のこと）のスクリプトスナップショットを`out-file`（訳注：`<output_file>`のこと）に書き出します。例えば次のコマンドでは、`dart2js.dart`というDartスクリプトのスナップショットを作成し、`dart2js.snapshot`と呼ばれるファイルの中に設置します。

```
dart --snapshot=dart2js.snapshot \ 
    dart-sdk/lib/dart2js/lib/_internal/compiler/implementation/dart2js.dart
```

そのスナップショットからスクリプトを実行するには、スナップショットファイルをコマンドラインで指定します：

```
dart <snapshot_file> <args>
```

指定した引数はスクリプトに渡されます。例えば、`myscript.dart -oout.js`を`dart2js`のコマンドライン引数に渡す時は、`dart2js`をこのように実行する事ができます：

```
dart dart2js.snapshot myscript.dart -oout.js
```

## フルスナップショットを生成する方法

（例えばDartiumのような）DartVMを埋め込む稀なプロジェクトのひとつで働いている場合、この項目を読んでみてください。`gen_snapshot`ツールは(コアライブラリ、`dart:uri`、`dart:io`、`dart:utf`、`dart:json`、`dart:isolate`などの)フルスナップショットを _`out-file`_ に書き出します：

```
gen_snapshot [<options>] --snapshot=<out_file>
```

次のオプションが利用できます

| 利用可能なオプション | 概要 |
|:-----|:------|
| `--package_root=path` | import(`import 'package:...'`)で使ってるパッケージの場所を指定する |
| `--url_mapping=mapping` | ライブラリのimportの際のURI解決のために、コマンドライン上でのURLのマッピングを提供します |


## まとめ

スナップショットについてもっと詳しく知りたい場合や、どのように実装されてるか知りたい場合は、[dart/runtime/vm directory](http://code.google.com/p/dart/source/browse/#svn%2Fbranches%2Fbleeding_edge%2Fdart%2Fruntime%2Fvm) のファイルを見てみてください。まずは [snapshot.h](http://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/runtime/vm/snapshot.h)の"Snapshot"を探すところから初めてみてください。コードは実装上の都合で移動されるかもしれませんので注意してください。

-----

翻訳ここまで ---- 以下感想など

-----

* 元々アドベントカレンダーでスナップショットについて書くつもりだったので今更ながら翻訳
* ブラウザ側でDartを使う場合は何も気にしなくていいし、知る必要がない
* サーバーサイドでDartを使う場合は、スクリプトスナップショットの作り方と、スナップショットからの起動方法は覚えておいた方が良いのかもしれない
* とはいえサーバーサイドで起動時間が気になる事なんてそうそう無いはずなので、記事の最初に書いてあるように頻繁に利用するようなDart製のコマンドラインアプリケーションを作る場合だけ知ってれば充分な気はします。