CleverStyle Frameworkはあらゆる可能な方法で、サーバーだけでなくフロントエンドでも開発者を支援します。 これについては過去の記事で何度か言及しましたが、すべてが内部でどのように配置されているかの詳細には触れませんでした。
この記事では、ページで必要なファイルの決定方法から始まり、HTTP / 2サーバープッシュなどの静的配信の最適化まで、フロントエンドの静的処理の詳細に没頭します。 CleverStyle Frameworkを使用すると、カスタムビルドシステムなしで実行できる理由と、必要に応じてフレームワークプロセスにそのようなビルドシステムを統合する方法を忘れないでください。
この記事では、特にBower / NPMとRequireJSの統合を見落としています。これは近い将来、別の記事のトピックになります。
接続するもの
最初のタスクは、特定のページで必要なファイル(CSS / JS / HTML)を判別することです。2つの条件グループがあります。
- サイトのすべてのページの共有ファイル
- 特定のページ(または複数のページ)に固有のファイル
共有ファイル
共有ファイルは、3つのサブグループに分けられます。
最初のサブグループには、 assets
ディレクトリのシステムカーネルファイルが含まれます。 フレームワーク自体が必要とする基本的な最小限のサービスファイルがあります(実際、これは回避できますが、それについては後で詳しく説明します)。 このサブグループのファイルが最初にダウンロードされます。
2番目のサブグループには、インターフェイスのthemes//{css|js|html}
現在のテーマのファイルが含まれますthemes//{css|js|html}
、カーネルファイルの直後に接続されます。
3番目のグループには、インストールするモジュールのファイルが含まれます。このページでは、どのページに接続する必要があるかは示されていません(ページは少し条件付きです)。
特定のページのファイル
特定のページは、インストールされたモジュールによって生成されます。
典型的なシナリオでは、 Module_name
モジュールをインストールするとき、 /Module_name
始まるページを処理します。 このモジュールのページで特定のファイルを使用する必要があることを示すために、モジュールのメタ情報を持つファイル内のパスに関連付けられたそのようなファイルのマップがコンパイルされます。
{ "package" : "Blogs", "category" : "modules", ... "assets" : { "admin/Blogs" : [ "cs-blogs-admin-*" ], "Blogs" : [ "cs-blogs-*" ] }, ... }
Blogsモジュールには、ページに接続するためのCSSファイルとJSファイルはなく、Webコンポーネントのみが含まれます(WebコンポーネントにはCSS / JSを含めることができますが、これは後で説明します)。
上記の例では、モジュールのすべてのページで、パスがcs-blogs-
始まるファイル(アスタリスクは読みやすくするためにのみ破棄およびサポートされます)が接続され、 cs-blogs-admin-
を持つファイルのみに接続されることがcs-blogs-admin-
管理ページ(このキーはリストの最初であるため、この接頭辞を持つファイルは最初に除外され、残りは同じ開始にもかかわらず次のキーに移動します)。
パスを犠牲にして、次のルートからカウントされることを明確にする必要があります: modules/Modules_name/assets/{css|js|html}
、ファイル形式から、それがどのディレクトリにあるか、つまりmodules/Modules_name/assets/html
のみがmodules/Modules_name/assets/html
で検索されmodules/Modules_name/assets/html
HTMLファイル。ただし、CSSやJSは含まれません。
直接的な依存関係
モジュール自体のファイルはストーリーの一部にすぎず、モジュール間の依存関係はこのシステムの重要なリンクです。
フォトギャラリーモジュールの例とその依存関係の1つであるUploaderモジュールを見てみましょう。
{ "package" : "Photo_gallery", "category" : "modules", ... "assets" : { "admin/Photo_gallery" : "admin.css", "Photo_gallery" : "general.*" }, ... "provide" : "photo_gallery", "require" : [ "System>=6.25", "System<7.0", "Composer", "Fotorama>=4.4.9", "file_upload", "composer_assets" ], ... }
{ "package" : "Uploader", "category" : "modules", ... "assets" : { "admin/Uploader" : "admin.css", "Uploader" : "script.js" }, ... "provide" : "file_upload", ... }
ここでは、 Photo gallery
モジュールがfile_upload
直接依存していることがfile_upload
ます。 file_upload
は、モジュールの名前ではなく、その機能です( 詳細はドキュメントで説明されています )。 静的処理の観点から、これはUploader
モジュール(サブページではなくモジュール全体)向けのファイルもPhoto gallery
モジュールのページに接続されることを意味します。さらに、モジュール自身のファイルの前で(これは依存関係に同期コードがある場合に重要です)依存関係に従ってさらに使用されます)。
このシナリオでは、必須(キーrequire
)だけでなく、オプション( optional
キー)の依存関係も考慮されることに注意してください。
逆依存関係
フロントエンドにとって、 逆依存関係も重要な概念です。 これらは、ターゲットモジュールではなく、サードパーティモジュール自体によって示される依存関係です。 これは、 代替実装でWebコンポーネントを再定義する機能とともに、かなり強力なツールです。 本質的に、これは、このモジュールが別のモジュールに追加機能を提供することをフレームワークに伝える機会を提供します(たとえば、ブログモジュール自体を編集することなくブログの外観を変更します)。 これは非常に微妙な点であり、悪用されるべきではありませんが、役に立つ場合もあります。
ネストされた依存関係
依存関係は、依存関係を繰り返すことができるなど、独自の依存関係を持つことができます。 フレームワークはこれを理解し、この機能を念頭に置いて依存関係ツリーをフラットな構造に変えます(循環依存関係を作成しようとしないでください。結果は未定義になります)。
システムのバージョン( System
モジュール)への依存は依存関係の周期的な性質に影響を与えないことに注意することが重要です。静的の処理中に無視されると効果的に仮定できます。
接続用のファイルを収集するプロセスへの統合
接続のためのファイルのアセンブリ中に、システムはサブスクライブすることによりSystem/Page/assets_dependencies_and_map
生成し、システムおよび構築された依存関係構造によって収集されたファイルを操作できます。
この構造に独自のファイルを追加し、独自の仮想モジュールに編成して、依存関係を構築できます。 したがって、 Composer assets
モジュールは、Bower / NPMパッケージからのファイルのインクルードをフレームワークに統合し、ファイルを処理するための内部メカニズムを使用します(これについてはもう少し先です)。
実際にファイルをページに接続する
フレームワークは、特定のページに必要なすべてのファイルを常に接続するだけでなく、システムの構成に応じて、より高度な方法で動作します。
次のオプションは、ファイルの添付方法に影響します。
- キャッシングと圧縮
- フロントエンドの負荷の最適化(前のパラメーターに依存)
- 加硫(最初のパラメーターにも依存)
- JavaScriptとHTMLをページの本文の背後に移動する
- Webコンポーネントのサポートを無効にする
JavaScriptとHTMLをページの本文を超えて移動する
これは最も単純で、JS / HTMLファイルは<head>
に配置されるのではなく、 </body>
前に含まれます。一般に、使用が推奨されます。
CSSは常に<head>
特別に含まれ<head>
。これは、基本的なスタイル設定が通常小さく、ページのレンダリングの遅延が存在しないためです(特にHTTP / 2とサーバープッシュを使用)。
Webコンポーネントサポートの無効化
また、かなりシンプルな設定ですが、これはカスタムテーマでのみ機能します(デフォルトのテーマで管理パネルが壊れないようにするため)。 HTMLファイルの完全なフィルタリングにつながり、Webコンポーネントのポリフィルとassets/Polymer
からのJSファイルのダウンロードも無効にします。これにより、必要ない場合、フレームワーク内のWebコンポーネントに関連するすべてが無効になります。 多くの市販のモジュールは、インターフェースが完全にWebコンポーネント上に構築されているため、動作を停止することを理解することが重要です。
キャッシングと圧縮
まず、フレームワークは、依存関係を考慮に入れてページ上の接続用に収集されたすべてのファイルを取得し、ファイルをキャッシュにパックします。 共有ファイルの場合、3つのキャッシュファイルがcss / js / html形式で作成され、インストールされた各モジュールの各assets
キーに対して同様のファイルが作成されます+個別のインターフェイス言語翻訳キャッシュが作成されます+ Webコンポーネントのポリフィルが個別にキャッシュされ、新しい依存構造が保存されます。キャッシュファイルを収集したデータ。
第二に、ファイルはキャッシュに直接送られるだけではありません-これには何らかの処理が先行します。 フレームワークは、この問題で空から星をつかもうとはしませんが、非常に高速に動作します。
CSS処理は次のとおりです。
- 余分なスペースと改行を削除する
- カラーHEX値を6文字から3文字に減らしたり、RGBカラーをHEXに変換するなど、一部のデザインを最適化する
- base64形式で小さな画像や類似のファイル(最大4 KiB)を埋め込むと、埋め込まれていないファイルは別のリストに記録され、後で使用されます
- 相対パスを調整して、新しいキャッシュされたCSSターゲティングを反映する
JS処理は、本格的な縮小子をドラッグする必要がないため、はるかに少ないです。そうでなければ、単純な検索と置換でコードを簡単に破ることができるため、次のように制限します。
- 保証された安全な改行の削除
- 行の先頭から始まる単一行のコメントを削除する
- 行の先頭から始まる複数行のコメントを削除します
-
</script>
から<\/script>
。このJSコードは後でHTMLに埋め込むために使用できるため - ES2015の複数行パターンは無視されます(最初から始まり最後で終わる-内部のすべては処理から除外されます)
CSS / JSミニフィケーションデータは非常に基本的なものですが、プロジェクト全体を数十ミリ秒で繰り返すことができますが、本格的なミニフィクサーは数秒しかかからず、Gzipでは最大5%のゲインしか得られません(これらのミニフィケーターをビルドされたキャッシュ上で実行できます)。
HTMLの処理はさらに少なくなります。実際、すべてのJSコードは、上記のミニファイヤを介してアセンブルおよび実行されます。各WebコンポーネントのCSSも、上記のミニマイザを介して実行されます<link rel="import" href="../polymer/polymer.html">
HTMLの<link rel="import" href="../polymer/polymer.html">
。
キャッシュが構築されると、 System/Page/rebuild_cache
がSystem/Page/rebuild_cache
ます。カスタムミニフィケーターやカスタムキャッシュの構築など、このイベントのハンドラーで実行できます。
キャッシュ構造では、各ファイルのパラメーターの部分にハッシュが付随します(HTTP / 2サーバープッシュに関する部分の以下の例)。 ハッシュはファイルの内容から計算されるため、1つのファイルを変更してキャッシュを再構築すると、対応するキャッシュファイルのハッシュが変更されますが、キャッシュ全体は一度に変更されません。
キャッシュ構造、依存関係などの説明を含む補助JSONファイルの構造については、ドキュメントをご覧ください。
加硫
加硫とは、CSS / JSコードが結果のHTMLに埋め込まれているHTMLファイルを処理するプロセスです。 CSSでは、Polymerはすべての状況でCSP互換のコンストラクトをまだサポートしていないため、これは重要ではありません。そのため、CSSは常に最終HTMLに埋め込まれます。
フレームワークでの実装はプロプライエタリです。一般に、 GitHubの対応するプロジェクトでそれについて読むことができます。
フロントエンドの負荷の最適化
これは興味深いメカニズムであり、その呼び出しはページの初期レンダリングを加速することです。
上記のように、一般的なCSS / JS / HTMLコードがあり、個々のページに固有です。 したがって、この一般的なコードは、Appシェルとして想像できます。 フロントエンドのロードの最適化は、最初は一般的なJS / HTMLのみがページに接続され、ロードされてワークアウトされた後にのみ、非同期ロードと残りのJS / HTMLコードの順次実行が開始されるという事実にあります(モジュールはHTMLに対応する必要があります)すべてのページに共通するコードは、このモジュールの依存関係のJSコードよりも早く実行できます)。
このアプローチにより、ページの最初のレンダリングを大幅に高速化できるため、インタラクティブなページではないにしても、ユーザーに可能な限り高速で何かを提供できます。
最適化されたロードのために、最適化されたキャッシュの追加構造を備えた別のファイルが構築されます。
HTTP / 2サーバープッシュ
キャッシュが有効になっている場合、ページに必要なファイルには、対応する「Link:」ヘッダーが付随します。プロキシは、CloudFlare、nghttpxなど、通常ヘッダーの例であるサーバープッシュになります。
Link:</storage/public_cache/CleverStyle:TinyMCE.html?602ca>; rel=preload; as=document Link:</storage/public_cache/CleverStyle:System.css?fecf7>; rel=preload; as=style Link:</storage/public_cache/CleverStyle:Uploader.js?2167a>; rel=preload; as=script Link:</storage/public_cache/CleverStyle:System.html?14dd7>; rel=preload; as=document Link:</storage/public_cache/CleverStyle:System.js?a0e9d>; rel=preload; as=script Link:</storage/public_cache/CleverStyle:Static_pages.html?a292d>; rel=preload; as=document
これにフロントエンドの負荷最適化を追加するとさらに興味深いものになります。サーバープッシュは、最初に接続されたファイルにのみ適用されます。上記と同じページの例です。
Link:</storage/public_cache/CleverStyle:System.html?14dd7>; rel=preload; as=document Link:</storage/public_cache/CleverStyle:System.js?a0e9d>; rel=preload; as=script Link:</storage/public_cache/CleverStyle:System.css?fecf7>; rel=preload; as=style
サーバープッシュは、サイズのためにCSSに埋め込まれなかったが、ページのレンダリングに必要なファイルも取得します(詳細については、ドキュメントを参照してください)。
もちろん、サーバープッシュは一度だけトリガーされ、その後、パフォーマンスの低下を防ぐためにCookieが設定されます。
カスタムフロントエンドビルドシステムが不要な理由
開発プロセスが私のものに似ている場合:LiveScript-> JavaScript、SCSS-> CSS、Jade-> HTML-File Watchersの助けを借りて、すべてが変更されてGitに完全に入るたびに自動的に生成され、カスタムビルドシステムなしで実行できます。 ファイルを変更すると、対応するアーティファクトが生成されます。ブラウザに切り替えてF5を押すと(フレームワークでキャッシュを有効にせずに)、すぐに使用できます。
カスタムビルドシステムがある場合、カスタムビルドシステムを追加するか、フレームワークの機能を完全に置き換えますか?
あなたの親友は2つのシステムイベントです:
- システム/ページ/ assets_dependencies_and_map
- システム/ページ/ rebuild_cache
彼らの助けを借りて、あなたはフレームワークの仕事に統合し、好きなように追加のアーティファクト/ツールを持っている/使用することにより、言及されたすべての利点を活用できます。
また、ドキュメントではキャッシュ構造についても説明しているため、フレームワークが理解できる形式でビルドシステムのアーティファクトを準備できるため、フレームワークビルドシステムを使用せず、独自のアーティファクトを食用形式で提供できます。
最後に
新しいアイデアと建設的なコメントに常に満足しています。
» GitHubのリポジトリ