Nobody likes to wait for web pages to load in the browser. The longer it takes, the more dissatisfied the users become. Slow web pages lead to a higher bounce rate and the loss of customers. To solve this kind of problems can be very hard sometimes. Before you even start to optimise your page, you have to understand the workflows a browser performs in order to display a page on the screen. In this talk you will get some insights in the critical rendering path and the javascript engine of your browser that help you to find performance problems and solve them. I will show you also some tools and best practices that make your life easier when it comes to performance.
8. Remember your
optimisations?
const arr = ['Peter', 'Paul', 'Mary'];
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
} // 1.734ms
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
} // 0.079ms
2nd run
9. Optimisation
Optimising your JavaScript code is not your problem. Most
of the work is done by the engine itself. You just have to know
how your environment works.
Optimising your code is pointless, as it only reduces
readability.
Keep the big picture in mind!
10. What matters?
The time until your user sees the first
information and is able to interact with
your application.
18. Building the Render Tree
https://developers.google.com/web/fundamentals/performance/critical-rendering-path/constructing-the-object-model
https://creativecommons.org/licenses/by/3.0/
25. Service Worker
Separate browser process that act as a proxy between
browser and server. A service worker is able to intercept and
answer a request to a server directly.
Service workers are able to speed up applications and make
them available offline.
28. Render Blocking CSS
Receiving CSS files is blocking the render process of a
page.
The more CSS is used, the longer the blocking takes.
29. Render Blocking CSS
Do not use @import in your CSS - better pack everything in
just one file.
Use as little CSS as possible in the Critical Rendering Path.
The media attribute helps to reduce the processed CSS.
Last resort solution: inline CSS
30. Render Blocking JavaScript
All of the JavaScript that is not necessary for the initial page
load can be loaded at a later time.
Generating a script tag at the load event.
or lazy loading with a module loader such as webpack
31. App Shell Architecture
Minimal HTML, CSS and JavaScript as foundation for the
User Interface.
• loads fast
• can be cached
• shows dynamic content
33. The user is moving within the application. The application
stays open in the browser over a long period of time.
Data is loaded over the whole lifecycle of the application.
There are no additional page loads
34. Application state is stored in memory.
Object representations are stored in memory.
Memory consumption increases over time.
40. Hidden Classes
For property access usually one big directory is used. To
speed up property access hidden classes per object is
used. The hidden class points to the location of a property in
memory.
42. function Point(x, y) {
this.x = x;
this.y = y;
}
var p1 = new Point(2, 4);
p1
Hidden Class
C0
43. function Point(x, y) {
this.x = x;
this.y = y;
}
var p1 = new Point(2, 4);
p1
Hidden Class
C0
x: offset 0
Hidden Class
C0 Property x added -
use C1.
44. Hidden Class
C1
x: offset 0
function Point(x, y) {
this.x = x;
this.y = y;
}
var p1 = new Point(2, 4);
p1
Hidden Class
C2
x: offset 0
y: offset 1
Hidden Class
Property y added - use C2
47. JIT Compiler
V8 compiles JavaScript code to machine code at first run.
The engine tries to guess the according hidden classes and
patches the machine code. All future usages of the object are
using the same hidden classes. If there’s a mismatch the
engine corrects it accordingly.
48. JIT Compiler
# ebx = the point object
cmp [ebx,<hidden class offset>],<cached hidden class>
jne <inline cache miss>
mov eax,[ebx, <cached x offset>]
p1.x
50. Garbage Collection
V8 does memory management when the processor is idle to
reduce impact to the application.
The Garbage Collector regularly checks used memory and
frees unused memory.
Unused means: No more references to the object in memory.
51. Garbage Collection
new assigned memory
older objects
Memory structure
Most objects only have a short lifecycle
young generation
old generation
52. new assigned memory
Garbage Collection
Object1
Object2
Object3
Object1
Object2
Object3
older objects
Object1
As soon as one block is full, every used
object is moved to another block. The
old block is emptied afterwards.
If an object is moved for the second time
it’s moved to old generation space.
54. Garbage Collection
Where the young generation space is cleaned up with a
scavenge algorithm which is using a lot of memory, the old
generation space is cleaned up with a mark-and-sweep
collector.
Active objects are marked, all unmarked objects are
deleted.
A complete run takes 100 ms. Your application is stopped for
this time. V8 is able to do this process in increments which
take 5ms each.
55. JavaScript Engines
A lot optimisations of a browser engine only work for structures
which are used multiple times.
57. Repaints & Reflows
Repaint: Browser checks all elements for visibility, color,
measurements and other visual properties.
58. Repaints & Reflows
Reflow: The browser recalculates the layout of the page. A
reflow might cause reflows for other elements (children, or
siblings).
After a reflow a repaint is triggered.
59. Trigger for reflows
• Addition, removal or update of a DOM element
• Change of the content of a page
• Movement of an element
• Animations
• Reading measurements
• Change of CSS property
• Change of the class name of an element
• Addition or removal of a stylesheet
• Change of window size
• Scrolling
60. Omitting reflows
• Omit series of single style changes
• Collect operations in CSS classes
• Detach elements, change them, attach them to the
DOM
• Cache styles in JS variables
• Use fixed positions for animations
63. Memory Leaks
Memory leaks slow down an application, cause crashes and
increase latency.
A memory leak occurs, if memory is not used any more but
not freed by the GC.
65. Memory Leaks
var theThing = null;
var replaceThing = function () {
var originalThing = theThing;
var unused = function () {
if (originalThing)
console.log("hi");
};
theThing = {
longStr: new Array(1000000).join('*'),
someMethod: function () {
console.log(someMessage);
}
};
};
setInterval(replaceThing, 100);
http://info.meteor.com/blog/an-interesting-kind-of-javascript-memory-leak
68. JavaScript Animations
If you’re doing animations with JavaScript, you periodically
change certain CSS properties of an object.
At 60 frames per second an animation is looking fluid.
69. function move(elem, to) {
var left = 0;
function frame() {
left++;
elem.style.left = left + 'px';
if (left === to) {
clearInterval(id)
}
}
var id = setInterval(frame, 10);
}
document.getElementById('outer').onclick = function () {
move(this.children[0], 500);
};
<div id="outer" class="outer">
<div id="inner" class="inner"></div>
</div>
HTML
CSS
70. Disadvantages
JavaScript is executed in the CPU and shares this resource
with a lot of other processes.
GC cycles can slow performance further down.
If your system is under load, animations are not fluid anymore.
73. CSS animations
CSS animations are calculated by the GPU and don’t create
load on the CPU.
CSS animations are more fluid than their JS counterpart.
Your browser is able to optimise your CSS animations.
75. CSS animations
If transitions are not enough, you can control animations with
@keyframes.
There are a lot of generators online (e.g. http://
cssanimate.com)
77. Prefetching
Your browser prefetches certain pages in order to load faster
if a user is browsing to that page. All browsers except Safari
support this attribute.
Chrome (49), IE (not Edge) and Opera are supporting
prerendering, where your browser prerenders the page to
further speed up display of a page.
<link rel="prefetch" href="users.html" />
79. Performance @facebook
A very good example of web performance tuning is the react
library. The virtual DOM provides an in memory structure on
which all the changes are performed. Afterwards all necessary
operations are calculated and performed in an optimised
operation to the actual DOM.
80. More performance
@facebook
To further improve performance, react introduces a full rewrite
of the reconciliation algorithm with version 16. In this version
there are different schedulers which determine when a
change should be performed.