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

Adds requestIdleCallback to vdom/component #409

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,23 @@ extend(Component.prototype, {
// return true;
// },

/** Sets a `requestIdleCallback` id on the component. If there are
* repeated calls to render the component (and the component is set to render
* asynchronously), the existing rIC callback will be cancelled using this id.
*
* @private
*/
set renderId (id) {
this._id = id;
},

/** Gets the stored `requestIdleCallback` id.
*
* @private
*/
get renderId () {
return this._id || null;
},

/** Returns a function that sets a state property when called.
* Calling linkState() repeatedly with the same arguments returns a cached link function.
Expand Down
74 changes: 51 additions & 23 deletions src/vdom/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,39 +17,67 @@ import { removeNode } from '../dom/index';
* @param {boolean} [opts.render=true] If `false`, no render will be triggered.
*/
export function setComponentProps(component, props, opts, context, mountAll) {
if (component._disable) return;
component._disable = true;

if ((component.__ref = props.ref)) delete props.ref;
if ((component.__key = props.key)) delete props.key;
const requestIdleCallback =
typeof window !== 'undefined' &&
typeof window.requestIdleCallback !== 'undefined' ?
window.requestIdleCallback :
null;

if (!component.base || mountAll) {
if (component.componentWillMount) component.componentWillMount();
}
else if (component.componentWillReceiveProps) {
component.componentWillReceiveProps(props, context);
}
const cancelIdleCallback =
requestIdleCallback !== 'null' ?
Copy link

Choose a reason for hiding this comment

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

'null'? Did you mean null?

requestIdleCallback !== null

Copy link
Member

Choose a reason for hiding this comment

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

whoops!

Copy link
Author

Choose a reason for hiding this comment

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

Nah, I didn't. I did a typeof test earlier on, and that carried through. Awwwwkward.

Copy link

@alekseychikin alekseychikin Nov 22, 2016

Choose a reason for hiding this comment

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

@paullewis you did return window.requestIdleCallback to const requestIdleCallback if typeof window !== 'undefined' && typeof window.requestIdleCallback !== 'undefined'. So, now requestIdleCallback contains a function or null. Not a typeof from earlier test.

Copy link

Choose a reason for hiding this comment

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

@MakingOff is right, requestIdleCallback will be null not 'null' when window.requestIdleCallback is not defined, so cancelIdleCallback will be undefined instead of null in that case.

screen shot 2016-12-02 at 3 47 44 pm

It doesn't actually cause an error since cancelIdleCallback is never called when requestIdleCallback is not defined, but still worth fixing 😄

window.cancelIdleCallback :
null;

if (context && context!==component.context) {
if (!component.prevContext) component.prevContext = component.context;
component.context = context;
let handler = cb => cb();

// Only support async if rIC is supported and the component requests it.
if (requestIdleCallback && component.renderAsync) {
handler = requestIdleCallback;

// Remove any pending requests for this component.
if (component.renderId) {
cancelIdleCallback(component.renderId);
}
}

if (!component.prevProps) component.prevProps = component.props;
component.props = props;
component.renderId = handler(() => {
component.renderId = null;

if (component._disable) return;
component._disable = true;

component._disable = false;
if ((component.__ref = props.ref)) delete props.ref;
if ((component.__key = props.key)) delete props.key;

if (opts!==NO_RENDER) {
if (opts===SYNC_RENDER || options.syncComponentUpdates!==false || !component.base) {
renderComponent(component, SYNC_RENDER, mountAll);
if (!component.base || mountAll) {
if (component.componentWillMount) component.componentWillMount();
}
else {
enqueueRender(component);
else if (component.componentWillReceiveProps) {
component.componentWillReceiveProps(props, context);
}

if (context && context!==component.context) {
if (!component.prevContext) component.prevContext = component.context;
component.context = context;
}

if (!component.prevProps) component.prevProps = component.props;
component.props = props;

component._disable = false;

if (opts!==NO_RENDER) {
if (opts===SYNC_RENDER || options.syncComponentUpdates!==false || !component.base) {
renderComponent(component, SYNC_RENDER, mountAll);
}
else {
enqueueRender(component);
}
}
}

if (component.__ref) component.__ref(component);
if (component.__ref) component.__ref(component);
});
}


Expand Down