Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

compile templates at build time rather than at run time #432

Closed
wkeese opened this issue Nov 10, 2015 · 0 comments
Closed

compile templates at build time rather than at run time #432

wkeese opened this issue Nov 10, 2015 · 0 comments
Assignees
Milestone

Comments

@wkeese
Copy link
Member

wkeese commented Nov 10, 2015

Refactor how handlebars plugin works in builds.

There are a number of enhancements/bug fixes from this refactor relating to builds:

  1. Reduce CPU used at page load time by precompiling templates at build time.
  2. Make sure that dependencies specified in templates via the requires="..." attribute
    are properly included into the build.
  3. Builds with templates no longer download requirejs-text/text.js, delite/Template.js,
    and delite/handlebars.js to the browser. That's assuming that you do a custom build
    (rather than using the delite/layer.js file), and assuming that the builder and loader
    are working correctly. We could also consider excluding handlebars.js and Template.js
    from the delite/layer.js file.

Also one bug fix for the non-build case: stop using the text! plugin directly since
the parentRequire() method passed to load() runs in the context of the caller. If the
caller remapped requirejs-text/text to point to another module, it would inadvertently
affect the behavior of delite/handlebars.

Previously, the build step for handlebars!foo.html would merely write this to the layer file:

define("requirejs-text/text!foo.html", function(){
   return "...";
});

Thus the build eliminated the XHR to get the template text, but still ran template compilation
at page load, and the browser still needed to download delite/handlebars.js, and therefore also
requirejs-text/text.js and delite/Template.js.

With this commit, the handlebars build writes the generated template function to the layer,
for example:

define('delite/handlebars!deliteful/list/List/_PageLoaderRenderer.html',["deliteful/ProgressIndicator"], function(){
        return function anonymous(document,register
/**/) {
this.setClassComponent('template', (this.loading ? 'd-loading' : ''), this)
var c1 = this.renderNode = register.createElement('div');
...
return {
        ...
        refresh: function(props){
                if('loading' in props)
                        this.setClassComponent('template', (this.loading ? 'd-loading' : ''), this);
                ...
        }.bind(this),

        destroy: function(){
        ...
        }.bind(this)
};

Note that this increases the bytes needed for each template. For example, deliteful's layer.js goes
from 112351 bytes / 26393 gzipped to 127540 bytes / 28103 gzipped. But on the other hand, it means
that Template.js doesn't need to be downloaded to the browser, a savings of 9536 bytes (3230 gzipped).
You don't currently get that savings though if you include delite/layer.js, since delite/layer.js
currently includes Template.js and handlebars.js.

PR in #431.

@wkeese wkeese self-assigned this Nov 10, 2015
@wkeese wkeese added this to the 0.8.0 milestone Nov 10, 2015
@wkeese wkeese closed this as completed in 2c0633f Nov 10, 2015
wkeese added a commit that referenced this issue Feb 19, 2016
compiled template.

Template creates dummy elements (ex: <d-button>) for introspection, to
find out when to call element.foo = 123 rather than element.setAttribute("foo", 123).
That of course first requires running the code to define the custom elements.
That wasn't working right during builds, because the javascript files were
referencing symbols that don't exist in Node, such as HTMLElement.

Partial rollback of 2c0633f

Fixes #438, refs #432.
wkeese added a commit that referenced this issue Mar 11, 2016
Turns out that it's problematic even to create the AST at build time, because then
(during the build) handlebars.js will create dummy custom elements (ex: <d-button>)
for introspection.  They are used to find out when to call element.foo = false
rather than element.foo = "false".

Creating the dummy elements first requires running the code to define the custom elements.
That wasn't working right during builds, because the javascript files were
referencing symbols that don't exist in Node, such as HTMLElement.

Rolls back more of (and most of) 2c0633f.

Fixes #438 for real, and refs #432.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant