-
Notifications
You must be signed in to change notification settings - Fork 15
Resource Aggregation with dependency expansion
The Aggregator, as its name implies, aggregates requests for multiple resources (JavaScript, CSS, HTML, etc.) into a single HTTP response. The Aggregator can also expand the AMD module dependencies of the requested resources to include them in the response before the loader asks for them. This can help to reduce or eliminate the cascade of requests caused by dependency discovery on the client.
There are two basic types of Aggregator requests:
- Application generated requests used to load the application's bootstrap layer, usually invoked from the landing page (e.g. index.html).
- Loader generated requests.
Application generated requests may include non-AMD resources (using the scripts
URL parameter) such as the AMD loader, the loader config, and any other non-AMD scripts. AMD modules to be included in the application's bootstrap layer are specified by the deps
and preloads
URL parameters. The responses for application generated requests are expanded to include the expanded dependencies for the AMD modules specified using the deps
and preloads
URL parameters.
Application generated requests may also specify the includeUndefinedFeatureDeps
and the includeRequireDesp
query args to generate a 'whole-app' layer in order to populate the browser application cache for offline support, or to populate the Aggregator cache for the purpose of generating a cache-primer bundle.
Loader generated requests are initiated by application calls to the AMD loader's require
function. The modules specified in the require call's dependency array which have not previously been delivered to the client will be requested from the Aggregator and included in the response. The expanded dependencies of the modules specified in the require call's dependency array (excluding modules previously delivered to the client) can also be included in the response if dependency expansion is being performed.
The Aggregator supports two approaches for performing dependency expansion of loader generated requests; Server-side layer expansion and Require list expansion. Each of these approaches has their own advantages and disadvantages.
##Require-list expansion vs. Server-side layer expansion
Require list expansion is the most flexible approach because it allows the AMD loader to remain in charge of determining which modules get loaded and when. This is most important when issuing multiple, concurrent requests (e.g. when require
is called before a previously outstanding require
call has completed). With Server-side layer expansion, this situation can lead to extra requests when responses arrive in a different order than than they were requested. This is why the i18nSplit
loader extension config parameter is not supported for server-side layer expansion.
The downside to require list expansion is that it unavoidably results in expansion of the application code. For certain usage patterns this expansion can be significant. One of the more problematic usage patterns includes heavy use of the has!
loader plugin to conditionally load modules where the feature conditionals used in the plugin expressions are not yet defined when the expansion takes place, thereby invoking has! plugin branching. Excessive use of has! plugin branching can result in bloating of expanded require lists and high CPU utilization on the server.
If you don't need to use i18nSplit
and your application doesn't make multiple, concurrent, require
calls, then you should probably use server-side layer expansion since this yields the smallest possible layers. Use require list expansion if you want to use i18nSplit
to improve the cacheablility of Aggregator responses in proxy caches or if you need to support multiple, concurrent, calls to require
from your application. Try running the application with both options to gauge the impact of require list expansion on layer size for your application layers. Just be sure to use the gzip compressed response sizes when comparing layer sizes because require list expansion contains many repeated patterns which lend themselves to high compression ratios.
You can explore the effect of require list expansion on application size using the sample application. The sample uses require list expansion by default, but if you add ?serverExpandLayers=1
to the page URL, then it will use server-expanded layers instead.