Design:AmdHarness.org/loader

From ApiFusion
Jump to: navigation, search

Goal

The unification of loading stuff for application modules with helpers on specific steps of SDLC.

Application specific configuration

Support the application specific configuration for main and secondary modules and pages. It supports common load targets which will be used also in a build.

As application could be a complex set of module combinations it is important to keep the common dependencies coherently across different subsets.

The app pages, module's test will refer a same loader.js which keeps an application level loading configuration. In release build the loader.js will become a resources container for 2nd phase of page loading(link TBD).

Targets

Source, Release, Debug are the most popular targets. Others are serving more specific SDLC goals:

Test

  • Test - standard Unit test
  • LoadTest unit test with extensive module use. Separate large or generated data set is used for test, the integrity checks shall be triggered just occasionally or upon whole test completion to prevent the timing interference.
  • ReleaseCheck compares the unit test on Source target results match to the same test set but on another( like Release) target to validate the load sequence on target does not break the functionality.

Platform tune up

Different platforms could have own configuration for application AMD loading and transformation chain. There are some specifics on platforms

  • Bundle size. As the initial load speed could be important and the bandwidth limited, the bundling in small chunks could help to deliver initial content faster. See the browser app loading stages(link TBD). Each package( i.e. loading stage ) will have own target.
  • JS version. The source code could rely on some particular feature of language. Like Array.prototype.forEach() or fat arrow functions ( => ).

The loader could add the AMD load rule to invoke the transformation or add the API shim to either transform the module or alter environment API.

  • Browser features. The lack of CSS3 or particular HTML tag in browser version which is used on template could be covered by shim on browser API or transformation of template itself.

The "IE7" target could trigger all shims and transformations either during load in IE or during build which will be delivered to browser by web server capable of mapping accordingly to the User-Agent HTTP header.

Optimization

During algorithms optimization it is important to have a straights simple unoptimized but correct reference implementation. Than several levels of changes will lead to one or few best for particular platform. The ReleaseCheck target will help to validate the algorithm transformation correctness. The different targets comprise the different optimization flags.

There are samples of optimizations:

  • Some platform could give an advanced treats like SIMD commands in array processing loop. The "LoopOptimize_SIMD" transformation could be added to substitute specific algorithm in that platform target.
  • The common case is to have optimization done manually. The loop unrolling, function calls inlining, conditions to boolean operations substitution, binary operations for math etc.

Resource aggregation

While it is a part of optimization and as such is a subject for ReleaseCheck, the aggregation has some extra specifics.

  • JS bundling.
  • Image concatenation
  • CSS bundling
  • localization

Resource inlining

The different types of resources could be fused together to improve the performance. Samples of such inclusions:

  • template referenced in widget as URL could be substituted by inline string from this URL.
  • The CSS MID could embedded into HTML during the build.
  • The images embedding in HTML will work depend of image type and browser:
    • SVG inlining works in most modern browsers
    • PNG and JPG in some. The transformation between formats will be justifiable depend of the image type. Background with solid color transitions has a direct match to SVG ones.

AMD transformation rules

Loader API

AMD

The AMD require() and define() are trapped to perform the implementation fixes over base AMD loader and support for loader functionality.

loader config

Could be

  • embedded into loader.js
  • passed as script parameter. Namespace and attribute name TBD.
  • passed as global loader.config={} variable

It is advised to keep reusable portion of configuration within loader.js

The global variable or script tag attribute will be available only in caller page. Hence it is a best way to pass overrides specific to the page still keeping common app settings within loader.js

In config you coould pass everything require.config() accepts plus

require.config(
{   transform: [{from:'CommomJS_mod', to: 'AMD_mod', mid:'CommonJS2Amd'}
] // array of transformers 
,   postShim: 
    

});

Altering the module loading

transformation

The module source could be transformed via transformation

Module shims

The module code could be modified after loading by shim. Shim could extending the API, wrap around methods in order to fix the bugs or adding the missing functionality.

Thirdparty features

The module could be written with certain expectation to the environment. In this case instead of modification of the module the environment could be altered. For example the shim to implement the Array.prototype.forEach()

As the environment change could affect other parts of application this feature need to be accomplished with full test over remaining modules with the change in place. Still there is a risk remains as the order of modules load and the change is not same in test, runtime and build.


Test

Implementations

AmdHarness.org/loader is an abstract API with multiple implementations over AMD loaders. At the moment it covers dojo and RequireJS

Other AMD implementations could use the implementations above as a base. Hopefully with smaller shims set, as they could be more respectful to relative paths and default AMD plugins.

The loader.js abstraction layer for more AMD implementations TBD.