-
Notifications
You must be signed in to change notification settings - Fork 62
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
Preload dependencies during idle time? #7
Comments
Hey @oliviertassinari! Thanks! Yeah, totally a great idea and I think @bradennapier has some alternative ideas around this problem. It would be great to come up with a simple and flexible solution for this. I'll review your solution when I get a chance and keep this in the back of my mind. Happy to collaborate with you to get something awesome together. |
Olivier, I may be misunderstanding your intent - but the fact the async loading is done using import which already returns promises, we shouldn't need to use setTimeout to accomplish nested asynchronous loading. This method also allows using the defer method to handle pushing to the client for rendering which @ctrlplusb has given us. From my testing it appears to do a good job so far, but I haven't done extensive tests on it as its working for our dev thus far. I have setup a method of handling routes asynchronously as well as their dependencies. export default [
{
id: 'Home',
exactly: true,
props: {
title: 'Home'
},
pattern: '/',
component: () => import('./screens/Home')
},
{
id: 'Welcome',
props: {
title: 'Welcome'
},
pattern: '/login/1',
component: () => import('./screens/Welcome')
},
{
id: 'SecurityCenter',
props: {
title: 'Security Center'
},
pattern: '/security-center',
secure: true,
component: () => import('./screens/SecurityCenter')
},
{
id: 'UserProjects',
props: {
title: 'Project Select'
},
pattern: '/project',
component: () => import('./screens/UserProjects')
},
{
id: 'LoginPage',
props: {
title: 'Login'
},
pattern: '/login',
component: () => import('./screens/Login')
}
] Then when we move deeper into the routes we simply pass new routes that will be also imported asynchronously import React from 'react'
import Resolver from 'app/resolver'
const routes = [
{
id: 'ProjectSelect',
pattern: '/',
exactly: true,
component: () => import('./screens/ProjectSelect')
},
{
id: 'ProjectDashboard',
pattern: '/dashboard/:projectSlug',
component: () => import('./screens/ProjectDashboard')
}
]
export default props => (<Resolver {...props} routes={routes} />) Then we have this as a Resolver ( I added a redux push as well for redirecting when accessing secure pages using a layer: const RoutedResolver = ({ routes, ...props }) => (
<div>
{
routes.map( route => {
if ( ! route.id ) { throw new Error('Route Does not have an ID: ', route) }
const matchProps = {
...route,
key: route.id,
exactly: route.exactly == true,
pattern: route.pattern === '/'
? props.pathname
: props.pathname + route.pattern
}
return <Match {...matchProps} render={ renderProps => {
const appProps = {
...matchProps,
...renderProps,
}
return <Resolver {...props} {...appProps} />
}}
/>
})
}
</div>
)
const Loading = () => (<div>LOADING</div>)
const Resolver = ({
component, routes,
isAuthenticated = false,
defer = false,
secure = false,
...props
}, { store }) => {
if ( secure && ! isAuthenticated ) {
const { location, ...rest } = props
store.dispatch({
type: 'ROUTER_SECURE_REQUESTED',
location: props.location,
props: rest
})
return null
}
const Component = routes
? RoutedResolver
: component
? BuildAsyncComponent(component, secure || defer)
: Loading
if ( routes ) { props.routes = routes }
//console.log('Resolver: ', props.id, props)
return <Component {...props} />
}
Resolver.contextTypes = {
store: PropTypes.object.isRequired
}
export const BuildAsyncComponent = (component, defer) =>
createAsyncComponent({
resolve: component,
defer
})
export default Resolver |
Related: ctrlplusb/react-universally#406 |
Hey, cool to see you have abstracted away the lazy loading handling for large React tree.
I found the approach much better than what react-router is suggesting to do!
I'm wondering, do you have any plan preloading dependencies on the client side during the idle time?
I have been implemented a naive solution, I'm pretty sure we could improve that. It's preloading everything.
If we were collecting some data. For instance, the order of lazing loading, we could even build a prediction model. I have heard that Facebook is using a machine learning algorithm to smartly load dependencies ahead of time.
The text was updated successfully, but these errors were encountered: