
Interview with the author of React-like Inferno about JavaScript optimisations - expression100
http://survivejs.com/blog/inferno-interview/
======
underwater
I've spent a lot of time optimizing the startup time of large React codebases.
In my experience the size of the React bundle is irrelevant; it will be
quickly dwarfed by the product code for any meaningful application. The real
problems in startup speed are twofold:

Browsers are stuck optimizing an outdated model - parsing and compiling
JavaScript on the critical path is madness. The only benefit of that model is
that a web developer can right click and view source to see some unreadable
minified JavaScript code. The cost is that every web user has to wait hundreds
or milliseconds or multiple seconds for the browser to do busy work. Even
advancements like Service Workers don't do anything to mitigate this problem.

The second problem is that browser vendors are locked in a arms race chasing
artificial metrics. This started years ago when the Chrome team introduced V8
with a huge PR push to sell the benefits of their JIT. It looks awesome to say
that your browser tops SunSpider but those metrics don't necessarily correlate
to how sites use JavaScript. Firefox has a heavily optimized JIT that kicks in
when a function is run 1,000 times. When loading Facebook the hottest codepath
is run 900 times.

~~~
trueadm
Note: I'm the author of Inferno

I commonly hear the same thing – you've benchmarked React and it performs
fine. Did you benchmark this on a modern MacBook/laptop by any chance?

The realism is that the desktop market is only 15% of the entire global online
market. In developing nations, Android mobile performance is essential. React,
Angular, Ember and other libraries have never performed well in this space.

If you're shipping a huge bundle for your app – you're doing something wrong
too. You need to take into account that mobile users are likely to have a 3G
connection at best and are likely to be on a 5+ year old device. You need to
endorse code-splitting, service workers and other PWA features to better
accommodate those users. Inferno will deliver the best in class mobile
performance when paired with those features.

~~~
acqq
Please, please, write more, and more details!

To much web developers have that "works on my (fastest possible) desktop or
notebook" attitude, and every developer that understands and talks about
what's actually going on by most of the users (those using the slower devices)
is worth gold.

~~~
trueadm
The interview actually talks quite a bit about how I went about making these
changes. Worth fully reading!

~~~
acqq
Thanks. I've read it, what I'd like to see is more of the stuff addressed to
other developers, exactly like in your response above.

You understand the issues because you personally compared, measured, whereas
most of the developers just consider something as "working" if they personally
"don't wait" too much for the stuff they are producing. That's why I wanted to
motivate you to consider talking about your experiences that more developers
can directly use.

------
wje
Sadly, this article has nothing to do with an inferno OS port to js.

[http://www.vitanuova.com/inferno/](http://www.vitanuova.com/inferno/)

~~~
sedachv
Agreed and similarly disappointed. Can we please change the title to point out
that this is specific to ReactJS?

~~~
trueadm
This has nothing to do with React. This is a JavaScript library called Inferno
– the title makes sense to people in the JavaScript scene.

------
slezakattack
You'll have to excuse my ignorance as I just like to lightly follow the JS web
dev community and am no way a JS expert, but what is the reasoning behind the
React spin-offs? There's Inferno, Preact, ivi, and possibly more, but are all
of these so different that they require their own repository? Is it out of the
question to simply contribute to the other existing open source projects? I
imagine there are some backwards compatible breaking changes but it feels a
bit weird to have so many React-like spinoffs. Could anyone shed a light on
this? I'm genuinely curious.

~~~
trueadm
Note: I'm the author of Inferno and know the authors of Preact and Ivi well.

That's a great question and one I frequently get asked. The "current" React
codebase is legacy in many ways, the React team are hard at work on React
Fiber which is complete re-write of the entire codebase.

The legacy codebase isn't something we can actively make better (I've had my
PRs merged though) without a huge rewrite. If we tried to make changes, it
would break React for many people due to how coupled many things are.

A lot has changed in the last few years and the approach to virtual DOM has
been one of them. Going forward, the React team are making big efforts to
change this.

~~~
6DM
I haven't kept up with React like I should. When you say they're undergoing a
re-write, is this going to be like Angular 1 vs Angular 2? I just took a quick
look at their react fiber demo page [0], is it going to be opinionated react
as redux based? That's the vibe I'm getting from this.

[0] [http://reactbits.github.io/fiber/](http://reactbits.github.io/fiber/)

~~~
trueadm
Unlike Angular 1 -> Angular 2, React Fiber will be fully backwards compatible
with the current React.

~~~
danabramov
I probably wouldn't claim 100% compatibility but we're already passing ~95% of
the tests, and intend to fix more. There will likely be a few minor
differences but we also have 20 thousand components that need to "just work"
so we're striving for as much compat as possible, and any changes would be
very contained.

------
mmanfrin
I misunderstood the title and was very confused as to why Dan Brown would have
things to say about Javascript perf.

------
igl
React's event system is one of its strong points. Like with many alternatives,
I stopped looking into them when i read "no event system" in the README. Perf
is not the single most high priority in a framework.

~~~
trueadm
Inferno also has its own event system like React does.

------
s2d2
I love it. When it comes to PCs I am a speed junkie. Maybe because the first
thing I started to learn as a kid was 3D graphics dev.

Anyway most websites are incredibly slow and clunky. With 20+ scripts and
everything pops up or moves while loading.

On the speed of pure JS. I recently developed a JS game just for fun.
Optimizing in a language with GC sucks.

------
findjashua
the big motivation for small size seems to be shaving the time spent on
parsing the js. Is there any reason this can't be parceled off to a background
worker, and using the main thread only for rendering?

------
marknadal
Pro tip: function calls (especially anonymous ones) are the biggest
performance bottleneck. I've done pretty extensive research on this:
[http://youtu.be/BEqH-oZ4UXI](http://youtu.be/BEqH-oZ4UXI) .

~~~
dcherman
So I watched that and heard that you used BenchmarkJS which I believe
intentionally prevents optimization from occurring, otherwise many tests would
just end up being optimized away. Have you considered how function inlining
might affect your results versus benchmarks like you ran in the video? Have
you profiled them side by side under actual usage?

"Anonymous" function calls (function expressions, either immediate or not) are
generally only more expensive because they're re-created all the time.
Sometimes this is necessary to create a closure, often it's not. If you were
to profile `var foo = function() {}`, performance should match the function
declaration variant identically, so it's not the method of declaration that
affects performance.

~~~
marknadal
That is something I have been suspecting of BenchmarkJS, which is unfortunate
because I am/wasn't expecting to be responsible for building a better
benchmarking tool (we are already building a database and a distributed
testing framework).

FireFox does inline, and we can tell even with BenchmarkJS, which is why I
think V8 wasn't (although it has improved significantly recently).

We ran an "actual use" test that saved 100M+ records a day for $10 total (on
about 100GB+, processing, storage, backup). However since it is an "actual
use" we don't know if inlining happened or not (I still suspect not, since I
haven't seen that in V8 - but again, maybe that is BenchmarkJS killing it,
despite seeing it in FF).

Correct correct. The function call is still expensive (anonymous or not), and
managing scope is extremely expensive. You are on top of this stuff! Sounds
like you do performance testing regularly?

~~~
dcherman
I do, but it's also easy to sound smart when you're standing on the shoulders
of very smart people. @jdalton and @petkaantonov are two that I've regularly
followed and read their code for learning purposes. IRHydra by @mraleph is a
great tool for learning about V8 internals and examining what's going on under
the hood. Bluebird is an amazing example to follow if you _really_ want to
optimize, however the vast majority of libraries and apps don't need to
concern themselves with some of the crazier optimizations that are performed
there.

The biggest takeaways that I've had are mainly that if you really want to
optimize, then write the kind of code that the various engines can optimize
best. With that in mind, TypeScript is not only a great language, it's
actually a great performance tool since it can help you to identify
polymorphic functions that _maybe_ could be changed to monomorphic ones if
they're in the hot path.

I've got another fun hacky kind of optimization for you though that I've
mainly used for benefit in some angular code/expressions that are executed
potentially millions of times. If you can make some assumptions about the name
of the property being accessed for security reasons and it's going to be
repeatedly used, compare the following:

// Setup

const makeGetter = (prop) => new Function("obj", "return obj." \+ prop");

const slowGetter = (obj, prop) => obj[prop];

const fastGetter = makeGetter("foo");

const obj = { foo: "bar" };

// Test

slowGetter(obj, 'foo');

fastGetter(obj);

This is primarily an optimization for Internet Explorer, but if I recall it
was somewhat positive in other browsers at the time as well. It makes more
sense if you consider it in the context of executing a simple angular
expression repeatedly, though 1.6.0 might narrow that gap significantly now
that the expressions sandbox was removed as I think they generate code similar
to my "makeGetter" factory. Haven't re-tested yet.

