Skip to content

Question about nextTick, compiler and ready hook #393

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

Closed
ayamflow opened this issue Aug 9, 2014 · 5 comments
Closed

Question about nextTick, compiler and ready hook #393

ayamflow opened this issue Aug 9, 2014 · 5 comments

Comments

@ayamflow
Copy link

ayamflow commented Aug 9, 2014

Might be related to #352.

We've been noticing lately that on some VMs, the ready hook is called but some of its content is not accessible yet (querySelector returning null/empty array, offsetWidth/Height returning 0). Sometime we have to use nextTick to access some template element/properties, and sometime even a double nested nextTick is needed! I'm wondering if this is a bug introduced in v0.10.5 because I never had the issue before.
I think it happens both with and without the use of partials (cf the referenced issue), but I'll check at work to be sure.

I took a look at the source and noticed that the ready hook is executed synchronously after all calls to the compile/compileElement/compileTextNode methods (which are all synchronous, since they manipulate the DOM). So I don't understand the behavior I'm having.

Another question related to nextTick: how does it ensures that all updates will be done when it calls the callback ? Since it's a requestAnimationFrame (with setTimeout fallback), how does the compiler "fits" all the updates to process in the 16ms (raf) / 4ms (setTimeout) interval ?

It's more a collection of questions I was asking myself about async stuff in Vue than a real issue - but I would be really pleased if someone was able to enlighten me.

@yyx990803
Copy link
Member

To your first issue, it might be because of the component is created, but it is not inserted into the DOM yet by the directive that created it yet. However I'm not sure if that's really the cause - would help if you can reproduce the bug in a fiddle.

To your nextTick question: because raf and setTimeout are not triggered by strictly counting the time, rather, they both simply put the task function into a queue, and the queue is guaranteed to be executed in order, even if it takes longer than 16ms/4ms to exhaust the queue.

@ayamflow
Copy link
Author

I'll try to make a fiddle at work. The component is either created by a custom v-view or manually so in both cases, there is first the instantiation of the component, then a call to $appendTo. That might be it.

I understand now, it's actually basic DOM rendering! So it's in fact our job to minimize the job queue so the browser takes less than 16ms to render, and have a smooth experience.

@ayamflow
Copy link
Author

Alright so, it was indeed coming from the fact that when a component is created procedurally, the ready hook is called before the VM is added to the DOM. I find this behavior odd because I was expecting ready to fire when the component $el is is compiled and attached to the DOM, not when the VM's fragment is compiled (and not inserted). Anyway I used a custom hook like this:

// Use the $appendTo callback to send the event
someComp.$appendTo($wrapper, function() {
    someComp.$emit('hook:added');
});

...

(in the component)
this.$on('hook:added', someAwesomeMethod);

And I don't need some weird double nested nextTick anymore. I should probably watch for both ready and added event before doing any DOM logic, but I'm feeling lazy.

@yyx990803
Copy link
Member

You can also try this.$once('attached', cb) in created hook, although the attached hook is kinda unreliable sometimes.

@ayamflow
Copy link
Author

Ah! Didn't think of this one, I thought attached was only called by v-if. Will try :)

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

No branches or pull requests

2 participants