-
Notifications
You must be signed in to change notification settings - Fork 134
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
Move things around, make the navigation calculation run in seperate thread #955
Move things around, make the navigation calculation run in seperate thread #955
Conversation
5f2323f
to
e3f0e48
Compare
Codecov Report
@@ Coverage Diff @@
## master #955 +/- ##
==========================================
- Coverage 52.58% 51.12% -1.46%
==========================================
Files 53 56 +3
Lines 1046 1021 -25
Branches 212 200 -12
==========================================
- Hits 550 522 -28
- Misses 395 396 +1
- Partials 101 103 +2
|
15a35d0
to
fc26489
Compare
@@ -12,172 +12,126 @@ import './Navigation.scss'; | |||
|
|||
const basepath = document.baseURI; | |||
|
|||
const openshiftLinks = { | |||
supportcases: { | |||
const extraLinks = { |
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 make sure the Documentation link is always the last one?
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.
Sure thing! I've made it to match what was here previously, but I've seen the ticket about matching position of all docs link everywhere.
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.
Awesome. That got merged in with #942 so I just wanted to make sure we didn't revert what we just committed 😄
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.
There is a definite improvement. I took a look at the react profiler and these are some of the observations.
Before
We have 3 renders on the initial load. The final render is committed around 3s. The number will never be precise.
After
We now have 4 renders but committed at around 1.6s so the cut on initial render time about 50% on my machine. 🎉
The biggest "bottleneck" I see is the transition from loaders to the actual navigation. That is mostly caused by evaluating the YAML file which seems to be quite an expensive operation. The jump between commits is 0.4s to 1.6s and that is with cached main.yml file.
@karelhala could we just store the nav JSON structure to sessionStorage and give it a couple of hours of timeout? Or use the same cache strategy as for the YAML file? This would further decrease the time to first interactive.
Edit: here is a gif where you can see the time commits. As you can see, it only takes around 20ms to render the whole nav from the JSON. But it takes around 1.2s to actually evaluate the code itself.
src/js/App/Header/Loader.js
Outdated
|
||
const HeaderLoader = () => <React.Fragment />; | ||
|
||
export default HeaderLoader; |
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.
You can just export React.Fragment
. No need for additional node in the VirtualDOM.
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 wanted to use some fancy loader similiar to navigation, but had hard time doing it. Let's nuke this file and use just Fragment there.
SideNav.propTypes = { | ||
activeTechnology: PropTypes.string, | ||
globalNav: PropTypes.arrayOf(PropTypes.shape({ | ||
[PropTypes.string]: PropTypes.any |
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 think you should list all used attributes instead of creating a generic object. If you want that just use PropTypes.object
.
@@ -10,24 +13,24 @@ export let getNavFromConfig = async (masterConfig) => { | |||
}, {}); | |||
}; | |||
|
|||
const isCurrVisible = (permissions) => Promise.all( | |||
flatMap([permissions], ({ method } = {}) => ( | |||
// (null, undefined, true) !== false |
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.
leftover comment?
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.
Not really, this is to show what is actually evalueted here because the boolean logic is slightly more complex than it could be for new commers.
src/js/nav/globalNav.js
Outdated
const isCurrVisible = (permissions) => Promise.all( | ||
flatMap([permissions], ({ method } = {}) => ( | ||
// (null, undefined, true) !== false | ||
visibilityFunctions?.[method]?.(...permissions.args || []) !== false || false |
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 don't think the || false
is necessary here. x !== false
will always return boolean value. Or am I crazy 😆 I must say this makes me think much harder than it should.
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.
Yeah, the false is not necessary here, the logic is if visibility function return something else then false return true, otherwise false
. But that's correct and doesn't need the || false
src/js/nav/globalNav.js
Outdated
const groupedNav = await getNavFromConfig(safeLoad(yamlConfig)); | ||
|
||
const [active, section] = [getUrl('bundle'), getUrl('app')]; | ||
const globalNav = (groupedNav[active] || groupedNav.insights).routes; |
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 has the potential to crash. I would add ?.
src/js/nav/globalNav.js
Outdated
|
||
const [active, section] = [getUrl('bundle'), getUrl('app')]; | ||
const globalNav = (groupedNav[active] || groupedNav.insights).routes; | ||
let activeSection = globalNav.find(({ id }) => id === section); |
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.
activeSection
is never re-assigned.
@Hyperkid123 I was thinking about storing the calculated JSON in cache as well, but didn't wanted to bloat this PR even more. But let's do it to improve loads even more! |
@karelhala We can do it in different PR if you want. It will make it easier to review and test. |
3b50bf9
to
c4dc7b6
Compare
1967bfd
to
bf437b5
Compare
@@ -244,7 +244,7 @@ exports[`Navigation should render corectly 1`] = ` | |||
ariaRightScroll="Scroll right" | |||
> | |||
<NavExpandable | |||
className="ins-m-navigation-align" |
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 css is required to fix the navigation text left alignment. Kan you keep it? (introduced in #958)
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.
Sure thing!
bf437b5
to
9b18f26
Compare
Features
Depracated
disabled_on_stable
- this field should no longer be used as consumers can use permissions function