abstract-state-router icon indicating copy to clipboard operation
abstract-state-router copied to clipboard

Lazy-loading states

Open TehShrike opened this issue 9 years ago • 3 comments
trafficstars

On Twitter, Ryan Grove brought up the need to painlessly lazy-load route modules.

On the surface, this seems like it would be easy to implement. The state's template property could be a promise-returning function that would return the real template object. Exactly how the function would go out and get the template/code would be an implementation detail that would depend on the bundler the consumer was using.

In practice, I don't feel comfortable writing out specs until I know of at least one (probably Webpack) user willing to give some real use case details here so that I could be sure that the solution I've thought of would solve a real problem.

So, if you're some Webpack user (or anyone else with a lazy-load-friendly bundler that you want to use) and you want this feature, let me know here! I'm willing to implement it if the complexity doesn't get out of hand.

TehShrike avatar Jul 26 '16 21:07 TehShrike

CC @thelarkinn aka ME!

TheLarkInn avatar Jul 26 '16 21:07 TheLarkInn

Any news on this?

It would be extremely useful with many big components using https://github.com/TehShrike/svelte-state-renderer...

frederikhors avatar Nov 02 '19 22:11 frederikhors

I think this would actually be pretty easy to implement this from ASR's side of things.

You could make a renderer that took any other renderer and wrapped it in such a way that it would wait for a promise to resolve before passing the template value on to the original renderer.

Something like

const makeAsyncRenderer = realRenderer => stateRouter => {
	const renderer = realRenderer(stateRouter)

	return Object.assign(Object.create(renderer), {
		async render(context, cb) {
			const thunk = context.template
			const template = await thunk()
			const contextForRealRenderer = Object.assign({}, context, { template })
			return renderer.render(contextForRealRenderer, cb)
		}
	})
}

Usage would look like

const StateRouter = require('abstract-state-router')
const makeSvelteStateRenderer = require('svelte-state-renderer')

const defaultParameters = {
	props: {
		annoy() {
			alert('Modal dialogs are annoying')
		}
	}
}
const svelteRenderer = makeSvelteStateRenderer(defaultParameters)
const asyncRenderer = makeAsyncRenderer(svelteRenderer)


const stateRouter = StateRouter(asyncRenderer, document.querySelector('body'))

stateRouter.addState({
	name: 'whatever',
	template: () => import('./whatever.svelte')
})

and then it would be up to your bundler to handle the hard code splitting and lazy-loading parts.

TehShrike avatar Nov 02 '19 23:11 TehShrike