-
Notifications
You must be signed in to change notification settings - Fork 581
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
feat: Introduce RouterLink component to prefetch links as they enter the viewport #11293
base: main
Are you sure you want to change the base?
feat: Introduce RouterLink component to prefetch links as they enter the viewport #11293
Conversation
src/app/Components/RouterLink.tsx
Outdated
|
||
return ( | ||
<ElementInView onVisible={handleVisible}> | ||
<Touchable {...restProps} onPress={handlePress} /> |
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 wonder here if Touchable
would be our preferred way, sometimes we use TouchableOpacity
and sometimes we use TouchableWithoutHighlight
.
Anyway, that's a problem for later, we can start with this now and extend it later.
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 this is a call to use RouterTouchableOpacity
🤷
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 used the Touchable
component from "@artsy/palette-mobile" and figured this is probably the preferred one. It has a prop to adjust the opacity on press.
Yeah, RouterTouchableOpacity
or RouterTouchable
could also be good names for this component. I took the name RouterLink
from Force but haven't thought much about naming yet. I'm very open for ideas for the naming.
f26a274
to
2cfaa76
Compare
1104fed
to
d93009a
Compare
346d855
to
9e354b2
Compare
to: string | null | undefined | ||
} | ||
|
||
export const RouterLink: React.FC<RouterLinkProps & TouchableProps> = ({ |
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've named the component RouterLink
, as it is called in Force (routerlink.ts). But I am open to other suggestions regarding the naming. Another name I find quite good for this component is AppLink
.
fbbd649
to
3a7712b
Compare
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.
Thanks for this addition. I left few suggestions - I would leave to use to decide if they're worth the effort
@@ -46,6 +46,7 @@ const prefetchRoute = async <TQuery extends OperationType>( | |||
const allVariables = { ...result.params, ...variables } | |||
|
|||
return queries.map((query) => { | |||
console.log("[queryPrefetching] Prefetching:", route, JSON.stringify(allVariables)) |
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 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.
Thanks! This doesn't need to be here. Just used it for debugging.
@@ -8,7 +8,7 @@ import { fetchQuery, GraphQLTaggedNode } from "react-relay" | |||
import { OperationType, Variables, VariablesOf } from "relay-runtime" | |||
import { logPrefetching } from "./loggers" | |||
|
|||
const DEFAULT_QUERIES_PER_INTERVAL = 60 | |||
const DEFAULT_QUERIES_PER_INTERVAL = 180 |
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.
👍
const handlePress = (event: GestureResponderEvent) => { | ||
onPress?.(event) | ||
|
||
if (!to) return | ||
|
||
if (passProps) { | ||
navigate(to, { passProps }) | ||
} else { | ||
navigate(to) | ||
} | ||
} |
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.
thought: I don't have strong opinions about your approach here but I would have approached this differently for the benefit of more flexibility.
I would have left handlePress={props.onPress}
to allow us to have full flexibility about taps and to be able as well to disable router links without much code added and handle the navigate
event from within the component that uses RouterLink
. And, I would use to
only for prefetching the url.
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.
That's a very interesting thought! I approached it this way to simplify how we implement links (similar to the web) while still having the full flexibility of onPress
.
Do you have an example from the app where we would not be able to use the new to
prop?
If it's just an edge case, then the workaround could be to do the navigation in onPress
and not use to
and not prefetch
} | ||
|
||
return ( | ||
<ElementInView onVisible={handleVisible}> |
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 lot of the computation gets triggered here. I would also suggest to wrap the component behind the same enableViewPortPrefetching
feature flag.
Maybe something like
Wrapper = enableViewPortPrefetching ? ElementInView : Touchable
(maybe not exactly like that)
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 is a good idea and could be useful if the change affects performance too much 👍
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.
beautiful 👏
This PR resolves ONYX-1461
Description
This PR introduces a
RouterLink
component that wraps Palette'sTouchable
and takes an extrato
prop with a URL or path to link to.The reason for introducing the new
RouterLink
component is to be able to prefetch (all) app links as they enter the viewport, similar to how it's implemented in Force (artsy/force#14520 & artsy/force#14454).If prefetching is enabled, the component automatically prefetches the URL with Relay as soon as it enters the viewport.
The new
RouterLink
component will replacePrefetchFlatList
, which is also capable of prefetching links as they enter the viewport, but is limited and cannot be used as universally as the new link component.Next Steps:
RouterLink
component in more placesroutes.ts
Screenshots / Videos
Bildschirmaufnahme.2025-01-09.um.10.54.00.mov
PR Checklist
To the reviewers 👀
Changelog updates
Changelog updates
Cross-platform user-facing changes
iOS user-facing changes
Android user-facing changes
Dev changes
Need help with something? Have a look at our docs, or get in touch with us.