この記事では、RequireJS ベースのプロジェクトをマージおよび圧縮する方法を説明します。この記事では、Node.js などのいくつかのツールを使用します。 したがって、Node.js がまだ手元にない場合は、ここをクリック してダウンロードできます。
モチベーション
RequireJS については多くの記事で紹介されています。このツールを使用すると、JavaScript コードをモジュールに簡単に分割し、コードをモジュール化して保守しやすく保つことができます。こうすることで、相互依存関係のある多数の JavaScript ファイルが作成されます。 HTML ドキュメント内で RequireJS ベースのスクリプト ファイルを参照するだけで、必要なすべてのファイルが自動的にページに参照されます。
ただし、運用環境ですべての JavaScript ファイルを分離するのは悪い習慣です。その結果、ファイルが小さい場合でも多くのリクエストが発生し、多くの時間が無駄になります。 これらのスクリプト ファイルをマージすると、リクエストの数が減り、読み込み時間を節約できます。
ロード時間を節約するもう 1 つの方法は、ロードされるファイルのサイズを減らすことです。ファイルが小さいほど転送速度が速くなります。このプロセスは最小化と呼ばれ、コードの動作や機能を変更せずに、スクリプト ファイルのコード構造を慎重に変更することで実現されます。たとえば、不要なスペースを削除し、変数 (変数またはメソッド) 名と関数 (メソッドまたはメソッド) 名を短縮 (マングリングまたは圧縮) します。ファイルを結合して圧縮するこのプロセスは、コードの最適化と呼ばれます。この方法は、JavaScript ファイルの最適化に加えて、CSS ファイルの最適化にも適しています。
RequireJS には、define() と require() という 2 つの主要なメソッドがあります。これら 2 つのメソッドは基本的に同じ宣言を持ち、どちらも依存関係をロードしてコールバック関数を実行する方法を知っています。 require() とは異なり、define() はコードを名前付きモジュールとして保存するために使用されます。 したがって、define()のコールバック関数は、このモジュール定義として戻り値を持つ必要があります。これらの同様に定義されたモジュールは、AMD (Asynchronous Module Definition、非同期モジュール定義) と呼ばれます。
RequireJS に詳しくない場合、または私が何を書いているのかよく理解できない場合でも、心配しないでください。以下にその一例を示します。
JavaScript アプリケーションの最適化
このセクションでは、Addy Osmani の TodoMVC Backbone.js RequireJS プロジェクト を最適化する方法を示します。 TodoMVC プロジェクトにはさまざまなフレームワークでの多くの TodoMVC 実装が含まれているため、バージョン 1.1.0 をダウンロードし、Backbone.js RequireJS アプリケーションを抽出しました。 ここをクリック してアプリをダウンロードし、ダウンロードした zip ファイルを解凍します。 todo-mvc の解凍されたディレクトリがこの例のルート パスになり、以降このディレクトリを
スクリプトファイルを参照するindex.htmlコード
<script data-main="js/main" src="js/lib/require/require.js"></script> <!--[if IE]> <script src="js/lib/ie.js"></script> <![endif]-->
其实,整个项目只需要引用require.js这个脚本文件。如果你在浏览器中运行这个项目,并且在你喜欢的(擅长的)调试工具的network标签中, 你就会发现浏览器同时也加载了其它的JavaScript文件:
所有在红线边框里面的脚本文件都是由RequireJS自动加载的。
我们将用RequireJS Optimizer(RequireJS优化器)来优化这个项目。根据已下载的说明文件,找到r.js并将其复制到
RequireJS Optimizer有很多用处。它不仅能够优化单个JavaScript或单个CSS文件,它还可以优化整个项目或只是其中的一部分,甚至多页应用程序(multi-page application)。它还可以使用不同的缩小引擎(minification engines)或者干脆什么都不用(no minification at all),等等。本文无意于涵盖RequireJS Optimizer的所有可能性,在此仅演示它的一种用法。
正如我之前所提到的,我们将用到Node.js来运行优化器(optimizer)。用如下的命令运行它(optimizer):
运行RequireJS Optimizer
$ node r.js -o <arguments>
有两种方式可以将参数传递给optimizer。一种是在命令行上指定参数:
在命令行上指定参数
$ node r.js -o baseUrl=. name=main out=main-built.js
另一种方式是构建一个配置文件(相对于执行文件夹)并包含指定的参数 :
$ node r.js -o build.js
build.js的内容:配置文件中的参数
({ baseUrl: ".", name: "main", out: "main-built.js" })
我认为构建一个配置文件比在命令行中使用参数的可读性更高,因此我将采用这种方式。接下来我们就为项目创建一个
({ appDir: './', baseUrl: './js', dir: './dist', modules: [ { name: 'main' } ], fileExclusionRegExp: /^(r|build)\.js$/, optimizeCss: 'standard', removeCombined: true, paths: { jquery: 'lib/jquery', underscore: 'lib/underscore', backbone: 'lib/backbone/backbone', backboneLocalstorage: 'lib/backbone/backbone.localStorage', text: 'lib/require/text' }, shim: { underscore: { exports: '_' }, backbone: { deps: [ 'underscore', 'jquery' ], exports: 'Backbone' }, backboneLocalstorage: { deps: ['backbone'], exports: 'Store' } } })
RequireJS Optimizer のすべての構成オプションを理解することがこの記事の目的ではありませんが、この記事で使用したパラメーターについて説明 (説明) したいと思います:
RequireJS Optimizer とより高度なアプリケーションの詳細については、その Web ページで以前に提供されている情報に加えて、ここをクリックして、使用可能なすべての構成オプションに関する詳細情報を表示できます。
ビルド ファイルを作成したので、オプティマイザーを実行できます。
オプティマイザを実行します
$node r.js -o build.js
新しいフォルダーが生成されます:
最適化されたプロジェクトを実行すると、最適化されていないプロジェクトとまったく同じように表示されます。ページのネットワーク トラフィック情報を再度確認すると、JavaScript ファイルが 2 つだけ読み込まれていることがわかります。
RequireJs Optimizer は、サーバー上のスクリプト ファイルの数を 13 から 2 に減らし、合計ファイル サイズを 164 KB から 58.6 KB (require.js と main.js) に減らします。
オーバーヘッド
明らかに、最適化後は、require.js ファイルを参照する必要がなくなりました。分離されたスクリプト ファイルがなく、依存関係のあるすべてのファイルが読み込まれているためです。
それにもかかわらず、最適化プロセスにより、すべてのスクリプトが 1 つの最適化されたスクリプト ファイルにマージされ、このファイルには多くの define() および require() 呼び出しが含まれます。 したがって、アプリケーションが適切に実行できるようにするには、アプリケーションのどこか (つまり、これらのファイルを含む) に、define() と require() を指定して実装する必要があります。
これにより、よく知られたオーバーヘッドが発生します。define() と require() を実装するコードが常に存在します。このコードはアプリケーションの一部ではなく、インフラストラクチャを考慮するためにのみ存在します。 この問題は、JavaScript ライブラリを開発する場合に特に大きくなります。これらのライブラリは通常、RequireJS に比べて非常に小さいため、ライブラリに含めると大きなオーバーヘッドが発生します。
これを書いている時点では、このオーバーヘッドに対する完全な解決策はありませんが、アーモンドを使用してこの問題を軽減できます。 Almond は、RequireJS インターフェイス (API) を実装する非常にシンプルな AMD ローダーです。したがって、最適化されたコードで RequireJS 実装の代替として使用でき、プロジェクトにアーモンドを含めることができます。
そのため、私はオーバーヘッドなしで RequireJS アプリケーションを最適化できるオプティマイザーの開発に取り組んでいますが、これはまだ新しいプロジェクト (開発の初期段階) であるため、ここで紹介するものは何もありません。
ダウンロードと概要