Open tpluscode opened 7 years ago
Hmm, nope not possible, never played with lazy loading :(. Any idea how to mark import as lazy in TypeScript? I mean what syntax should we use?
I see where you're going but I wouldn't necessarily bake this into twc concretely. After all lazy-imports only one possible way to achieve... lazy imports. It's just a nuisance that it requires putting additional markup inside <dom-module>
as a sibling of <template>
.
Instead of focusing on imports maybe it wouldn't be too cumbersome to put any extra HTML outside the element's template?
The best bad idea I have is an additional annotation but it would just increase fragmentation.
How about this:
import { CustomElement } from 'twc/polymer';
@CustomElement()
class MyElement extends Polymer.Element {
// importing and returning the modules
async importGroupA() {
return {
...await import('bower:paper-button/paper-button.html'),
...await import('bower:paper-behaviors/paper-inky-focus-behavior.html')
};
}
// just importing the modules
async importGroupB() {
await import('bower:paper-behaviors/paper-button-behavior.html');
await import('bower:paper-behaviors/paper-checked-element-behavior.html');
}
connectedCallback() {
// do the actual import of group A
this.importGroupA()
// then do something with imported assets (or just after it imports)
.then(({ PaperButton, PaperInkyFocusBehavior }) => {
console.log('loaded components:', PaperButton, PaperInkyFocusBehavior);
});
// do the actual import of group B (does not wait for anything)
this.importGroupB();
}
}
This would translate to:
<dom-module id="upgrade-button">
<link rel="lazy-import" group="import-group-a" href="../paper-button/paper-button.html">
<link rel="lazy-import" group="import-group-a" href="../paper-behaviors/paper-inky-focus-behavior.html'">
<link rel="lazy-import" group="import-group-b" href="../paper-behaviors/paper-button-behavior.html">
<link rel="lazy-import" group="import-group-b" href="../paper-behaviors/paper-checked-element-behavior.html">
<template>
...
</template>
<script>
class MyElement extends Polymer.LazyImportsMixin(Polymer.Element) {
static get is() { return 'my-element'; }
connectedCallback() {
this.importLazyGroup('import-group-a').then(({ PaperButton, PaperInkyFocusBehavior }) => {
console.log('loaded components:', PaperButton, PaperInkyFocusBehavior);
});
this.importLazyGroup('import-group-b');
}
}
customElements.define(MyElement.is, MyElement);
</script>
</dom-module>
Does this look ok? The idea is to pick up all the async methods with awaited imports (or maybe just methods with imports?) and put those imports into the <dom-module>
, and every call of that method would be replaced with this.importLazyGroup(*method-name-dash-cased*)
. It would be possible to match both dot notation (this.methodName
) and square bracket notation (this['methodName']
). The only thing that remains an open question, is how to deal with computed method name or variables. TWC does not evaluate the runtime, so for now dynamic group names would require to be called as this.importLazyGroup(dynamicName)
, which would probably lose the types in then
callback.
Following our conversation, here's what we pretty much came up with:
interface LazyImportsMixin {
importLazyGroup<T>(this: T, groupName: keyof T): Promise<string[]>;
}
declare interface PolymerStatic {
LazyImportsMixin: Mixin<LazyImportsMixin>;
}
import { CustomElement, lazyImportGroup } from 'twc/polymer';
@CustomElement()
class MyElement extends Polymer.LazyImportsMixin(Polymer.Element) {
@lazyImportGroup()
async groupA() {
await import('bower:paper-input/paper-input.html');
}
connectedCallback() {
this.importLazyGroup('groupA')
.then((imported: string[]) => {
console.log('loaded components:', imported);
});
}
}
<dom-module id="my-element">
<link rel="lazy-import" group="group-a" href="../paper-input/paper-input.html" />
<script>
class MyElement extends Polymer.LazyImportsMixin(Polymer.Element) {
static get is() { return 'my-element'; }
connectedCallback() {
this.importLazyGroup('groupA')
.then((imported) => {
console.log('loaded components:', imported);
});
}
}
customElements.define(MyElement.is, MyElement);
</script>
</dom-module>
There is a few things to note:
groupA
methodconnectedCallback
, updateStyles
, etc which are all members of MyElement
groupA
methodfor all that to work with typescript I needed this in tsconfig.json
{
"module": "esnext",
"lib": [ "es2016" ]
}
I've just realized that with TWC it is not possible to have additional markup inside of the
<dom-module>
which is how<lazy-imports>
are used:Or is it possible?