Transcript
Page 1: Hacking Webkit & Its JavaScript Engines

Thursday, November 3, 2011

Page 2: Hacking Webkit & Its JavaScript Engines

forget to run

the tests

Typical Scenario

This is awesome!

Thursday, November 3, 2011

Page 3: Hacking Webkit & Its JavaScript Engines

Ariya Hidayat & Jarred NichollsSencha

Twitter: @ariyahidayat @jarrednicholls

HACKING WEBKIT & ITS JAVASCRIPT ENGINES

Thursday, November 3, 2011

Page 4: Hacking Webkit & Its JavaScript Engines

What is WebKit?

Thursday, November 3, 2011

Page 5: Hacking Webkit & Its JavaScript Engines

Browser at a High LevelUser Interface

Browser Engine

Graphics Stack

Data P

ersistence

Render Engine

JavaScript Engine

Networking I/O

Thursday, November 3, 2011

Page 6: Hacking Webkit & Its JavaScript Engines

Browser at a High LevelUser Interface

Browser Engine

Graphics Stack

Data P

ersistence

JavaScript Engine

Networking I/O

Render Engine

WebKit

Thursday, November 3, 2011

Page 7: Hacking Webkit & Its JavaScript Engines

≠Thursday, November 3, 2011

Page 8: Hacking Webkit & Its JavaScript Engines

⊂Thursday, November 3, 2011

Page 9: Hacking Webkit & Its JavaScript Engines

WebKit isEVERYWHERE!

Thursday, November 3, 2011

Page 10: Hacking Webkit & Its JavaScript Engines

Even in your living room!

Thursday, November 3, 2011

Page 11: Hacking Webkit & Its JavaScript Engines

How?

Thursday, November 3, 2011

Page 12: Hacking Webkit & Its JavaScript Engines

Client InterfaceThursday, November 3, 2011

Page 13: Hacking Webkit & Its JavaScript Engines

WebKit ComponentsRender Engine

WebCore

JavaScript Engine (JSC/V8)Client Interface

HTML

DOMCSS

SVG

Canvas

Thursday, November 3, 2011

Page 14: Hacking Webkit & Its JavaScript Engines

Port Abstraction

Client Interface

Networking I/O

GraphicsThemeEventsClipboard

Thread Geolocation Timer

API CallsEvents

Port(Chrome, Safari, etc.)

Thursday, November 3, 2011

Page 15: Hacking Webkit & Its JavaScript Engines

<input type=”number” />

WebKit Port

Paint me some spin

buttons, STAT!

I know how to do that!

Thursday, November 3, 2011

Page 16: Hacking Webkit & Its JavaScript Engines

<input type=”number” />

WebKit

right there

please, kthx

Thursday, November 3, 2011

Page 17: Hacking Webkit & Its JavaScript Engines

<input type=”number” />

Port

Piece of cake!

lookin’ sexy!

Thursday, November 3, 2011

Page 18: Hacking Webkit & Its JavaScript Engines

<input type=”number” />

Theme Interfacebool paintInnerSpinButton(RenderObject*, const PaintInfo&, const IntRect&);

Thursday, November 3, 2011

Page 19: Hacking Webkit & Its JavaScript Engines

<input type=”number” />

bool paintInnerSpinButton(RenderObject*, const PaintInfo&, const IntRect&);

Theme Interface

Client Interface

Theme

RenderTheme->paint()

PortpaintInnerSpinButton

Thursday, November 3, 2011

Page 20: Hacking Webkit & Its JavaScript Engines

Command LineWebKit

Thursday, November 3, 2011

Page 21: Hacking Webkit & Its JavaScript Engines

Demo

Thursday, November 3, 2011

Page 22: Hacking Webkit & Its JavaScript Engines

How’d you do that!?

Thursday, November 3, 2011

Page 23: Hacking Webkit & Its JavaScript Engines

Headless WebKit

Thursday, November 3, 2011

Page 24: Hacking Webkit & Its JavaScript Engines

“Headless”

Thursday, November 3, 2011

Page 25: Hacking Webkit & Its JavaScript Engines

Display

Paint

Layout

Normal Browser

Thursday, November 3, 2011

Page 26: Hacking Webkit & Its JavaScript Engines

Display

Paint

Layout

Headless

X

Thursday, November 3, 2011

Page 27: Hacking Webkit & Its JavaScript Engines

What’s in it for me?

Thursday, November 3, 2011

Page 28: Hacking Webkit & Its JavaScript Engines

What’s in it for me?Automated “smoke” tests

Continuous integration

Pixel-perfect regression tests

Web scraping

...

Thursday, November 3, 2011

Page 29: Hacking Webkit & Its JavaScript Engines

Demo

Thursday, November 3, 2011

Page 30: Hacking Webkit & Its JavaScript Engines

JavaScript Optimizations & Best

Practices

Thursday, November 3, 2011

Page 31: Hacking Webkit & Its JavaScript Engines

Benchmark.jsRobust benchmarking libraryCreated by Mathias Bynens and John-David Dalton

Platform/Browser independent

Supports high-precision timers

http://benchmarkjs.com

Thursday, November 3, 2011

Page 32: Hacking Webkit & Its JavaScript Engines

var suite = new Benchmark.Suite;// add testssuite.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

Page 33: Hacking Webkit & Its JavaScript Engines

jsperf.comOnline JavaScript benchmarking toolCreated by Mathias Bynens

Powered by Benchmark.js

Integrated with Browserscopehttp://www.browserscope.org/

Easy benchmark suite setup / teardown

http://jsperf.com

Thursday, November 3, 2011

Page 34: Hacking Webkit & Its JavaScript Engines

Best PracticesBatching DOM Operations

Reuse & Recycle DOM

Cache Variables

Optimal Enumeration

Dirty Math Hack

Thursday, November 3, 2011

Page 35: Hacking Webkit & Its JavaScript Engines

Batch DOM Operations

Thursday, November 3, 2011

Page 36: Hacking Webkit & Its JavaScript Engines

<span id="test"></span>var span = document.getElementById('test');

setup

Thursday, November 3, 2011

Page 37: Hacking Webkit & Its JavaScript Engines

span.innerHTML = '';for (var i = 0; i < 10; i++) { span.innerHTML += 'Line #' + (i+1) + '<br />';}

span.innerHTML = '';var buffer = '';for (var i = 0; i < 10; i++) { buffer += 'Line #' + (i+1) + '<br />';}span.innerHTML = buffer;

multiple ops

single op

Thursday, November 3, 2011

Page 38: Hacking Webkit & Its JavaScript Engines

span.innerHTML = '';for (var i = 0; i < 10; i++) { span.innerHTML += 'Line #' + (i+1) + '<br />';}

span.innerHTML = '';var buffer = '';for (var i = 0; i < 10; i++) { buffer += 'Line #' + (i+1) + '<br />';}span.innerHTML = buffer;

multiple ops

single op

fast

slow

Thursday, November 3, 2011

Page 39: Hacking Webkit & Its JavaScript Engines

Batch DOM Operations

http://jsperf.com/batch-dom-operations

Thursday, November 3, 2011

Page 40: Hacking Webkit & Its JavaScript Engines

Reuse & Recycle

Thursday, November 3, 2011

Page 41: Hacking Webkit & Its JavaScript Engines

Netflix Video Carousel

Thursday, November 3, 2011

Page 42: Hacking Webkit & Its JavaScript Engines

current pane

current pane

Thursday, November 3, 2011

Page 43: Hacking Webkit & Its JavaScript Engines

current pane

transition pane

transition pane current pane

Thursday, November 3, 2011

Page 44: Hacking Webkit & Its JavaScript Engines

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

Page 45: Hacking Webkit & Its JavaScript Engines

Variable Caching

Thursday, November 3, 2011

Page 46: Hacking Webkit & Its JavaScript Engines

<script>Some = { Deeply: { Nested: { array: [1, 2, 3, 4, 5] } }};</script>

setup

Thursday, November 3, 2011

Page 47: Hacking Webkit & Its JavaScript Engines

for (var i = 0, x; i < Some.Deeply.Nested.array.length; i++) { x = Some.Deeply.Nested.array[i];}

var arr = Some.Deeply.Nested.array, ln = arr.length;for (var i = 0, x; i < ln; i++) { x = arr[i];}

no cache

cached var

Thursday, November 3, 2011

Page 48: Hacking Webkit & Its JavaScript Engines

for (var i = 0, x; i < Some.Deeply.Nested.array.length; i++) { x = Some.Deeply.Nested.array[i];}

var arr = Some.Deeply.Nested.array, ln = arr.length;for (var i = 0, x; i < ln; i++) { x = arr[i];}

no cache

cached var

fast

slow

Thursday, November 3, 2011

Page 49: Hacking Webkit & Its JavaScript Engines

Variable Caching

http://jsperf.com/variable-reference-caching

Thursday, November 3, 2011

Page 50: Hacking Webkit & Its JavaScript Engines

Enumeration

Thursday, November 3, 2011

Page 51: Hacking Webkit & Its JavaScript Engines

var i = 0, ln = myArray.length, x;for (; i < ln; i++) { x = myArray[i];}

for (var x in myArray) {

}

var i = 0, x;for (; x = myArray[i]; i++) {

}

var i = myArray.length, x;while (i--) { x = myArray[i];}

index < length

for in

test value truthiness test index truthiness

Thursday, November 3, 2011

Page 52: Hacking Webkit & Its JavaScript Engines

var i = 0, ln = myArray.length, x;for (; i < ln; i++) { x = myArray[i];}

for (var x in myArray) {

}

var i = 0, x;for (; x = myArray[i]; i++) {

}

var i = myArray.length, x;while (i--) { x = myArray[i];}

slowest

depends...? depends...?

index < length

for in

test value truthiness test index truthiness

fastest

Thursday, November 3, 2011

Page 53: Hacking Webkit & Its JavaScript Engines

Enumeration

http://jsperf.com/optimal-array-enumeration

Thursday, November 3, 2011

Page 54: Hacking Webkit & Its JavaScript Engines

Dirty Math Hack

Thursday, November 3, 2011

Page 55: Hacking Webkit & Its JavaScript Engines

<script>var myArray = [];for (var i = 0; i < 65535; i++) { myArray.push(Math.random() * 10000);}</script>

setup

Thursday, November 3, 2011

Page 56: Hacking Webkit & Its JavaScript Engines

var i = 0, ln = myArray.length;for (var x; i < ln; i++) { x = Math.round(myArray[i]);}

var i = 0, ln = myArray.length;for (var x; i < ln; i++) { x = (0.5 + myArray[i]) << 0;}

Math.round in loop

inline left bit shift

Thursday, November 3, 2011

Page 57: Hacking Webkit & Its JavaScript Engines

var i = 0, ln = myArray.length;for (var x; i < ln; i++) { x = Math.round(myArray[i]);}

var i = 0, ln = myArray.length;for (var x; i < ln; i++) { x = (0.5 + myArray[i]) << 0;}

Math.round in loop

inline left bit shift

fastslow

Thursday, November 3, 2011

Page 58: Hacking Webkit & Its JavaScript Engines

Math

http://jsperf.com/jit-part-2

Thursday, November 3, 2011

Page 59: Hacking Webkit & Its JavaScript Engines

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

Page 60: Hacking Webkit & Its JavaScript Engines

Don’t Trust Intuition!

Thursday, November 3, 2011

Page 61: Hacking Webkit & Its JavaScript Engines

Code Analysis

Thursday, November 3, 2011

Page 62: Hacking Webkit & Its JavaScript Engines

Demo

Thursday, November 3, 2011

Page 63: Hacking Webkit & Its JavaScript Engines

"type": "IfStatement","test": { "type": "BinaryExpression", "operator": "==", "left": { "type": "Identifier", "name": "x" }, "right": { "type": "Identifier", "name": "y" } }, "consequent": { "type": "ExpressionStatement", "expression": { "type": "CallExpression", "callee": { "type": "Identifier", "name": "foo" }, "arguments": [] } }, "alternate": null

if (x == y) foo();

Thursday, November 3, 2011

Page 64: Hacking Webkit & Its JavaScript Engines

"type": "IfStatement","test": { "type": "BinaryExpression", "operator": "==", "left": { "type": "Identifier", "name": "x" }, "right": { "type": "Identifier", "name": "y" } }, "consequent": { "type": "ExpressionStatement", "expression": { "type": "CallExpression", "callee": { "type": "Identifier", "name": "foo" }, "arguments": [] } }, "alternate": null

if (x == y) foo();

Thursday, November 3, 2011

Page 65: Hacking Webkit & Its JavaScript Engines

"type": "IfStatement","test": { "type": "BinaryExpression", "operator": "==", "left": { "type": "Identifier", "name": "x" }, "right": { "type": "Identifier", "name": "y" } }, "consequent": { "type": "ExpressionStatement", "expression": { "type": "CallExpression", "callee": { "type": "Identifier", "name": "foo" }, "arguments": [] } }, "alternate": null

if (x == y) foo();

Danger!

Thursday, November 3, 2011

Page 66: Hacking Webkit & Its JavaScript Engines

Wrap Up

Thursday, November 3, 2011

Page 67: Hacking Webkit & Its JavaScript Engines

THANK YOU!

Thursday, November 3, 2011

Page 68: Hacking Webkit & Its JavaScript Engines

QUESTIONS?

ariya @ sencha.com

ariyahidayat

ariya.ofilabs.com

jarred @ sencha.com

jarrednicholls

about.me/jarrednicholls

Thursday, November 3, 2011

Page 69: Hacking Webkit & Its JavaScript Engines

Hardware AccelerationToday 3:00pm

Thursday, November 3, 2011

Page 70: Hacking Webkit & Its JavaScript Engines

Typical Dynamic Lang.

Parser Runtime

Interpreter

Thursday, November 3, 2011

Page 71: Hacking Webkit & Its JavaScript Engines

How does JavaScript talk to the DOM?

Thursday, November 3, 2011

Page 72: Hacking Webkit & Its JavaScript Engines

How does JavaScript talk to the DOM?

BINDINGS!

Thursday, November 3, 2011

Page 73: Hacking Webkit & Its JavaScript Engines

window.location.href

Thursday, November 3, 2011

Page 74: Hacking Webkit & Its JavaScript Engines

window.location.href

Thursday, November 3, 2011


Recommended