Skip to content
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: Guard against unnecessary timer rerenders on /artwork/id for closed auction artworks #15053

Closed
wants to merge 1 commit into from

Conversation

damassi
Copy link
Member

@damassi damassi commented Jan 6, 2025

The type of this PR is: Fix

Description

This fixes an issue where we were unnecessarily rerendering the artwork page even if an auction artwork has closed by:

  • Checking if the artwork is still open auction-wise
  • adjusting the function signature of useTimer and useCurrentTime by adding an additional enabled prop
  • adding an enabled prop to the AuctionWebsocket context and checking if we should enable it

Additionally:

  • fixes yarn scan by downgrading the lib to a working version (something broke in the latest, which made it so that we couldn't see rerenders. Fixed it 0.0.39
  • bumped rsbuild because there's some memory improvements. Triggered an OOM issue after all of the saves trying to debug this.

cc @artsy/diamond-devs

@damassi damassi requested a review from a team January 6, 2025 22:58
@damassi damassi force-pushed the review-app-inp-artwork branch from 04b4650 to 8442c61 Compare January 6, 2025 22:59
Copy link

relativeci bot commented Jan 6, 2025

#1440 Bundle Size — 8.98MiB (+0.02%).

fa11f36(current) vs dfdda0e main#1433(baseline)

Warning

Bundle contains 14 duplicate packages – View duplicate packages

Bundle metrics  Change 2 changes Regression 1 regression
                 Current
#1440
     Baseline
#1433
Regression  Initial JS 3.66MiB(~+0.01%) 3.66MiB
No change  Initial CSS 0B 0B
Change  Cache Invalidation 77.36% 43.2%
No change  Chunks 103 103
No change  Assets 106 106
No change  Modules 5842 5842
No change  Duplicate Modules 529 529
No change  Duplicate Code 4.02% 4.02%
No change  Packages 266 266
No change  Duplicate Packages 13 13
Bundle size by type  Change 1 change Regression 1 regression
                 Current
#1440
     Baseline
#1433
Regression  JS 8.84MiB (+0.02%) 8.84MiB
No change  Other 143.36KiB 143.36KiB

Bundle analysis reportBranch review-app-inp-artworkProject dashboard


Generated by RelativeCIDocumentationReport issue

@damassi damassi force-pushed the review-app-inp-artwork branch from 8442c61 to 67b6c5a Compare January 6, 2025 23:09
@damassi damassi force-pushed the review-app-inp-artwork branch from 67b6c5a to fa11f36 Compare January 6, 2025 23:20
Copy link
Contributor

@joeyAghion joeyAghion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like you I was surprised this was so tricky. Left a few questions but am not familiar enough with this logic to guide.


const websocketEnabled = !!sale?.extendedBiddingIntervalMinutes
const websocketEnabled =
!!sale?.extendedBiddingIntervalMinutes && isLotClosed === false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haven't totally grokked this, but does this imply that a sale without extended bidding will always skip polling?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be ||

const partnerOfferTimer = useTimer(partnerOffer?.endAt || THE_PAST)
const partnerOfferTimer = useTimer({
endDate: partnerOffer?.endAt || THE_PAST,
enabled: !isLotClosed,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be based on the offer rather than lot status?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just set up so that if the lot is closed, we don't poll. I'm not too sure beyond that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me that we can just have use timer disable itself once it reaches the end date. And then we wouldn't need to explicitly enable or disable in these cases.

}

export const useCurrentTime = ({
interval = 1000,
interval = 5000,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is used to display so at the very least, that usage of it needs the 1 second interval

@@ -15,6 +15,7 @@ import { ArtworkErrorApp } from "Apps/Artwork/Components/ArtworkErrorApp/Artwork
import { ArtworkPageBanner } from "Apps/Artwork/Components/ArtworkPageBanner"
import { PrivateArtworkDetails } from "Apps/Artwork/Components/PrivateArtwork/PrivateArtworkDetails"
import { SelectedEditionSetProvider } from "Apps/Artwork/Components/SelectedEditionSetContext"
import { lotIsClosed } from "Apps/Artwork/Utils/lotIsClosed"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Finding it surprising that there's no field to determine if a lot is closed in Metaphysics

const { hasEnded } = useTimer({
endDate: biddingEndAt as string,
startAt: artwork?.sale?.startAt as string,
enabled: !initialIsLotClosedCheck,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thing about this entire approach is that we're not polling on the status right? So if you load the page before it starts the status will be closed and then if startAt comes to pass it will never enable.

@dzucconi
Copy link
Member

dzucconi commented Jan 9, 2025

Disabling the timer means it won't ever initialize if the page loads before startAt. The performance impact of once-per-second renders is negligible in real-world scenarios. If we do want to optimize this, we should focus on tightly scoping the renders by encapsulating the timers and components to avoid parent context interference.

@damassi
Copy link
Member Author

damassi commented Jan 15, 2025

Gonna close this because in the end it had no impact on INP. Thanks for the detailed comments everyone; we can return to this if / when we want to optimize.

@damassi damassi closed this Jan 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants