Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v2 RFC : Memo component by default and Boundary compoents #105

Closed
yisar opened this issue Nov 27, 2019 · 6 comments
Closed

v2 RFC : Memo component by default and Boundary compoents #105

yisar opened this issue Nov 27, 2019 · 6 comments

Comments

@yisar
Copy link
Collaborator

yisar commented Nov 27, 2019

I'm trying to improve the performance of fre. Here are two main ideas

Memo component by default

Maybe we can memo all components by default, every component is pureComponent, without additonal API

import { h, Lazy, useState } from 'fre'

function App() {
  const [list] = useState([1, 2, 3])
  const [count, setCount] = useState(0)
  return (
    <div>
       <ListView />
      <h1>{count}</h1>
      <button onclick={()=>setCount(count+1)}>add connt</button>
    </div>
  )
}

the ListView will rerender while state.list changed. It like useMemo, but for compoent rerender.

Suspense Boundary

Boundary components have similar APIs, it can use for es6 import()

const OtherCompont = import('./other-component')
<Suspense fallback={()=>'loading'}}>
  <OtherCompont />
</Suspense>

When OtherCompont have not resolve,it will render loading.

Error Boundary

const didCatch = e =>{
  reprotError(e)
  return 'I am borken'
}
<Catch fallback={didCatch}>
  <Child />
</Catch>

When Child catch any errors,it will render borken.

@yisar yisar changed the title Lazy List and Lazy List and Boundary compoents Nov 27, 2019
@yisar yisar changed the title Lazy List and Boundary compoents v2 RFC : Lazy List and Boundary compoents Nov 27, 2019
@yisar yisar pinned this issue Nov 27, 2019
@mindplay-dk
Copy link
Contributor

To be honest, I don't like the <Lazy> tag idea. I generally don't like burdening the user with more API choices to improve performance - we already have useMemo and that ought to be enough? Providing different ways to implement the same type of optimization, in my opinion, only leads to inconsistencies, more overhead for a developer in making these choices, and more overhead for someone trying to read what is essentially different versions of the same thing.

Having support for <Suspense> would be very cool. 👍

Regarding error boundaries, I've been looking at the React docs and their example and wondering how come they don't have an answer to error handling based on hooks? Error handling is behavior, which is what hooks are meant to abstract - this library is hooks first, so that's worth thinking about. (I'm clearly not the first to have thought about this - here's one example of error boundaries defined via hooks.)

Since we're talking about version 2 already, here's something I've been wondering about lately. Do you think it's possible to move the component execution and diffing off the main thread into a Worker? The component execution and the diffing itself does not actually involve the DOM at all - only during the very last step of an update do we apply the actual changes back to the DOM, and that last step is unavoidably a single blocking operation... if it were possible to do all of the component and virtual DOM work off the main thread, we might not need any scheduling at all? Since a Worker can't block the UI thread. (Obviously, this would depart quite radically from React, since components could no longer readily access window, document, fetch and so on - they would need to access these from callbacks via hooks or something, after the component execution and diffing itself, since these things can only occur on the main thread...)

Also, I think we still have issues to resolve with version 1 - mainly, tests should be rock solid and in working order before proceeding with more features, in my opinion. Error handling also likely needs work (we currently can't see errors at all) before adding more error handling features.

@yisar
Copy link
Collaborator Author

yisar commented Nov 28, 2019

I'm here. I'm very glad to hear from you. I think I can explain something:

we already have useMemo and that ought to be enough?

I thought about this. Maybe we need something like React.memo
But my idea is that we have built it in reconcilation algorithm by default without additional API. What do you think?

Regarding error boundaries, I've been looking at the React docs and their example and wondering how come they don't have an answer to error handling based on hooks?

Yes, right now, error boundary can only be applied to class in React now, I think it's similar to suspense, so I put forward a similar API.

@yisar
Copy link
Collaborator Author

yisar commented Nov 28, 2019

Do you think it's possible to move the component execution and diffing off the main thread into a Worker?

Wow, we thought of going together, as you said, I wrote another framework.

https://github.com/132yse/voe

There, I try to run diff into the web worker, and then the patch happens on the main thread.

voe is still in the prototype stage. If it works possible, I can improve it and change the repo to English.

But in fact, it's very difficult, because message posting is limited. It can't pass functions, DOM, so most diff algorithms can't be used.

I don't think fre is worth making such a big change

Also, I think we still have issues to resolve with version 1 - mainly, tests should be rock solid

Yes, we should. This issue is just a discussion about v2. In fact, V1 still needs to be tested completely and maintained for a long time.

@yisar yisar changed the title v2 RFC : Lazy List and Boundary compoents v2 RFC : Memo component by default and Boundary compoents Nov 28, 2019
@mindplay-dk
Copy link
Contributor

Voe looks interesting, I hadn't seen this. Also has the initialization wrapper function I talked about in #106. I need to take a closer look at this at some point. 🙂

But my idea is that we have built it in reconcilation algorithm by default without additional API. What do you think?

From my point of view, <Lazy/> is an API - any built-in special component is a kind of API, another choice you need to make. I prefer APIs that offer fewer API points that work in many situations, as opposed to offering many API points for very specific situations.

Not sure, I guess I'd need to see specifically what you mean...

@yisar
Copy link
Collaborator Author

yisar commented Nov 28, 2019

Not sure, I guess I'd need to see specifically what you mean...

I think about it again. Maybe we can do memo component without any APIs. Every component can be called pureComponent by default.

@yisar
Copy link
Collaborator Author

yisar commented Dec 8, 2019

https://github.com/132yse/fre/blob/master/demo/src/memo.js
I implemented fre.memo in fre without any additional API export. Every component is pure-component, just like Vue.

@yisar yisar closed this as completed Dec 20, 2019
@yisar yisar unpinned this issue Dec 20, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants