
Fine-grained timing and energy profiling in Servo - AndrewDucker
http://blog.servo.org/2015/09/11/timing-energy/?repost
======
amelius
I wish more groups looked at energy consumption in their applications. Take
for example React, which is being used in increasingly many apps. It re-
evaluates a complete tree to see if parts of the tree have changed. And this
happens for every minor change to the tree. Clearly, this scheme completely
goes against all good design practices that address battery life.

~~~
richthegeek
I'm not sure I would agree with that.

First, from a technical perspective, a well-designed React app should only
evaluate the minimal parts of the tree that have changed. And React can do
that easily with the PureRender mixin, or you can do it manually with the
componentShouldUpdate method.

Secondly, from an empirical perspective, one of React's major selling points
is that it renders many classes of DOM-based apps (and others) much more
quickly than previous methods (e.g. jQuery, Angular) could achieve. React
reduces the overall time spent performing CPU-intensive tasks, even if there
is (_if_) there is an increase in CPU-time spent book-keeping.

Of course, it would be moot if the DOM wasn't so utterly dreadful from a
performance perspective. But apparently it is fundamentally broken or it would
have been fixed years ago.

~~~
amelius
The PureRender and componentShouldUpdate methods are "escapes" from the React
philosophy, so I don't count them as being "React". They make the code more
complicated because, with them, inconsistencies can easily arise.

Making a simple local change to a list of N items, which would normally take
O(1) energy, suddenly takes O(N) energy. Even with the PureRender and
componentShouldUpdate methods, because React will traverse the complete list
to determine which items should be changed (calling componentShouldUpdate for
every item).

I agree with you on the DOM. Its speed needs to improve. React offers a nice
abstraction which may keep the code simple, but, as explained here, has
problems of its own.

~~~
richthegeek
Hardly - they enforce the React philosophy more strictly.

In an ideal system, Components receive props, modify internal state, and
render idempotently based on these. The PureRender mixin is a way of saying
"yes, this component conforms to the above constraints".

Unfortunately, it's not always the case that the naive way of writing a
Component will comply with the PureRender restrictions, so it's not enabled by
default. It's not difficult, 99% of the time, to alter a Component to work
properly with only minimal changes, and they aren't changes that make the
Component code more confusing.

ComponentShouldUpdate is a way of applying tree-trimming logic that React
could not automatically know. Business logic and the like. When a Component
implements componentShouldUpdate and returns false, it will prevent any
children of that component being iterated in that loop. Ideally,
componentShouldUpdate should just returning a Boolean value from state, rather
than calculating it each time.

~~~
amelius
> When a Component implements componentShouldUpdate and returns false, it will
> prevent any children of that component being iterated in that loop

Yes, but when you alter 1 element of a list L, then L must be iterated (simply
because it changed), so componentShouldUpdate() will return true for L. As a
consequence, _all_ elements of L will be checked. But you only changed one!

~~~
richthegeek
I sort of see where you are coming from, but I can't see how it could be done
any differently in an idealised system.

If you change the elements in a set, you need to re-evaluate how that set is
rendered. Wether you leave it to the elements to decide if they are to be
altered, or have that logic in the set-handling code, the book-keeping (and
related CPU time) still needs to occur?

Either way, the proof is in the pudding: React is so insanely faster for this
specific case than all other approaches.

~~~
omphalos
What should happen is that we do incremental computation, sort of like what's
described here [1]. You ought to be able to declaratively specify that such-
and-such collection maps to such-and-such elements. If you change just one
element in the collection, change tracking built into an incremental
computation framework should cause that one element to update. Logically,
there's really no need to review the entire collection if just one element
changes.

Certainly the Virtual DOM is one way to let you declaratively write to the DOM
and not worry about change tracking yourself. But it's not the most efficient
way.

Unfortunately this sort of thing has never been implemented in JavaScript
(that I can find) so currently the Virtual DOM is probably our least worst
choice, at the moment.

[1] [https://blogs.janestreet.com/introducing-
incremental/](https://blogs.janestreet.com/introducing-incremental/)

~~~
amelius
Yes, this is also the approach I was thinking about. Perhaps it is time
somebody at Facebook gets the chance to develop the javascript variant of this
technique, as it is a far more "correct" way of approaching the problem, from
a Computer Science standpoint.

