Adam Bar
@NOtherDev

what would YOU do
without a framework?


front-end anew with lit-html

whatwebcando.today

bundlephobia.com

angular?

website obesity crisis

~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);

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>
    );
  }
}

🤷

conclusions?

don't be a framework-only developer

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

By Adam Bar

What would YOU do without a framework? Front-end anew with lit-html

  • 3,411