From 993413c5f225acfa9ff4d2d25c7c8fd4b559dc92 Mon Sep 17 00:00:00 2001 From: Luke De Feo Date: Mon, 10 Jul 2023 09:22:39 -0700 Subject: [PATCH] Prefetch IDE resolve query Summary: To avoid showing the Ugly spinner in the context menu as well as a better UX we prefetch the IDE resolved path. It was important to limit the concurrency of the running arc jobs otherwise lots of bad things happen and the whole machine stalls out. The general idea is as the frame comes off the wire we send them to react query to prefetch. by setting the cache time sending the same key twice will not result in 2 fetches, so we dont need to worry about deduplication on our side Reviewed By: antonk52 Differential Revision: D47210292 fbshipit-source-id: 4a1d8efdfae754c1a73c6a868b02d1f3a0a5b567 --- .../components/fb-stubs/IDEContextMenu.tsx | 2 ++ .../public/ui-debugger/components/main.tsx | 3 ++- desktop/plugins/public/ui-debugger/index.tsx | 25 ++++++------------- .../plugins/public/ui-debugger/package.json | 4 +++ .../plugins/public/ui-debugger/reactQuery.tsx | 25 +++++++++++++++++++ desktop/plugins/public/yarn.lock | 14 ++++++++++- 6 files changed, 54 insertions(+), 19 deletions(-) create mode 100644 desktop/plugins/public/ui-debugger/reactQuery.tsx diff --git a/desktop/plugins/public/ui-debugger/components/fb-stubs/IDEContextMenu.tsx b/desktop/plugins/public/ui-debugger/components/fb-stubs/IDEContextMenu.tsx index 577eea27a..9084e29c1 100644 --- a/desktop/plugins/public/ui-debugger/components/fb-stubs/IDEContextMenu.tsx +++ b/desktop/plugins/public/ui-debugger/components/fb-stubs/IDEContextMenu.tsx @@ -11,6 +11,8 @@ import React from 'react'; import {UINode} from '../../types'; +export async function prefetchSourceFileLocation(_: UINode) {} + export function IDEContextMenuItems(_: {node: UINode}) { return <>; } diff --git a/desktop/plugins/public/ui-debugger/components/main.tsx b/desktop/plugins/public/ui-debugger/components/main.tsx index 5b3604d19..23655a9d9 100644 --- a/desktop/plugins/public/ui-debugger/components/main.tsx +++ b/desktop/plugins/public/ui-debugger/components/main.tsx @@ -27,6 +27,7 @@ import {Button, Spin} from 'antd'; import {QueryClientProvider} from 'react-query'; import {Tree2} from './Tree'; import {StreamInterceptorErrorView} from './StreamInterceptorErrorView'; +import {queryClient} from '../reactQuery'; export function Component() { const instance = usePlugin(plugin); @@ -96,7 +97,7 @@ export function Component() { ); } else { return ( - + <> diff --git a/desktop/plugins/public/ui-debugger/index.tsx b/desktop/plugins/public/ui-debugger/index.tsx index 949309284..8024b5507 100644 --- a/desktop/plugins/public/ui-debugger/index.tsx +++ b/desktop/plugins/public/ui-debugger/index.tsx @@ -30,9 +30,9 @@ import { UIState, } from './types'; import {Draft} from 'immer'; -import {QueryClient, setLogger} from 'react-query'; import {tracker} from './tracker'; import {getStreamInterceptor} from './fb-stubs/StreamInterceptor'; +import {prefetchSourceFileLocation} from './components/fb-stubs/IDEContextMenu'; type LiveClientState = { snapshotInfo: SnapshotInfo | null; @@ -265,6 +265,7 @@ export function plugin(client: PluginClient) { } applyFrameworkEvents(frameScan); + return true; } catch (error) { pendingData.frame = frameScan; @@ -339,6 +340,12 @@ export function plugin(client: PluginClient) { checkFocusedNodeStillActive(uiState, nodesAtom.get()); } + setTimeout(() => { + //let react render, this can happen async + for (const node of nodes.values()) { + prefetchSourceFileLocation(node); + } + }, 0); } client.onMessage('subtreeUpdate', (subtreeUpdate) => { processFrame({ @@ -350,8 +357,6 @@ export function plugin(client: PluginClient) { }); client.onMessage('frameScan', processFrame); - const queryClient = new QueryClient({}); - return { rootId, uiState, @@ -362,7 +367,6 @@ export function plugin(client: PluginClient) { metadata, perfEvents, setPlayPause, - queryClient, os, }; } @@ -503,16 +507,3 @@ const HighlightTime = 300; export {Component} from './components/main'; export * from './types'; - -setLogger({ - log: (...args) => { - console.log(...args); - }, - warn: (...args) => { - console.warn(...args); - }, - error: (...args) => { - //downgrade react query network errors to warning so they dont get sent to scribe - console.warn(...args); - }, -}); diff --git a/desktop/plugins/public/ui-debugger/package.json b/desktop/plugins/public/ui-debugger/package.json index f5f44f452..a4d7d463b 100644 --- a/desktop/plugins/public/ui-debugger/package.json +++ b/desktop/plugins/public/ui-debugger/package.json @@ -17,10 +17,14 @@ "react-color": "^2.19.3", "react-hotkeys-hook": "^3.4.7", "react-query": "^3.39.1", + "async": "2.3.0", "@tanstack/react-virtual": "3.0.0-beta.54", "ts-retry-promise": "^0.7.0", "memoize-weak": "^1.0.2" }, + "devDependencies": { + "@types/async": "3.2.20" + }, "bugs": { "url": "https://github.com/facebook/flipper/issues" }, diff --git a/desktop/plugins/public/ui-debugger/reactQuery.tsx b/desktop/plugins/public/ui-debugger/reactQuery.tsx new file mode 100644 index 000000000..b514c9340 --- /dev/null +++ b/desktop/plugins/public/ui-debugger/reactQuery.tsx @@ -0,0 +1,25 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + */ + +import {QueryClient, setLogger} from 'react-query'; + +export const queryClient = new QueryClient({}); + +setLogger({ + log: (...args) => { + console.log('[ui-debugger] ReactQuery ', ...args); + }, + warn: (...args) => { + console.warn('[ui-debugger] ReactQuery ', ...args); + }, + error: (...args) => { + //downgrade react query network errors to warning so they dont get sent to scribe + console.warn('[ui-debugger] ReactQuery ', ...args); + }, +}); diff --git a/desktop/plugins/public/yarn.lock b/desktop/plugins/public/yarn.lock index a359e722c..56c7e9d95 100644 --- a/desktop/plugins/public/yarn.lock +++ b/desktop/plugins/public/yarn.lock @@ -194,6 +194,11 @@ resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.0.tgz#14264692a9d6e2fa4db3df5e56e94b5e25647ac0" integrity sha512-iIgQNzCm0v7QMhhe4Jjn9uRh+I6GoPmt03CbEtwx3ao8/EfoQcmgtqH4vQ5Db/lxiIGaWDv6nwvunuh0RyX0+A== +"@types/async@3.2.20": + version "3.2.20" + resolved "https://registry.yarnpkg.com/@types/async/-/async-3.2.20.tgz#53517caaa68c94f99da1c4e986cf7f2954981515" + integrity sha512-6jSBQQugzyX1aWto0CbvOnmxrU9tMoXfA9gc4IrLEtvr3dTwSg5GLGoWiZnGLI6UG/kqpB3JOQKQrqnhUWGKQA== + "@types/brotli@^1.3.1": version "1.3.1" resolved "https://registry.yarnpkg.com/@types/brotli/-/brotli-1.3.1.tgz#65dc6c69bb9f4159677032f60e81ffc09faf1fce" @@ -401,6 +406,13 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= +async@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/async/-/async-2.3.0.tgz#1013d1051047dd320fe24e494d5c66ecaf6147d9" + integrity sha512-uDDBwBVKsWWe4uMmvVmFiW07K5BmdyZvSFzxlujNBtSJ/qzAlGM6UHOFZsQd5jsdmWatrCMWwYyVAc8cuJrepQ== + dependencies: + lodash "^4.14.0" + atob@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" @@ -1402,7 +1414,7 @@ lodash.throttle@^4.1.1: resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ= -lodash@^4.0.1, lodash@^4.17.15, lodash@^4.17.21: +lodash@^4.0.1, lodash@^4.14.0, lodash@^4.17.15, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==