diff --git a/package.json b/package.json index e843d0f133..cfdf5851a6 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,6 @@ "cli-spinners": "^1.0.0", "clipboard-js": "^0.3.6", "css-loader": "^1.0.1", - "html2canvas": "^1.0.0-alpha.12", "error-stack-parser": "^2.0.2", "es6-symbol": "3.0.2", "escape-string-regexp": "^1.0.5", @@ -81,10 +80,12 @@ "flow-bin": "^0.94.0", "fs-extra": "^3.0.1", "gh-pages": "^1.0.0", + "html2canvas": "^1.0.0-alpha.12", "immutable": "3.7.6", "jest": "22.1.4", "lerna": "^2.8.0", "lint-staged": "^7.0.5", + "lodash.throttle": "^4.1.1", "log-update": "^2.0.0", "lru-cache": "^4.1.3", "memoize-one": "^3.1.1", diff --git a/src/devtools/store.js b/src/devtools/store.js index 69dbf45133..225f9a8ac8 100644 --- a/src/devtools/store.js +++ b/src/devtools/store.js @@ -1,6 +1,8 @@ // @flow import EventEmitter from 'events'; +import memoize from 'memoize-one'; +import throttle from 'lodash.throttle'; import { TREE_OPERATION_ADD, TREE_OPERATION_RECURSIVE_REMOVE_CHILDREN, @@ -35,6 +37,8 @@ const debug = (methodName, ...args) => { const LOCAL_STORAGE_CAPTURE_SCREENSHOTS_KEY = 'React::DevTools::captureScreenshots'; +const THROTTLE_CAPTURE_SCREENSHOT_DURATION = 500; + type Config = {| isProfiling?: boolean, supportsCaptureScreenshots?: boolean, @@ -129,8 +133,8 @@ export default class Store extends EventEmitter { if (supportsCaptureScreenshots) { this._supportsCaptureScreenshots = true; this._captureScreenshots = - localStorage.getItem(LOCAL_STORAGE_CAPTURE_SCREENSHOTS_KEY) !== - 'false'; + localStorage.getItem(LOCAL_STORAGE_CAPTURE_SCREENSHOTS_KEY) === + 'true'; } if (supportsFileDownloads) { this._supportsFileDownloads = true; @@ -416,6 +420,13 @@ export default class Store extends EventEmitter { this.emit('isProfiling'); } + _captureScreenshot = throttle( + memoize((commitIndex: number) => { + this._bridge.send('captureScreenshot', { commitIndex }); + }), + THROTTLE_CAPTURE_SCREENSHOT_DURATION + ); + _takeProfilingSnapshotRecursive = (id: number) => { const element = this.getElementByID(id); if (element !== null) { @@ -454,10 +465,9 @@ export default class Store extends EventEmitter { profilingOperations.push(operations); } - const commitIndex = profilingOperations.length - 1; - if (this._captureScreenshots) { - this._bridge.send('captureScreenshot', { commitIndex }); + const commitIndex = profilingOperations.length - 1; + this._captureScreenshot(commitIndex); } } diff --git a/src/devtools/views/Profiler/SidebarCommitInfo.css b/src/devtools/views/Profiler/SidebarCommitInfo.css index a9bd56a2e7..6e99ac4ff3 100644 --- a/src/devtools/views/Profiler/SidebarCommitInfo.css +++ b/src/devtools/views/Profiler/SidebarCommitInfo.css @@ -79,3 +79,13 @@ border: 1px solid var(--color-border); border-radius: 0.5rem; } + +.NoScreenshot { + width: 100%; + height: 200px; + background-color: var(--color-button-background-focus); + border-radius: 0.25rem; + display: flex; + align-items: center; + justify-content: center; +} diff --git a/src/devtools/views/Profiler/SidebarCommitInfo.js b/src/devtools/views/Profiler/SidebarCommitInfo.js index 86debc8e04..a786d6e8db 100644 --- a/src/devtools/views/Profiler/SidebarCommitInfo.js +++ b/src/devtools/views/Profiler/SidebarCommitInfo.js @@ -18,7 +18,11 @@ export default function SidebarCommitInfo(_: Props) { selectTab, } = useContext(ProfilerContext); - const { profilingCache, profilingScreenshots } = useContext(StoreContext); + const { + captureScreenshots, + profilingCache, + profilingScreenshots, + } = useContext(StoreContext); const screenshot = selectedCommitIndex !== null @@ -97,14 +101,20 @@ export default function SidebarCommitInfo(_: Props) { ))} - {screenshot != null && ( + {captureScreenshots && (