Skip to content

Commit

Permalink
Merge pull request #964 from bolt-design-system/feature/animation-ren…
Browse files Browse the repository at this point in the history
…dering-performance

Bolt Core Renderer + Rendering Animation Performance Comparison
  • Loading branch information
sghoweri committed Nov 26, 2018
2 parents a467e71 + 4963ce5 commit 6b08652
Show file tree
Hide file tree
Showing 23 changed files with 1,010 additions and 11 deletions.
@@ -0,0 +1,28 @@
<h1>Bolt - LitHTML Test</h1>

<script>
function toggleThrottledLitRendering(){
console.log('toggleThrottledLitRendering');
var element = document.querySelector('.js-lit-test');
var buttonTriggle = document.querySelector('.js-lit-test-button');
if (element.hasAttribute('throttle')){
element.removeAttribute('throttle');
buttonTriggle.textContent = 'Enable LitHTML Throttling';
} else {
element.setAttribute('throttle', '');
buttonTriggle.textContent = 'Disable LitHTML Throttling';
}
};
window.toggleThrottledLitRendering = toggleThrottledLitRendering;
</script>


<bolt-button on-click="toggleThrottledLitRendering" class="js-lit-test-button">Enable LitHTML Throttling</bolt-button>

<bolt-lit-test class="js-lit-test"></bolt-lit-test>



@@ -0,0 +1,78 @@
import {
props,
define,
declarativeClickHandler,
sanitizeBoltClasses,
hasNativeShadowDomSupport,
afterNextRender,
watchForComponentMutations,
} from '@bolt/core/utils';
import { html, render, withLitHtml } from '@bolt/core/renderers/renderer-lit-html';
import { styleString } from '@polymer/lit-element/lib/render-helpers';

@define
export class Dot extends withLitHtml() {
static is = 'bolt-lit-dot';

static props = {
x: props.number,
y: props.number,
size: props.number,
hover: props.boolean,
}

constructor(self) {
self = super(self);
this.enter = this.enter.bind(this);
this.leave = this.leave.bind(this);
}

enter() {
console.log('enter');
this.hover = true;
this.triggerUpdate();
}

leave() {
this.hover = false;
this.triggerUpdate();
}

render() {
const s = this.props.size! * 1.3;
const style = styleString({
width: s + 'px',
height: s + 'px',
left: this.props.x + 'px',
top: this.props.y + 'px',
borderRadius: s / 2 + 'px',
lineHeight: s + 'px',
background: this.props.hover ? '#ff0' : '#61dafb',
});
return html`
<style>
:host {
position: absolute;
background: #61dafb;
font: normal 15px sans-serif;
text-align: center;
cursor: pointer;
}
div {
position: absolute;
background: #61dafb;
font: normal 15px sans-serif;
text-align: center;
cursor: pointer;
}
</style>
<div
style="${style}"
@mouseover="${this.enter}"
@mouseout="${this.leave}"
>
${this.props.hover ? '*' : ''}<slot></slot>${this.props.hover ? '*' : ''}
</div>
`;
}
}
@@ -0,0 +1,104 @@
import {
props,
define,
declarativeClickHandler,
sanitizeBoltClasses,
hasNativeShadowDomSupport,
afterNextRender,
watchForComponentMutations,
defineContext,
withContext,
} from '@bolt/core/utils';
import { html, render, withLitHtml } from '@bolt/core/renderers/renderer-lit-html';
import { styleString } from '@polymer/lit-element/lib/render-helpers';
import './bolt-lit-triangle.ts';

const containerStyle = {
position: 'absolute',
transformOrigin: '0 0',
left: '50%',
top: '50%',
width: '10px',
height: '10px',
background: '#eee',
};

export const LitRenderPerfContext = defineContext({
throttle: false,
});

@define
export class BoltLitHTMLTest extends withContext(withLitHtml()) {
static is = 'bolt-lit-test';

// provide context info to children that subscribe
// (context + subscriber idea originally from https://codepen.io/trusktr/project/editor/XbEOMk)
static get provides() {
return [LitRenderPerfContext];
}

static props = {
elapsed: props.number,
seconds: props.number,
intervalID: props.number,
rafID: props.number,
throttle: props.boolean,
}

constructor(self) {
self = super(self);
self.useShadow = hasNativeShadowDomSupport;
return self;
}

connectedCallback() {
super.connectedCallback();
this.updated();
this.seconds = 0;
this.intervalID = setInterval(() => {
this.seconds = (this.seconds % 10) + 1;
}, 1000);

const start = new Date().getTime();
const update = () => {
this.elapsed = new Date().getTime() - start;
this.rafID = requestAnimationFrame(update);
};
this.rafID = requestAnimationFrame(update);
}

disconnectedCallback() {
console.log('disconnectedCallback');
clearInterval(this.intervalID);
cancelAnimationFrame(this.rafID!);
}

render() {
let { throttle } = this.props;

const t = (this.elapsed! / 1000) % 10;
const scale = 1 + (t > 5 ? 10 - t : t) / 10;
const transform =
'scaleX(' + scale / 2.1 + ') scaleY(0.7) translateZ(0.1px)';
const style = styleString({ ...containerStyle, transform });

this.contexts.get(LitRenderPerfContext).throttle = throttle || this.props.throttle;

// const throttle = this.props.throttle || false;
// ?throttle=${throttle}

return html`
<div style="${style}">
<div>
<bolt-lit-triangle
x="${0}"
y="${0}"
s="${1000}"
label="${this.seconds}"
></bolt-lit-triangle>
</div>
</div>
`;
}
}

@@ -0,0 +1,90 @@
import {
props,
define,
declarativeClickHandler,
sanitizeBoltClasses,
hasNativeShadowDomSupport,
afterNextRender,
watchForComponentMutations,
withContext,
} from '@bolt/core/utils';
import { html, render, withLitHtml } from '@bolt/core/renderers/renderer-lit-html';
import './bolt-lit-dot';

import { LitRenderPerfContext } from './bolt-lit-test';

const targetSize = 25;

@define
export class SierpinskiTriangle extends withContext(withLitHtml()) {

static is = 'bolt-lit-triangle';

static props = {
x: props.number,
y: props.number,
s: props.number,
label: props.string,
}

// subscribe to specific props that are defined and available on the parent container
// (context + subscriber idea originally from https://codepen.io/trusktr/project/editor/XbEOMk)
static get consumes() {
return [[LitRenderPerfContext, 'throttle']];
}


connectedCallback() {
super.connectedCallback();
this.context = this.contexts.get(LitRenderPerfContext);
}

render() {
let { s, x, y, label } = this.props;
if (s <= targetSize) {
return html`
<bolt-lit-dot
x="${x - targetSize / 2}"
y="${y - targetSize / 2}"
size="${targetSize}"
>
${label}
</bolt-lit-dot>
`;
}

const { throttle } = this.context || false; // fallback if the `throttle` context isn't available for some reason
const slowDown = throttle;

// console.log(slowDown);
if (slowDown === true) {
const e = performance.now() + 0.8;
while (performance.now() < e) {
// Artificially long execution time.
}
}

s /= 2;

return html`
<bolt-lit-triangle
x="${x}"
y="${y - s / 2}"
s="${s}"
label="${label}"
></bolt-lit-triangle>
<bolt-lit-triangle
x="${x - s}"
y="${y + s / 2}"
s="${s}"
label="${label}"
></bolt-lit-triangle>
<bolt-lit-triangle
x="${x + s}"
y="${y + s / 2}"
s="${s}"
label="${label}"
></bolt-lit-triangle>
`;
}
}
@@ -0,0 +1,8 @@
import { polyfillLoader } from '@bolt/core/polyfills';

polyfillLoader.then(res => {
import(/*
webpackMode: 'lazy',
webpackChunkName: 'bolt-lit-test'
*/ './bolt-lit-test');
});
@@ -0,0 +1,28 @@
<h1>Bolt - Preact</h1>

<script>
function toggleThrottledPreactRendering(){
console.log('toggleThrottledRendering');
var element = document.querySelector('.js-preact-test');
var buttonTriggle = document.querySelector('.js-preact-test-button');
if (element.hasAttribute('throttle')){
element.removeAttribute('throttle');
buttonTriggle.textContent = 'Enable Preact Throttling';
} else {
element.setAttribute('throttle', '');
buttonTriggle.textContent = 'Disable Preact Throttling';
}
};
window.toggleThrottledPreactRendering = toggleThrottledPreactRendering;
</script>


<bolt-button on-click="toggleThrottledPreactRendering" class="js-preact-test-button">Enable Preact Throttling</bolt-button>

<bolt-preact-test class="js-preact-test"></bolt-preact-test>



0 comments on commit 6b08652

Please sign in to comment.