-
Notifications
You must be signed in to change notification settings - Fork 14.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: reset perf logger timer for soft navigation for SPA pages #16668
fix: reset perf logger timer for soft navigation for SPA pages #16668
Conversation
Codecov Report
@@ Coverage Diff @@
## master #16668 +/- ##
==========================================
- Coverage 76.90% 76.89% -0.02%
==========================================
Files 1005 1005
Lines 54007 54016 +9
Branches 7337 7338 +1
==========================================
Hits 41536 41536
- Misses 12231 12240 +9
Partials 240 240
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a few comments
resetStartTime() { | ||
this.softNavigationStart = window.performance.now(); | ||
}, | ||
|
||
// note that this returns ms since page load, NOT ms since epoch |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// note that this returns ms since page load, NOT ms since epoch | |
// note that this returns ms since last navigation, NOT ms since epoch |
superset-frontend/src/views/App.tsx
Outdated
@@ -43,26 +49,39 @@ const bootstrap = JSON.parse(container?.getAttribute('data-bootstrap') ?? '{}'); | |||
const user = { ...bootstrap.user }; | |||
const menu = { ...bootstrap.common.menu_data }; | |||
const common = { ...bootstrap.common }; | |||
let lastLocation: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we call this lastLocationPathname
or lastPathname
to make it more clear?
superset-frontend/src/views/App.tsx
Outdated
useEffect(() => { | ||
// reset performance logger timer start point to avoid soft navigation | ||
// cause dashboard perf measurement problem | ||
if (lastLocation && lastLocation !== location.pathname) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a problem for future us, but will this break with slice navigation since viewing slices in explore all have the same pathnames (and instead use url params for switching which slice you're on)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
switch between slices is not a big concern for me, because in the explore view page, there is no link out to other slice(s). Like dashboard, most use cases are switching between list page and dashboard. Right now click on +
button to create new slice/dashboard, are all hard navigation.
Thanks for the fix! +1 on making perf tracking more accurate. Is there a way in current tracking setup to distinguish between "hard landing" and "soft navigation"s? If possible, some example SQL queries on the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a valid stop-gap solution, but in the future, it might be more useful to utilize browser API like Performance.mark and Performance.measure to get even more accurate perf logging.
superset-frontend/src/views/App.tsx
Outdated
@@ -34,6 +39,7 @@ import { theme } from 'src/preamble'; | |||
import ToastPresenter from 'src/messageToasts/containers/ToastPresenter'; | |||
import setupApp from 'src/setup/setupApp'; | |||
import { routes, isFrontendRoute } from 'src/views/routes'; | |||
import { Logger } from '../logger/LogUtils'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use absolute imports.
superset-frontend/src/views/App.tsx
Outdated
useEffect(() => { | ||
// reset performance logger timer start point to avoid soft navigation | ||
// cause dashboard perf measurement problem | ||
if (lastLocation && lastLocation !== location.pathname) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lastLocation
is a Location
object so lastLocation !== location.pathname
will always be true. Plus comparing with last location is not needed because useEffect
already only triggers when the dependency [location.pathname]
updates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lastLocation is actually the pathname (see line 63) :P that's why i made a comment about variable naming
</ReduxProvider> | ||
</ThemeProvider> | ||
); | ||
const RootContextProviders: React.FC = ({ children }) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of putting this in RootContextProviders
, it might be more appropriate to put the logic into App
itself----the logger is not exactly a provider.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic needs to stay with global route change. Do you mean to move this logic to root dashboard / list / welcome etc, each component?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean move it to the App
component in L86.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we chatted a little bit offline. Based on current way we use <Router>
and <RootContextProviders>
, keep this logic inside is probably the best solution.
superset-frontend/src/views/App.tsx
Outdated
@@ -43,26 +49,39 @@ const bootstrap = JSON.parse(container?.getAttribute('data-bootstrap') ?? '{}'); | |||
const user = { ...bootstrap.user }; | |||
const menu = { ...bootstrap.common.menu_data }; | |||
const common = { ...bootstrap.common }; | |||
let lastLocation: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ktmud lastLocation is string type. I think the name is really misleading, i fixed as Erik suggested.
@@ -101,6 +101,7 @@ class Dashboard extends React.PureComponent { | |||
const bootstrapData = appContainer?.getAttribute('data-bootstrap') || ''; | |||
const { dashboardState, layout } = this.props; | |||
const eventData = { | |||
is_soft_navigation: Logger.softNavigationStart > 0, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ktmud i added flag here to track soft navigation or not.
|
||
resetStartTime() { | ||
this.softNavigationStart = window.performance.now(); | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The window.performance
API refers the start time as "time origin", so how about renaming the variables like:
markTimeOrigin() {
this.timeOriginOffset = window.performance.now();
}
getTimestamp() {
return Math.round(window.performance.now() - this.timeOriginOffset);
},
…e#16668) * fix: reset perf logger timer for soft navigation for SPA pages * fix comments * fix extra comments Co-authored-by: grace_guo <grace_guo@grace-guos-MacBook-Pro.local>
…e#16668) * fix: reset perf logger timer for soft navigation for SPA pages * fix comments * fix extra comments Co-authored-by: grace_guo <grace_guo@grace-guos-MacBook-Pro.local>
SUMMARY
We used some features from HTML5 Performance API to track dashboard page load performance. After we started to use SPA to generate and soft navigate between pages, "navigation" is any subsequent route change. Performance API's start point is based on
onload
event, so if user switch between chart list, dash list and dashboard (these pages are built from SPA structure), the old measurement for dashboard page load time is not accurate anymore.This PR uses location to detect soft navigation and reset logging time start point.
BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
BEFORE SPA
AFTER FIX
TESTING INSTRUCTIONS
CI and manual test
ADDITIONAL INFORMATION
cc @etr2460 @ktmud