I have been using React from couple of months and React doesn't simply re-rendering a component completely instead it finds the difference and makes those changes. Does Angular 2 does something like this?
And also whenever a change in state is detected does Angular 2 re-render all the components from the root node or does it only re-render those specific components and their sub-tree whose change is detected?
React doesn't simply re-rendering a component completely instead it finds the difference and makes those changes. Does Angular 2 does something like this?
Conceptually yes, it does not re-render entire components.
Angular builds a change detector object for each component/directive. Template bindings (which includes input property bindings) are tracked inside these change detector objects. When change detection runs, by default, each binding is dirty checked for changes. If a change is found, the changed value is propagated to the child component (if an input property changed) or to the DOM. That's it. The entire template/view is not re-rendered. Only the changed values are updated in the DOM. When Angular change detection finishes, the browser notices the DOM changes and updates what we see on the screen.
whenever a change in state is detected does Angular 2 re-render all the components from the root node or does it only re-render those specific components and their sub-tree whose change is detected?
Angular doesn't detect changes to some model/data objects. Rather, it only detects changes to template bindings.
By default, each time change detection runs, it starts from the root component and checks all components for changes, in depth-first order, using those change detector objects. As described above, only template bindings with changes are updated. So, I wouldn't say that Angular ever re-renders a component... it only modifies those parts of the DOM where a template binding changed.
You can configure a component to use the OnPush change detection strategy to limit when that component and its descendants are checked for changes. You can also completely detach() a component from the change detector tree, which means that component and its descendants will not be change detected until you reattach().
Angular is not using virtual DOM as React do. No need for that in context of Angular.
If you have <input> and need to set its value in runtime to something else you don't need to change all DOM around it. You just call setValue() on that element and that's it.
The same applies to any other DOM element. For example if you have this:
<div>{{someVar}}</div>
and Angular detects that someVar was changed it will change content of only that particular <div>.
Angular only renders where it detects changes.
AFAIK there is some room for improvments in *ngFor where it sometimes re-renders too many items when some are added/removed in the middle or the beginning but that is a known issue and will be fixed eventually.
From my comment below
In fact Angular doesn't need re-rendering optimization because it only does anything when bound values change and then it only changes the DOM where it is bound to the changed value. Angular doesn't have a virtual DOM that it needs to mirror to the actual DOM.
Angular2 is using zone.js for onChange rendering. Usually when a change is detected, it will trigger changeDetection that component and all the children, but you also can have control to change that, to force render some things or not render when you don't like angular2 behavior.
Here is a very good talk about how Angular2 change detection works : https://www.youtube.com/watch?v=CUxD91DWkGM
LE: Just to clarify, it will not re-render the component and all the children, it will detect and trigger changes for all of those, but will render only what is necessary.
Related
Let's say I've triggered an update of a single React component & as we know by default it will trigger the update of all it's children components.
BUT
How does it work in combination with browser's reflow/repaint ?
How does the whole process look like (step by step) after we trigger a single React-component's update?
By default, the child components would be updated as well, however, that only happens in the virtualDOM, and not the actual DOM.
Changes are made to the virtualDOM, React then checks to see which DOM elements/components are changed/updated, and only those are updated in the actual DOM, it's part of the reason why your React app is fast.
You can refer to this thread for more information, though I think they are more so on class component, not functional component.
In a React component I am using an external library that creates complex components that I modify slightly on render. Thus, in my own component, I use things like element queries and mutation observers to get rendered elements in the DOM and dynamically add my own modifications, depending on the state of the DOM itself (not the external component, since I cannot access its state).
This works great, but I have not been able to figure out how to test this functionality [in Jest]. In particular, I add mutation listeners that add my own small React components based on the HTML that the external component renders, adding a button when the mouse hovers over a list of dynamically-created elements. When I attempt to test this in Jest, none of this logic is performed, and the functionality I have added cannot be tested, as the changes to the DOM do not appear, even with full rendering. In particular, during testing I have found that the queries I am using in the component do not have any values, as they need the external component to fully render the HTML for my own component to observe the changes.
I need a way to test my component in a way such that the external component is rendered, but such that my own component can perform updates afterwards, when its own state changes.
How can I test the functionality of the updates that I perform that are based on element queries if there are not any results to these queries during testing?
I'd like to modify a div inside my Vue component's template using the Rangy library. I have code like this in one of my methods:
let tooltip = document.createElement('button');
tooltip.setAttribute('type', 'button');
tooltip.setAttribute('v-tooltip.top-center', '"msg"');
tooltipSpan.innerHTML = 'x';
// Insert span with tooltip after of mistake
range.collapse(false);
range.insertNode(tooltipSpan);
As you can see in the third line, I also want to use a v-tooltip component. If I could hardcode this inside the template, it'd simply be <button v-tooltip.top-center="msg">x</button>. But in my app, this component could be programmatically placed anywhere inside a div, so I need to insert it with JavaScript. There might also be more than one instance of that component.
Unfortunately, my approach does not work at all. It doesn't matter whether I use the approach mentioned above using the v-tooltip directive or if I simply insert a component (e.g., let tooltip = document.createElement('my-custom-tooltip');): The new DOM element is correctly inserted, but Vue does not recognize/interpret it as a component. In the above example, all I get is a simple, unstyled button element.
I tried this.$forceUpdate(), this.$nextTick() and a bunch of older methods (that have probably vanished from Vue 2), but nothing worked.
Is there a way to make Vue re-render after manual changes to he DOM, correctly interpreting components that have been inserted?
Vue "owns" the DOM tree belonging to any component; if you mess around in the DOM like you are, any Vue-specific things that you create or modify (like directives) won't magically work.
The DOM that is generated by Vue is a function of the component's data; any time the data changes Vue will re-render the DOM to reflect that change. Vue doesn't know how to deal with manual changes you make to the DOM.
I don't know specifically what you are trying to do and why Rangy is needed, but the correct way to do something like this would be to modify your data not the DOM, and then your template (or render function) takes care of rendering the new data.
Is there a way to make Vue re-render after manual changes to he DOM, correctly interpreting components that have been inserted?
No.
I'm using ember.js(version 3.7) and I bite confused now. Now, I'm working on optimizing the code part for our app. First I'll try to find What are the things are re-render in components? After getting into this topic I bite confused with it.
In ember they used didRender() method to trigger re-rendering things (jQuery DOM Manipulation, Asnyc function loading,etc...). Right now I don't have much idea about re-render in ember. Can someone explain to me re-render in detail? And, please share if you have any resource about re-render in ember.
Thanks in advance.
didRender hook doesn't about triggering a re-render. It is described as the Guide that you shared the link of:
You can leverage this hook to perform post-processing on the DOM of a component after it's been updated.
You might want to do something about sizes or focuses or scrolls. To achieve that you need to wait till your rendering finishes. Because otherwise you cannot get the exact values and positions of the components. For those cases you can use didRender hook.
For example:
- if you want to focus some parts of the view
- if you want to scroll some parts of the view
- if you want to resize some components
- if you want to call a third-party libraries which tries to access DOM element.
etc. You can use this hook.
For sure, if you do something that affects to component's values, it can trigger a re-render. But this is something that you normally shouldn't do.
Let's have one more clarification of re-render:
As components are rendered, re-rendered and finally removed, Ember provides lifecycle hooks that allow you to run code at specific times in a component's life.
(Ref)
Guide says about 3 main phases (Ref):
Initial Render
Re-render
Component Destroy
In here Re-render means, if an argument or a property of a component changes, it starts to re-render itself. For example, think of a person-card component which displays the properties of a person. Such as {{person-card person=model.person}}. Whenever the person parameter changes, the component will re-render.
Every once in a while I have a situation where my code changes some variable binded to the view, or even change some attribute of a Dom element, but the view renders only when all the code is executed, when I usually I don't need the effect anymore, like for example an animation for an Ajax data load.
Is there a way or a command that forces the DOM or Angular to revalidate its bindings or simple refreshes the view?
If I understand your problem correctly it looks like you need to run change detection manually.
ChangeDetectorRef.detectChanges() would trigger change detection for view and child components.
ChangeDetection Docs