WebKit, along with its JavaScript engines, is not a magical black box. We will show you the internal of various WebKit building blocks (10,000-foot overview) and how they work together. In particular, learn also the simple steps on how to experiment with WebKit with your own and leverage WebKit functionalities to find the performance problems, track the network issues, automate effective smoke tests, and implement per-pixel correctness tests. In addition, armed with a little extra knowledge about JavaScript engines, you will be ready to improve both the quality and performance of your JavaScript code.
5. Browser at a High Level
User Interface
Data Persistence
Browser Engine
Render Engine
Networking JavaScript Graphics
I/O Engine Stack
Thursday, November 3, 2011
6. Browser at a High Level
User Interface
W
Data Persistence
eb
K
it Browser Engine
Render Engine
Networking JavaScript Graphics
I/O Engine Stack
Thursday, November 3, 2011
30. JavaScript
Optimizations & Best
Practices
Thursday, November 3, 2011
31. Benchmark.js
Robust benchmarking library
Created by Mathias Bynens and John-David Dalton
Platform/Browser independent
Supports high-precision timers
http://benchmarkjs.com
Thursday, November 3, 2011
32. var suite = new Benchmark.Suite;
// add tests
suite.add('RegExp#test', function() {
/o/.test('Hello World!');
})
.add('String#indexOf', function() {
'Hello World!'.indexOf('o') > -1;
})
.add('String#match', function() {
!!'Hello World!'.match(/o/);
})
// add listeners
.on('complete', function() {
console.log('Fastest is ' +
this.filter('fastest').pluck('name'));
})
// run
.run();
Thursday, November 3, 2011
33. jsperf.com
Online JavaScript benchmarking tool
Created by Mathias Bynens
Powered by Benchmark.js
Integrated with Browserscope
http://www.browserscope.org/
Easy benchmark suite setup / teardown
http://jsperf.com
Thursday, November 3, 2011
34. Best Practices
Batching DOM Operations
Reuse & Recycle DOM
Cache Variables
Optimal Enumeration
Dirty Math Hack
Thursday, November 3, 2011
42. current pane
current pane
Thursday, November 3, 2011
43. transition pane current pane
transition pane
current pane
Thursday, November 3, 2011
44. That gives us...
Lightweight DOM
Persistent JS References to DOM Elements
Faster / Less-Frequent Mark & Sweep by GC
Fewer Memory Leaks
Thursday, November 3, 2011
47. no cache
for (var i = 0, x; i < Some.Deeply.Nested.array.length; i++) {
x = Some.Deeply.Nested.array[i];
}
cached var
var arr = Some.Deeply.Nested.array,
ln = arr.length;
for (var i = 0, x; i < ln; i++) {
x = arr[i];
}
Thursday, November 3, 2011
48. no cache
for (var i = 0, x; i < Some.Deeply.Nested.array.length; i++) {
x = Some.Deeply.Nested.array[i];
}
slow
fast
cached var
var arr = Some.Deeply.Nested.array,
ln = arr.length;
for (var i = 0, x; i < ln; i++) {
x = arr[i];
}
Thursday, November 3, 2011
49. Variable Caching
http://jsperf.com/variable-reference-caching
Thursday, November 3, 2011
51. index < length
var i = 0, for in
ln = myArray.length,
for (var x in myArray) {
x;
for (; i < ln; i++) {
}
x = myArray[i];
}
test value truthiness test index truthiness
var i = 0, var i = myArray.length,
x; x;
for (; x = myArray[i]; i++) { while (i--) {
x = myArray[i];
} }
Thursday, November 3, 2011
52. index < length
var i = 0, for in
ln = myArray.length,
for (var x in myArray) {
x;
for (; i < ln; i++) {
}
x = myArray[i];
}
slowest
fastest
test value truthiness test index truthiness
var i = 0, var i = myArray.length,
x; x;
for (; x = myArray[i]; i++) { while (i--) {
x = myArray[i];
} }
depends...? depends...?
Thursday, November 3, 2011
53. Enumeration
http://jsperf.com/optimal-array-enumeration
Thursday, November 3, 2011
55. setup
<script>
var myArray = [];
for (var i = 0; i < 65535; i++) {
myArray.push(Math.random() * 10000);
}
</script>
Thursday, November 3, 2011
56. Math.round in loop
var i = 0,
ln = myArray.length;
for (var x; i < ln; i++) {
x = Math.round(myArray[i]);
}
inline left bit shift
var i = 0,
ln = myArray.length;
for (var x; i < ln; i++) {
x = (0.5 + myArray[i]) << 0;
}
Thursday, November 3, 2011
57. Math.round in loop
var i = 0,
ln = myArray.length;
for (var x; i < ln; i++) {
x = Math.round(myArray[i]);
}
slow
fast
inline left bit shift
var i = 0,
ln = myArray.length;
for (var x; i < ln; i++) {
x = (0.5 + myArray[i]) << 0;
}
Thursday, November 3, 2011
58. Math
http://jsperf.com/jit-part-2
Thursday, November 3, 2011
59. Math - Inline Equivalents
Math.floor(x) === (x << 0)
Math.round(x) === (0.5 + x << 0)
Math.ceil(x) === (x === x << 0 ? x : x + 1 << 0)
...
Thursday, November 3, 2011
Track B 11:15am-12:00pm \nA browser's JavaScript engine can seem like a magical black box. During this session, we'll show you how they work from 10,000 feet and give you the tricks to compile all the popular engines out there including JavaScriptCore, V8, and SpiderMonkey. We'll inspect the internals of the engine, and debug+profile your favorite code snippets. Armed with just a little extra knowledge about this black box, you will be ready to take a new look at JavaScript apps.\n
\n
As JavaScript/Web developers, you should be fully aware of what&#x2019;s going on under the hood, and the reach of these technologies outside of the traditional browser/black-box.\n
\n
traditional desktop browsers and frameworks\n
mobile devices (smartphones, tablets, etc.)\n
set top boxes (like Apple TV, Google TV, etc.), game consoles and hand helds, Netflix\n
and yes, on the server and command line\n
\n
Some may have seen JavaScript on the server, but a full functioning browser running headless on the server/CLI? That&#x2019;s news to many!\n
Let&#x2019;s first understand what WebKit is, and why it&#x2019;s ubiquitous.\n
Let&#x2019;s start by telling you what WebKit isnt...\n
it&#x2019;s NOT Safari!\n
it&#x2019;s NOT Chrome!\n\nOk now that we&#x2019;ve cleared up that whole mess...\n
\n
\n
Ok so it&#x2019;s a rendering engine...but what exactly does that mean?\nThat&#x2019;s best answered by describing how WebKit is consumed.... \n
How is WebKit so ubiquitous?\n
WebKit&#x2019;s engine was built with platform abstraction in mind, allowing different implementations to be made that can consume WebCore (parsers, DOM, CSS, Render Tree compilation, etc.)\n\nThe WebKit API is like a conductor, and WebKit ports are like musicians. The musicians know how to play their instruments, and the conductor knows what he wants to hear, and leads the musicians through a piece of music.\n
Port = &#x201C;implementation of the WebKit API interfaces (template/client methods)&#x201D;\n
\n
\n
\n
\n
\n
\n
slides on Boeing jet engines, to discuss how not all ports may have the same features or deliver output pixel-exact, but still use the same engine?\n
\n
\n
\n
VQA = Visual Quality Assurance\n\nNeat little pyramid eh?\n
VQA = Visual Quality Assurance\n\nNeat little pyramid eh?\n
VQA = Visual Quality Assurance\n\nNeat little pyramid eh?\n
VQA = Visual Quality Assurance\n\nNeat little pyramid eh?\n
VQA = Visual Quality Assurance\n\nNeat little pyramid eh?\n
VQA = Visual Quality Assurance\n\nNeat little pyramid eh?\n
VQA = Visual Quality Assurance\n\nNeat little pyramid eh?\n
VQA = Visual Quality Assurance\n\nNeat little pyramid eh?\n
VQA = Visual Quality Assurance\n\nNeat little pyramid eh?\n
jasmine tests\npixel comparison for visual regression testing\n
\n
parser, runtime, interpreter/VM\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Notice that red, orange, and green are the exact same in Firefox 7.0.1 and Safari 5.1.1. They both are able to JIT &#x201C;index < length&#x201D;, &#x201C;test index&#x201D; and &#x201C;test value&#x201D; into the same machine code and produce the same results. Chrome is obviously the fastest with &#x201C;index < length&#x201D;.\n\n&#x201C;for in&#x201D; is super slow everywhere because of the jump from JS context through native bindings to the native code on every iteration - it also cannot be JITed because of this.\n
\n
\n
it&#x2019;s even easier to read too\n
\n
V8 does a great job of optimizing property access (including native prop accessors), so caching isn&#x2019;t necessary.\n\nJSC and SpiderMonkey, however, benefit greatly from caching deeply nested variables and native property accessors like Array.length.\n
Doing lots of mathematical operations in tight loops or performance sensitive areas is a fairly common occurrence, especially with Canvas (image/pixel ops) and WebGL.\n
\n
\n
\n
avoiding the inner loop function calls will speed up your performance sensitive mathematical operations.\n
Avoid native function calls in tight loops doing mathematic calculations.\nPut major math operations in a helper function to be JIT friendly.\n
\n
\n
\n
\n
Doesn&#x2019;t matter what browser you use - invoking DOM methods and/or forcing repaints more than necessary will always slow things down a lot.\n\nSetting innerHTML 1 time vs. setting it 10 times is literally 9x slower...as expected.\n
\n
\n
\n
keeps the DOM light, reuses DOM nodes so memory consumption is reduced and buildup/teardown is not as intensive.\nJS references to the DOM nodes can be persistent, so there is no lag time between dereferencing old DOM nodes, and GC cleanup; thus, GC cycles are performed faster and less frequently, and there is less chance of memory leaks occurring.\n