Adam Bar
@NOtherDev
what would YOU do
without a framework?
front-end anew with lit-html
bundlephobia.com
angular?
website obesity crisis
code splitting + dynamic imports
~1,5s
Templating timeline
var div = document.createElement('div');
div.setAttribute('class', 'foo');
document.body.innerHTML = '<div class="foo">Hello</div>';
<div ng-class="{'foo': hasFoo}">{{greeting}}</div>
<div className={hasFoo ? 'foo' : ''}>{this.greeting}</div>
??
const fancyTemplate = `
<div class="${hasFoo ? 'foo' : ''}">
${this.calculateGreeting()}
</div>
`;
const fancyTemplate = myTag`
<div class="${hasFoo ? 'foo' : ''}">
${this.calculateGreeting()}
</div>
`;
function myTag(parts, ...values) {
// parts = ['<div ...", '">', ...]
// values = ['foo', 'Hello']
// ...
return 'whatever we need';
}
lit-html
lit = little
lit = lightweight
lit = literals
const litTemplate = html`
<div class=${hasFoo ? 'foo' : ''}>
${this.calculateGreeting()}
</div>
`;
render(litTemplate, document.body);
Credits: Lars Den Bakker
Efficiency
const countTemplate = (count) => html`
<p>The current count is: ${count}</p>
`;
let i = 0;
setInterval(() => {
render(countTemplate(i++),
document.body);
}, 1000);
expressiveness
const greetingTemplate = html`
<h1>${greeting} ${name}!</h1>
`;
const parentTemplate = html`
<div class=${hasFoo ? 'foo' : ''}>
${greetingTemplate}
</div>
`;
render(parentTemplate, document.body);
extensibility
function fetchData() {
return window.fetch(/* ... */);
}
const dataTemplate = html`<p>
${until(fetchData(), 'loading...')}
</p>`;
render(dataTemplate, document.body);
let's play
Web components
encapsulation
composability
isolation
<my-component my="stuff"/>
<!-- living on the edge, no bundling,
no transpilation, no polyfills -->
<script type="module"
src="./modern.js"></script>
<!-- "classic", with bundling,
transpilation, polyfills -->
<script nomodule
src="./legacy.js"></script>
lit-html was made by polymer...
...but it doesn't depend on polymer
lit-element
lit-html + web components
class MyElement extends LitElement {
render() {
return html`
<div class=${hasFoo ? 'foo' : ''}>
${calculateGreeting()}
</div>
`;
}
}
class MyElement extends LitElement {
render() {
return html`
<div class=${this.hasFoo ? 'foo' : ''}>
${this.greeting}
</div>
`;
}
}
class MyElement extends LitElement {
constructor(hasFoo, greeting) {
super();
this.hasFoo = hasFoo || false;
this.greeting = greeting || 'Hello!';
}
render() {
return html`
<div class=${this.hasFoo ? 'foo' : ''}>
${this.greeting}
</div>
`;
}
}
class MyElement extends LitElement {
constructor(hasFoo, greeting) {
super();
this.hasFoo = hasFoo || false;
this.greeting = greeting || 'Hello!';
}
static get properties() {
return {
hasFoo: {type: Boolean},
greeting: {type: String}
};
}
render() {
return html`
<div class=${this.hasFoo ? 'foo' : ''}>
${this.greeting}
</div>
`;
}
}
class MyElement extends LitElement {
constructor(hasFoo, greeting) {
super();
this.hasFoo = hasFoo || false;
this.greeting = greeting || 'Hello!';
}
static get properties() {
return {
hasFoo: {type: Boolean},
greeting: {type: String}
};
}
render() {
return html`
<div class=${this.hasFoo ? 'foo' : ''}>
${this.greeting}
</div>
`;
}
}
customElements.define('my-element', MyElement);
<my-element
hasFoo="true"
greeting="Hi!"/>
let's play
@customElement('my-element')
class MyElement extends LitElement {
@property()
hasFoo = false;
@property()
greeting = 'Hello!';
render() {
return html`
<div class=${this.hasFoo ? 'foo' : ''}>
${this.greeting}
</div>
`;
}
}
class MyElement extends LitElement {
connectedCallback() {
// ...
}
shouldUpdate() {
// ...
}
updated() {
// ...
}
render() {
// ...
}
disconnectedCallback() {
// ...
}
}
class MyElement extends LitElement {
constructor(hasFoo, greeting) {
super();
this.hasFoo = hasFoo || false;
this.greeting = greeting || 'Hello!';
}
static get properties() {
return {
hasFoo: {type: Boolean},
greeting: {type: String}
};
}
render() {
return html`<div
class=${this.hasFoo ? 'foo' : ''}>
${this.greeting}
</div>
`;
}
}
customElements.define('my-element',
MyElement);
class MyElement extends React.Component {
constructor({hasFoo, greeting}) {
super();
this.state = {
hasFoo: hasFoo || false,
greeting = greeting || 'Hello!'
};
}
static propTypes = {
hasFoo: PropTypes.boolean,
greeting: PropTypes.string
}
render() {
const className = this.state.hasFoo
? 'foo' : '';
return (
<div className={className}>
{this.state.greeting}
</div>
);
}
}
🤷
react
Credits: Lars Den Bakker
lit-html
Credits: Lars Den Bakker
conclusions?
there are always many options
size matters
don't be a framework-only developer
-
there are always many options
-
size matters
-
don't be a framework-only developer
Adam Bar
@NOtherDevÂ
What would YOU do without a framework? Front-end anew with lit-html v0.1
By Adam Bar
What would YOU do without a framework? Front-end anew with lit-html v0.1
- 1,679