Skip to content

Instantly share code, notes, and snippets.

@frank-dspeed
Forked from andrejewski/can-defer.js
Last active March 12, 2018 11:50
Show Gist options
  • Select an option

  • Save frank-dspeed/791c1bc25ce548f0c1ca4446593359ae to your computer and use it in GitHub Desktop.

Select an option

Save frank-dspeed/791c1bc25ce548f0c1ca4446593359ae to your computer and use it in GitHub Desktop.
Declaratively defer rendering for large components and lists (Can v4)
import Component from 'can/component/';
export default Component.extend('CanDeferComponent', {
tag: 'can-defer',
viewModel: {
delayMs: {
type: 'number',
default: 0,
set: x => parseInt(x, 10)
},
initialHtml: { default: null },
/*
This is a convenience prop for rendering lists in
chunks as one can pass (delay-scalar)="scope.index"
*/
delayScalar: {
default: null,
set: x => parseInt(x, 10)
},
isActive: { default: false },
delay: {
get () {
const delayScalar = this.delayScalar;
const delayMs = this.delayMs;
if (delayScalar === 'number') {
return delayMs;
}
return delayScalar * delayMs;
}
}
},
_timeout: 'any',
activate () {
if (!this._timeout && !this.isActive) {
this._timeout = setTimeout(() => {
requestAnimationFrame(() => {
this.isActive = true;
this._timeout = null;
});
}, this.delay);
}
}
},
view: '{{#if isActive}}<content/>{{else}}{{{initialHtml}}}{{/if}}',
connectedCallback: (el) => {
this.element = el;
this.viewModel.activate();
}
});
/* USAGE
<can-defer delay-ms="500">
<my-heavy-component />
</can-defer>
{{#each list}}
<can-defer delayMs="500" delayScalar="{{scope.index}}">
<my-heavy-item {{value}}="." />
</can-defer>
{{/each}}
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment