perf: improve inject performance
This commit is contained in:
		
							parent
							
								
									0952d4cf51
								
							
						
					
					
						commit
						117630fb92
					
				@ -7,24 +7,29 @@ export function provide<T>(key: Key<T>, value: T | Value<T>) {
 | 
			
		||||
  if (!currentInstance) {
 | 
			
		||||
    // TODO warn
 | 
			
		||||
  } else {
 | 
			
		||||
    const provides = currentInstance.provides || (currentInstance.provides = {})
 | 
			
		||||
    let provides = currentInstance.provides
 | 
			
		||||
    // by default an instance inherits its parent's provides object
 | 
			
		||||
    // but when it needs to provide values of its own, it creates its
 | 
			
		||||
    // own provides object using parent provides object as prototype.
 | 
			
		||||
    // this way in `inject` we can simply look up injections from direct
 | 
			
		||||
    // parent and let the prototype chain do the work.
 | 
			
		||||
    const parentProvides =
 | 
			
		||||
      currentInstance.parent && currentInstance.parent.provides
 | 
			
		||||
    if (parentProvides === provides) {
 | 
			
		||||
      provides = currentInstance.provides = Object.create(parentProvides)
 | 
			
		||||
    }
 | 
			
		||||
    provides[key as any] = value
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function inject<T>(key: Key<T>): Value<T> | undefined {
 | 
			
		||||
  // traverse parent chain and look for provided value
 | 
			
		||||
  if (!currentInstance) {
 | 
			
		||||
    // TODO warn
 | 
			
		||||
  } else {
 | 
			
		||||
    let parent = currentInstance.parent
 | 
			
		||||
    while (parent) {
 | 
			
		||||
      const { provides } = parent
 | 
			
		||||
      if (provides !== null && provides.hasOwnProperty(key as any)) {
 | 
			
		||||
        const val = provides[key as any]
 | 
			
		||||
        return isValue(val) ? val : value(val)
 | 
			
		||||
      }
 | 
			
		||||
      parent = parent.parent
 | 
			
		||||
    const provides = currentInstance.parent && currentInstance.provides
 | 
			
		||||
    if (provides) {
 | 
			
		||||
      const val = provides[key as any]
 | 
			
		||||
      return isValue(val) ? val : value(val)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -112,7 +112,7 @@ export type ComponentInstance<P = Data, S = Data> = {
 | 
			
		||||
  update: ReactiveEffect
 | 
			
		||||
  render: RenderFunction<P, S> | null
 | 
			
		||||
  effects: ReactiveEffect[] | null
 | 
			
		||||
  provides: Data | null
 | 
			
		||||
  provides: Data
 | 
			
		||||
 | 
			
		||||
  // the rest are only for stateful components
 | 
			
		||||
  data: S
 | 
			
		||||
@ -194,7 +194,7 @@ export function createComponentInstance(
 | 
			
		||||
    rtc: null,
 | 
			
		||||
    ec: null,
 | 
			
		||||
    effects: null,
 | 
			
		||||
    provides: null,
 | 
			
		||||
    provides: parent ? parent.provides : {},
 | 
			
		||||
 | 
			
		||||
    // public properties
 | 
			
		||||
    data: EMPTY_OBJ,
 | 
			
		||||
@ -225,7 +225,6 @@ export function setupStatefulComponent(instance: ComponentInstance) {
 | 
			
		||||
  // 2. call setup()
 | 
			
		||||
  const { setup } = Component
 | 
			
		||||
  if (setup) {
 | 
			
		||||
    currentInstance = instance
 | 
			
		||||
    // the props proxy makes the props object passed to setup() reactive
 | 
			
		||||
    // so props change can be tracked by watchers
 | 
			
		||||
    // it will be updated in resolveProps() on updates before render
 | 
			
		||||
@ -234,7 +233,11 @@ export function setupStatefulComponent(instance: ComponentInstance) {
 | 
			
		||||
      : null)
 | 
			
		||||
    const setupContext = (instance.setupContext =
 | 
			
		||||
      setup.length > 1 ? createSetupContext(instance) : null)
 | 
			
		||||
 | 
			
		||||
    currentInstance = instance
 | 
			
		||||
    const setupResult = setup.call(null, propsProxy, setupContext)
 | 
			
		||||
    currentInstance = null
 | 
			
		||||
 | 
			
		||||
    if (isFunction(setupResult)) {
 | 
			
		||||
      // setup returned an inline render function
 | 
			
		||||
      instance.render = setupResult
 | 
			
		||||
@ -247,7 +250,6 @@ export function setupStatefulComponent(instance: ComponentInstance) {
 | 
			
		||||
      }
 | 
			
		||||
      instance.render = Component.render as RenderFunction
 | 
			
		||||
    }
 | 
			
		||||
    currentInstance = null
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user