SPAs are the "Google-scale" of frontend tech. YAGNI unless you are Big (or trying to fleece VCs). SPAs are useful where the latency and overall UX of a button press can be translated to some tiny % increase in a KPI through A/B testing, etc. Where you want to track user behavior down to a pixel & microsecond, and wrapping every element in JS is the only way to get there. This is frankly irrelevant to 99% of projects…
Lit's templating engine is just html that is made super efficient to render because only parts that change are re-rendered. There is no inter language to learn like JSX. It uses native browser html parser, native browser templating capabilities ( tag), native event handling and native literal template capabilities of javascript.
I have a simple wrapper class that renders and composes components efficiently and reactively when state changes. The views look like:
class TestView extends LittleLit {
static get properties() {
return {
paramter: {}
};
}
constructor(){
super();
this.el=document.querySelector('#main');//root component attached to the dom
this.subcomponent=new SomeView();
}
render(){
this.subcomponent.somestate=this.somestate;//propagate state down if necessary.
let h=html`Hellow ${parameter}${subcomponent.el}`;
render(h, this.el,{host:this});
}
}
To use v=new TestView();
v.parameter='world';//this triggers rendering if the parameter changed.
Here is my whole framework: class LittleLit {
constructor() {
this.el=document.createElement("div");
this.refreshScheduled=false;
this._properties={};
let properties =this.constructor.properties;
if(properties!==undefined){
for (let prop in properties) {
this.property(prop,properties[prop]);
}
}
}
refresh(){ //you can call refresh to trigger rendering efficiently
if(this.refreshScheduled===false){
this.refreshScheduled=true;
window.queueMicrotask(()=>this._update());//deduplicated rendering in an efficiently scheduled microtask
}
}
_update(){
this.render();
this.refreshScheduled=false;
}
property(name,options){
Object.defineProperty(this, name, {
set(v){
if(this._properties!==v){ //refresh only if property changed
this._properties[name]=v;
this.refresh();
}
},
get(){return this._properties[name];}
});
}
}Most of the power comes from the templating library: https://lit.dev/docs/templates/overview/