Improve UI performance by optimizing reactivity
- Replace `ref`s with `shallowRef` when deep reactivity is not needed. - Replace `readonly`s with `shallowReadonly` where the goal is to only prevent `.value` mutation. - Remove redundant `ref` in `SizeObserver.vue`. - Remove redundant nested `ref` in `TooltipWrapper.vue`. - Remove redundant `events` export from `UseCollectionState.ts`. - Remove redundant `computed` from `UseCollectionState.ts`. - Remove `timestamp` from `TreeViewFilterEvent` that becomes unnecessary after using `shallowRef`. - Add missing unit tests for `UseTreeViewFilterEvent`. - Add missing stub for `FilterChangeDetails`.
This commit is contained in:
@@ -1,6 +1,4 @@
|
||||
import {
|
||||
ref, computed, readonly,
|
||||
} from 'vue';
|
||||
import { shallowRef, shallowReadonly } from 'vue';
|
||||
import { IApplicationContext, IReadOnlyApplicationContext } from '@/application/Context/IApplicationContext';
|
||||
import { ICategoryCollectionState, IReadOnlyCategoryCollectionState } from '@/application/Context/State/ICategoryCollectionState';
|
||||
import { IEventSubscriptionCollection } from '@/infrastructure/Events/IEventSubscriptionCollection';
|
||||
@@ -16,7 +14,7 @@ export function useCollectionState(
|
||||
throw new Error('missing events');
|
||||
}
|
||||
|
||||
const currentState = ref<ICategoryCollectionState>(context.state);
|
||||
const currentState = shallowRef<IReadOnlyCategoryCollectionState>(context.state);
|
||||
events.register([
|
||||
context.contextChanged.on((event) => {
|
||||
currentState.value = event.newState;
|
||||
@@ -66,8 +64,7 @@ export function useCollectionState(
|
||||
modifyCurrentContext,
|
||||
onStateChange,
|
||||
currentContext: context as IReadOnlyApplicationContext,
|
||||
currentState: readonly(computed<IReadOnlyCategoryCollectionState>(() => currentState.value)),
|
||||
events: events as IEventSubscriptionCollection,
|
||||
currentState: shallowReadonly(currentState),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {
|
||||
WatchSource, readonly, ref, watch,
|
||||
WatchSource, shallowReadonly, ref, watch,
|
||||
} from 'vue';
|
||||
import { AsyncLazy } from '@/infrastructure/Threading/AsyncLazy';
|
||||
import { IconName } from './IconName';
|
||||
@@ -15,7 +15,7 @@ export function useSvgLoader(
|
||||
}, { immediate: true });
|
||||
|
||||
return {
|
||||
svgContent: readonly(svgContent),
|
||||
svgContent: shallowReadonly(svgContent),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue';
|
||||
import { defineComponent, shallowRef } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
@@ -31,7 +31,7 @@ export default defineComponent({
|
||||
'transitionedOut',
|
||||
],
|
||||
setup(_, { emit }) {
|
||||
const modalElement = ref<HTMLElement>();
|
||||
const modalElement = shallowRef<HTMLElement>();
|
||||
|
||||
function onAfterTransitionLeave() {
|
||||
emit('transitionedOut');
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<div ref="containerElement" class="container">
|
||||
<slot ref="containerElement" />
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {
|
||||
defineComponent, ref, onMounted, onBeforeUnmount,
|
||||
defineComponent, shallowRef, onMounted, onBeforeUnmount,
|
||||
} from 'vue';
|
||||
import { useResizeObserverPolyfill } from '@/presentation/components/Shared/Hooks/UseResizeObserverPolyfill';
|
||||
|
||||
@@ -21,7 +21,7 @@ export default defineComponent({
|
||||
setup(_, { emit }) {
|
||||
const { resizeObserverReady } = useResizeObserverPolyfill();
|
||||
|
||||
const containerElement = ref<HTMLElement>();
|
||||
const containerElement = shallowRef<HTMLElement>();
|
||||
|
||||
let width = 0;
|
||||
let height = 0;
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
import {
|
||||
useFloating, arrow, shift, flip, Placement, offset, Side, Coords, autoUpdate,
|
||||
} from '@floating-ui/vue';
|
||||
import { defineComponent, ref, computed } from 'vue';
|
||||
import { defineComponent, shallowRef, computed } from 'vue';
|
||||
import { useResizeObserverPolyfill } from '@/presentation/components/Shared/Hooks/UseResizeObserverPolyfill';
|
||||
import type { CSSProperties } from 'vue/types/jsx'; // In Vue 3.0 import from 'vue'
|
||||
|
||||
@@ -36,10 +36,10 @@ const MARGIN_FROM_DOCUMENT_EDGE_IN_PX = 2;
|
||||
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const tooltipDisplayElement = ref<HTMLElement | undefined>();
|
||||
const triggeringElement = ref<HTMLElement | undefined>();
|
||||
const arrowElement = ref<HTMLElement | undefined>();
|
||||
const placement = ref<Placement>('top');
|
||||
const tooltipDisplayElement = shallowRef<HTMLElement | undefined>();
|
||||
const triggeringElement = shallowRef<HTMLElement | undefined>();
|
||||
const arrowElement = shallowRef<HTMLElement | undefined>();
|
||||
const placement = shallowRef<Placement>('top');
|
||||
|
||||
useResizeObserverPolyfill();
|
||||
|
||||
@@ -47,7 +47,7 @@ export default defineComponent({
|
||||
triggeringElement,
|
||||
tooltipDisplayElement,
|
||||
{
|
||||
placement: ref(placement),
|
||||
placement,
|
||||
middleware: [
|
||||
offset(ARROW_SIZE_IN_PX + GAP_BETWEEN_TOOLTIP_AND_TRIGGER_IN_PX),
|
||||
/* Shifts the element along the specified axes in order to keep it in view. */
|
||||
|
||||
Reference in New Issue
Block a user