Repository navigation
News Site - Navigation workload - #167
Conversation
|
@rniwa - could you try one more time for me? |
|
Hm... I'm still hitting this error in Safari midway through the suite: |
ah - I can't repro on my machine. |
| }, | ||
| tests: [ | ||
| new BenchmarkTestStep("NavigateToUS", (page) => { | ||
| page.querySelector("#close-toast-link").click(); |
There was a problem hiding this comment.
We discussed this a bit before, but I have been considering if we should to force a layout in between each of these actions within a step. I believe this would create a more realistic workload for this type of test. While opening and immediately closing the navbar will create React and DOM work there won't be any layout required, while in practice a user discreetly clicking the toggle button twice would cause multiple layouts.
An alternative would be to make each step tiny (with a single action in sync time, then taking the forced layout in async time) but I understand there's a practical problem with noise when steps are so short. So I wonder if having a few big steps that run through a bunch of user actions would be a good compromise that allows them to be heavy enough to be more measurable but also not skipping work that would be happening if they were individual steps.
page.querySelector("#close-toast-link").click();
page.layout();
page.querySelector("#navbar-dropdown-toggle").click();
page.layout();
// and so on, possibly containing actions from multiple of the current BenchmarkTestSteps if there is a logical grouping
I'm curious for thoughts from others on the idea (cc @rniwa @camillobruni @smaug----)
There was a problem hiding this comment.
Forcing layouts after each click seems like a reasonable compromise to me since splitting work into multiple pieces can also lead to CPU getting throttled down.
There was a problem hiding this comment.
@bgrins - just to ensure I am making the right change - instead of multiple test steps, we'd have just one and calling the page.layout() function in between each action?
There was a problem hiding this comment.
Yes, something like that is what I was thinking
|
I like the shape of this test and think it adds some good coverage for the benchmark, thanks @flashdesignory! Will give @julienw a chance to make any comments on the code or the generated site itself (https://news-thor-next--speedometer-preview.netlify.app/resources/tentative/newssite/news-next/dist/), although I know there are a number of other items from the repo on his plate so we can discuss as a group on Wednesday how to sequence this if he doesn't have a chance to in the meantime (i.e. if we should just land in tentative and then take any issues as follow ups, or keep it as a PR until then). |
julienw
left a comment
There was a problem hiding this comment.
This looks pretty good to me. I just left a few comments, but it's not clear to me what was generated and what was written by you, so feel free to ignore them..
Also I profiled locally and it doesn't seem to me that we're losing any work in the user timing marks. To be honest I'm a bit surprised because this uses React 18, I was expecting things to be more asynchronous :-)
| <div className="article-content"> | ||
| <ul className={`article-list vertical ${display ?? ""}`}> | ||
| {content.map((item, index) => | ||
| <li key={`article-list-item-${index}`} className="article-list-item"> |
There was a problem hiding this comment.
Normally we shouldn't use the index as the key, rather we should use something that represents this article. Maybe its URL?
Otherwise React will update everything when the order changes for any reason. But maybe that's not a big deal in this context, because the content doesn't change actually? You know better than me.
(ditto in all other similar cases below)
| {item.url ? <a href={item.url}> | ||
| <ArticleText className="article-content truncate-multiline truncate-multiline-3" text={item.text} type="h3"/></a> |
There was a problem hiding this comment.
Indentation looks a bit weird here. I think that prettier+eslint ignores this code currently, it would be good to enable it right now.
There was a problem hiding this comment.
I'll take a look - thanks for flagging!
| return null; | ||
|
|
||
| const Tag = type; | ||
| return <Tag className={`${className ?? ""}`}>{text}</Tag>; |
There was a problem hiding this comment.
| return <Tag className={`${className ?? ""}`}>{text}</Tag>; | |
| return <Tag className={className ?? ""}>{text}</Tag>; |
or maybe even
| return <Tag className={`${className ?? ""}`}>{text}</Tag>; | |
| return <Tag className={className}>{text}</Tag>; |
(as when it's undefined or null, then I believe that the attribute just isn't added)
| // Since the navbar is supposed to appear below the menu, we can't use position: fixed, height: 100%. | ||
| // Therefore we are using 100vh for the height. This function fixes the challenge on mobile, where | ||
| // 100vh might include the addressbar, ect. |
There was a problem hiding this comment.
I'm not following completely, but would one of the newer units (such as dvh) be useful here? The support looks good enough, and I'd be interested in seeing this in the benchmark. What do you think?
There was a problem hiding this comment.
Yeah, there are newer units, but I think this still represents a larger amount of websites using this approach.
The only downside is that it's using JavaScript to set the custom property in CSS, but that's really common.
It's working and I think it's ok to keep and maybe follow up at a later point with a newer approach.
There was a problem hiding this comment.
I'm fine with keeping the current code as well
| const [navItems, dropdownItems] = keys.reduce( | ||
| (result, key) => { | ||
| // priority 0 does not show up in nav | ||
| if (content[key].priority === 0) | ||
| return result; | ||
|
|
||
| // priority 1 shows up in nav list | ||
| // priority 2 shows up in nav dropdown | ||
| result[content[key].priority === 1 ? 0 : 1].push(key); | ||
| return result; | ||
| }, | ||
| [[], []] | ||
| ); |
There was a problem hiding this comment.
optional nit: I think this would be clearer using an object with explicit properties, rather than a tuple.
There was a problem hiding this comment.
I could do something like this:
const navItems = [];
const dropdownItems = [];
keys.forEach(key => {
if (content[key].priority === 1)
navItems.push(key);
else if (content[key].priority === 2)
dropdownItems.push(key);
});
There was a problem hiding this comment.
pushed above snippet for review
| useEffect(() => { | ||
| setIsSelected(checked); | ||
| }, [checked]); |
There was a problem hiding this comment.
It's not clear to me why we need a local state instead of using directly the prop checked.
There was a problem hiding this comment.
The toggle component uses a "checked" prop, which will let us assign the initial state, or change the toggle from a parent component.
| function App({ Component, pageProps }) { | ||
| const [render, setRender] = useState(false); | ||
| useEffect(() => setRender(true), []); | ||
| return render ? <Component {...pageProps} /> : null; | ||
| } |
There was a problem hiding this comment.
It's not clear to me what the intent of this is. Have you written this or is that generated?
There was a problem hiding this comment.
ah, yes, this tripped me off too.
This next.js app uses static files, and this piece of code ensures that next.js doesn't try to render anything "on the server". With the useEffect, we ensure this code can only run client-side.
| async prepare(page) { | ||
| await page.waitForElement("#close-toast-link"); | ||
| }, |
There was a problem hiding this comment.
Can you look whether we can have the initial rendering (including rehydration!) in the tests step instead of in the prepare phase? This would be really good for the benchmark IMO.
There was a problem hiding this comment.
it's static files, no server-side phase is present in this build.
We should treat it the same as other static apps.
|
Looking good from my side, module sync-step length. |
Done in the last commit - thanks @camillobruni |
Co-authored-by: Kara <kara@users.noreply.github.com>
0dc6ee9 to
be5de90
Compare
This reverts commit 372bd7a.

News site built with next.js, using its static export feature.
To visualize the test - stepping through breakpoints:

@kara