- Notifications
You must be signed in to change notification settings - Fork346
👻 Tiny Concurrent UI library with Fiber.
License
frejs/fre
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
👻 Tiny Concurrent UI library with Fiber.
Concurrent Mode — This is an amazing idea, which implements the coroutine scheduler in JavaScript, it also calledTime slicing.
Keyed reconcilation algorithm — Fre has a minimal longest-common-subsequence algorithm, It supported keyed, pre-process.
Do more with less — After tree shaking, project of hello world is only 1KB, but it has most features, virtual DOM, hooks API, Fragments, Fre.memo and so on.
yarn add fre
import{render,useState}from'fre'functionApp(){const[count,setCount]=useState(0)return<><h1>{count}</h1><buttononClick={()=>setCount(count+1)}>+</button></>}render(<App/>,document.body)
useState
is a base API, It will receive initial state and return an Array
You can use it many times, new state is available when component is rerender
functionApp(){const[up,setUp]=useState(0)const[down,setDown]=useState(0)return(<><h1>{up}</h1><buttononClick={()=>setUp(up+1)}>+</button><h1>{down}</h1><buttononClick={()=>setDown(down-1)}>-</button></>)}
useReducer
anduseState
are almost the same,butuseReducer
needs a global reducer
functionreducer(state,action){switch(action.type){case'up':return{count:state.count+1}case'down':return{count:state.count-1}}}functionApp(){const[state,dispatch]=useReducer(reducer,{count:1})return(<>{state.count}<buttononClick={()=>dispatch({type:'up'})}>+</button><buttononClick={()=>dispatch({type:'down'})}>-</button></>)}
It is the execution and cleanup of effects, which is represented by the second parameter
useEffect(f) // effect (and clean-up) every timeuseEffect(f, []) // effect (and clean-up) only once in a component's lifeuseEffect(f, [x]) // effect (and clean-up) when property x changes in a component's life
functionApp({ flag}){const[count,setCount]=useState(0)useEffect(()=>{document.title='count is '+count},[flag])return(<><h1>{count}</h1><buttononClick={()=>setCount(count+1)}>+</button></>)}
If it returns a function, the function can do cleanups:
useEffect(()=>{document.title='count is '+countreturn()=>{store.unsubscribe()}},[])
More like useEffect, but useLayout is sync and blocking UI.
useLayout(()=>{document.title='count is '+count},[flag])
useMemo
has the same rules asuseEffect
, butuseMemo
will return a cached value.
constmemo=(c)=>(props)=>useMemo(()=>c,[Object.values(props)])
useCallback
is baseduseMemo
, it will return a cached function.
constcb=useCallback(()=>{console.log('cb was cached.')},[])
useRef
will return a function or an object.
functionApp(){useEffect(()=>{console.log(t)// { current:<div>t</div> }})constt=useRef(null)return<divref={t}>t</div>}
If it uses a function, it can return a cleanup and executes when removed.
functionApp(){constt=useRef((dom)=>{if(dom){doSomething()}else{cleanUp()}})returnflag&&<spanref={t}>I will removed</span>}
// fragmentfunctionApp(){return<>{something}</>}// render arrayfunctionApp(){return[a,b,c]}
plugins:[['@babel/plugin-transform-react-jsx',{runtime:'automatic',importSource:'fre',},],]
The comparison is difficult because the roadmap and trade-offs of each framework are different, but we have to do so.
- react
React is the source of inspiration for fre. Their implementation and asynchronous rendering are similar. The most amazing thing isconcurrent mode, which means that react and fre have the same roadmap --Exploring concurrent use cases.
But at the same time, fre has obvious advantages in reconciliation algorithm and bundle size.
- vue / preact
To some extent, vue and preact are similar. They have similar synchronous rendering, only the API is different.
The reconciliation algorithm of fre is similar to vue3, but the biggest difference is that vue/preact do not support concurrent mode, this means that the roadmap is totally different.
framework | concurrent | offscreen | reconcilation algorithm | bundle size |
---|---|---|---|---|
fre2 | √ | √ | ★★★★ | 2kb |
react18 | √ | √ | ★★ | 43kb |
vue3 | × | x | ★★★★★ | 33kb |
preactX | × | x | ★★★ | 4kb |
MIT @yisar
About
👻 Tiny Concurrent UI library with Fiber.