Skip to content

Expiration times#10426

Merged
acdlite merged 10 commits into
react:masterfrom
acdlite:expiration
Oct 10, 2017
Merged

Expiration times#10426
acdlite merged 10 commits into
react:masterfrom
acdlite:expiration

Conversation

@acdlite

@acdlite acdlite commented Aug 9, 2017

Copy link
Copy Markdown
Collaborator

An expiration time represents a time in the future by which an update should flush. The priority of the update is related to the difference between the current clock time and the expiration time. This has the effect of increasing the priority of updates as time progresses, to prevent starvation.

@acdlite acdlite changed the title [Work-in-progress] Assign expiration times to updates [Work-in-progress] Expiration times Aug 9, 2017
@acdlite acdlite mentioned this pull request Aug 10, 2017
17 tasks
@acdlite acdlite force-pushed the expiration branch 3 times, most recently from ee127ed to 796db96 Compare August 10, 2017 22:46
@acdlite acdlite requested a review from sebmarkbage August 11, 2017 14:28
@acdlite

acdlite commented Aug 11, 2017

Copy link
Copy Markdown
Collaborator Author

Confirms that this makes the Triangle demo work as expected. Still need to write some unit tests, but this is ready for review.

@acdlite acdlite changed the title [Work-in-progress] Expiration times Expiration times Aug 11, 2017
@acdlite

acdlite commented Aug 11, 2017

Copy link
Copy Markdown
Collaborator Author

Added unit tests. I confirmed that all the existing tests, including the sync DOM ones, are passing when expiration is enabled.

getPublicInstance,

now(): number {
// Test renderer does not use expiration

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@sebmarkbage I went back and forth on whether this should be an optional method. Landed on making it required because all renderers will need to account for features like expiration boundaries.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Since scheduleDeferredCallback is required it seems reasonable that this would be too since they kind of pair together.

return false;
}

// TODO: Better polyfill

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Is this polyfill sufficient? Or am I overlooking something?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It's fine. Maybe we should colocate it with ReactDOMFrameScheduling to have all these in one place?

It is also performance.now aware: https://github.com/facebook/react/blob/master/src/renderers/shared/ReactDOMFrameScheduling.js#L73

@acdlite acdlite force-pushed the expiration branch 2 times, most recently from 67388a1 to 14e68e3 Compare August 11, 2017 22:08
window.performance &&
typeof window.performance.now === 'function'
) {
now = function() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why not now = performance.now and now = Date.now?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

performance.now needs to be bound, but looks like Date.now doesn't. I'll update.

} = ReactTypeOfWork;
var {Placement, Ref, Update} = ReactTypeOfSideEffect;
var {OffscreenPriority} = ReactPriorityLevel;
var {Never} = ReactFiberExpirationTime;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I like that this name change decouples this expiration time from the UI context in which it's used. What we really mean is 'this might never finish updating, and that's ok' and that may or may not be literally "offscreen" in the UI.

TaskPriority,
HighPriority,
LowPriority,
OffscreenPriority,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

haha, I guess it's not a rename after all. ("OffscreenPriority" to "Never" expirationTime)

@reactjs-bot

reactjs-bot commented Sep 28, 2017

Copy link
Copy Markdown

Deploy preview ready!

Built with commit 564c7e9

https://deploy-preview-10426--reactjs.netlify.com

@acdlite

acdlite commented Sep 29, 2017

Copy link
Copy Markdown
Collaborator Author

@gaearon I’ve rebased this locally, just haven’t pushed yet. I’ll work on getting all my PRs updated tomorrow.

This was referenced Nov 8, 2024
mrizwanashiq pushed a commit to mrizwanashiq/react that referenced this pull request Jun 25, 2026
* [Work-in-progress] Assign expiration times to updates

An expiration time represents a time in the future by which an update
should flush. The priority of the update is related to the difference
between the current clock time and the expiration time. This has the
effect of increasing the priority of updates as time progresses, to
prevent starvation.

This lays the initial groundwork for expiration times without changing
any behavior. Future commits will replace work priority with
expiration times.

* Replace pendingWorkPriority with expiration times

Instead of a priority, a fiber has an expiration time that represents
a point in the future by which it should render.

Pending updates still have priorities so that they can be coalesced.

We use a host config method to read the current time. This commit
implements everything except that method, which currently returns a
constant value. So this just proves that expiration times work the same
as priorities when time is frozen. Subsequent commits will show the
effect of advancing time.

* Triangle Demo should use a class

shouldComponentUpdate was removed from functional components.

Running the demo shows, now that expiration is enabled, the demo does
not starve. (Still won't run smoothly until we add back the ability to
resume interrupted work.)

* Use a magic value for task expiration time

There are a few cases related to sync mode where we need to distinguish
between work that is scheduled as task and work that is treated like
task because it expires. For example, batchedUpdates. We don't want to
perform any work until the end of the batch, regardless of how much
time has elapsed.

* Use current time to calculate expiration time

* Add unit tests for expiration and coalescing

* Delete unnecessary abstraction

* Move performance.now polyfill to ReactDOMFrameScheduling

* Add expiration to fuzz tester

* Expiration nits

- Rename Done -> NoWork
- Use max int32 instead of max safe int
- Use bitwise operations instead of Math functions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants