From 11cb76c405dd351abce411c97e0d04a95e5cb649 Mon Sep 17 00:00:00 2001 From: Bill Wallace Date: Wed, 27 Sep 2023 17:41:18 -0400 Subject: [PATCH] feat: Add timing information for various user related actions --- extensions/cornerstone/src/init.tsx | 3 ++ .../cornerstone/src/utils/initViewTiming.ts | 45 +++++++++++++++++++ platform/app/public/html-templates/index.html | 7 +-- platform/app/src/routes/DataSourceWrapper.tsx | 8 +++- platform/app/src/routes/Mode/Mode.tsx | 10 ++++- platform/core/src/log.js | 19 +++++++- platform/core/src/types/TimingEnum.ts | 8 ++++ platform/core/src/types/index.ts | 3 ++ 8 files changed, 94 insertions(+), 9 deletions(-) create mode 100644 extensions/cornerstone/src/utils/initViewTiming.ts create mode 100644 platform/core/src/types/TimingEnum.ts diff --git a/extensions/cornerstone/src/init.tsx b/extensions/cornerstone/src/init.tsx index f052b6e0191..3a6703e1853 100644 --- a/extensions/cornerstone/src/init.tsx +++ b/extensions/cornerstone/src/init.tsx @@ -28,6 +28,7 @@ import interleaveTopToBottom from './utils/interleaveTopToBottom'; import initContextMenu from './initContextMenu'; import initDoubleClick from './initDoubleClick'; import { CornerstoneServices } from './types'; +import initViewTiming from './utils/initViewTiming'; // TODO: Cypress tests are currently grabbing this from the window? window.cornerstone = cornerstone; @@ -235,6 +236,8 @@ export default async function init({ element.addEventListener(EVENTS.CAMERA_RESET, resetCrosshairs); eventTarget.addEventListener(EVENTS.STACK_VIEWPORT_NEW_STACK, newStackCallback); + + initViewTiming({ element, eventTarget }); } function elementDisabledHandler(evt) { diff --git a/extensions/cornerstone/src/utils/initViewTiming.ts b/extensions/cornerstone/src/utils/initViewTiming.ts new file mode 100644 index 00000000000..8c4ad9f03de --- /dev/null +++ b/extensions/cornerstone/src/utils/initViewTiming.ts @@ -0,0 +1,45 @@ +import { log, Types } from '@ohif/core'; +import { EVENTS } from '@cornerstonejs/core'; + +const { TimingEnum } = Types; + +const IMAGE_TIMING_KEYS = [ + TimingEnum.DISPLAY_SETS_TO_ALL_IMAGES, + TimingEnum.DISPLAY_SETS_TO_FIRST_IMAGE, + TimingEnum.STUDY_TO_FIRST_IMAGE, +]; + +const imageTiming = { + viewportsWaiting: 0, +}; + +/** + * Defines the initial view timing reporting. + * This allows knowing how many viewports are waiting for initial views and + * when the IMAGE_RENDERED gets sent out. + * The first image rendered will fire the FIRST_IMAGE timeEnd logs, while + * the last of the enabled viewport will fire the ALL_IMAGES timeEnd logs. + * + */ + +export default function initViewTiming({ element }) { + if (!IMAGE_TIMING_KEYS.find(key => log.timingKeys[key])) { + return; + } + imageTiming.viewportsWaiting += 1; + element.addEventListener(EVENTS.IMAGE_RENDERED, imageRenderedListener); +} + +function imageRenderedListener(evt) { + if (evt.detail.viewportStatus === 'preRender') { + return; + } + log.timeEnd(TimingEnum.DISPLAY_SETS_TO_FIRST_IMAGE); + log.timeEnd(TimingEnum.STUDY_TO_FIRST_IMAGE); + log.timeEnd(TimingEnum.SCRIPT_TO_VIEW); + imageTiming.viewportsWaiting -= 1; + evt.detail.element.removeEventListener(EVENTS.IMAGE_RENDERED, imageRenderedListener); + if (!imageTiming.viewportsWaiting) { + log.timeEnd(TimingEnum.DISPLAY_SETS_TO_ALL_IMAGES); + } +} diff --git a/platform/app/public/html-templates/index.html b/platform/app/public/html-templates/index.html index 9853c121a65..eb53fc851c8 100644 --- a/platform/app/public/html-templates/index.html +++ b/platform/app/public/html-templates/index.html @@ -42,6 +42,10 @@ name="msapplication-config" content="<%= PUBLIC_URL %>assets/browserconfig.xml" /> + -