Successfully reported this slideshow.

Hacking Webkit & Its JavaScript Engines

21

Share

Loading in …3
×
1 of 74
1 of 74

Hacking Webkit & Its JavaScript Engines

21

Share

Download to read offline

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.

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.

More Related Content

More from Sencha

Related Books

Free with a 14 day trial from Scribd

See all

Hacking Webkit & Its JavaScript Engines

  1. 1. Thursday, November 3, 2011
  2. 2. Typical Scenario This is awesome! un t to r forge tests the Thursday, November 3, 2011
  3. 3. HACKING WEBKIT & ITS JAVASCRIPT ENGINES Ariya Hidayat & Jarred Nicholls Sencha Twitter: @ariyahidayat @jarrednicholls Thursday, November 3, 2011
  4. 4. What is WebKit? Thursday, November 3, 2011
  5. 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. 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
  7. 7. ≠ Thursday, November 3, 2011
  8. 8. ⊂ Thursday, November 3, 2011
  9. 9. WebKit is EVERYWHERE! Thursday, November 3, 2011
  10. 10. Even in your living room! Thursday, November 3, 2011
  11. 11. How? Thursday, November 3, 2011
  12. 12. Client Interface Thursday, November 3, 2011
  13. 13. WebKit Components Render Engine CSS DOM SVG HTML Canvas WebCore Client Interface JavaScript Engine (JSC/V8) Thursday, November 3, 2011
  14. 14. Port Abstraction Networking Thread Geolocation Timer I/O Client Interface Clipboard Events Theme Graphics API Calls Events Port (Chrome, Safari, etc.) Thursday, November 3, 2011
  15. 15. <input type=”number” /> Paint me some spin buttons, STAT! I know how to do that! WebKit Port Thursday, November 3, 2011
  16. 16. <input type=”number” /> ri pl ght ea th se er ,k e th x WebKit Thursday, November 3, 2011
  17. 17. <input type=”number” /> Piece of cake! y! s ex ’ k in l oo Port Thursday, November 3, 2011
  18. 18. <input type=”number” /> Theme Interface bool paintInnerSpinButton(RenderObject*, const PaintInfo&, const IntRect&); Thursday, November 3, 2011
  19. 19. <input type=”number” /> Theme Interface bool paintInnerSpinButton(RenderObject*, const PaintInfo&, const IntRect&); Theme Client Interface RenderTheme->paint() paintInnerSpinButton Port Thursday, November 3, 2011
  20. 20. Command Line WebKit Thursday, November 3, 2011
  21. 21. Demo Thursday, November 3, 2011
  22. 22. How’d you do that!? Thursday, November 3, 2011
  23. 23. Headless WebKit Thursday, November 3, 2011
  24. 24. “Headless” Thursday, November 3, 2011
  25. 25. Normal Browser Paint Layout Display Thursday, November 3, 2011
  26. 26. Headless Paint X Layout Display Thursday, November 3, 2011
  27. 27. What’s in it for me? Thursday, November 3, 2011
  28. 28. What’s in it for me? Automated “smoke” tests Continuous integration Pixel-perfect regression tests Web scraping ... Thursday, November 3, 2011
  29. 29. Demo Thursday, November 3, 2011
  30. 30. JavaScript Optimizations & Best Practices Thursday, November 3, 2011
  31. 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. 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. 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. 34. Best Practices Batching DOM Operations Reuse & Recycle DOM Cache Variables Optimal Enumeration Dirty Math Hack Thursday, November 3, 2011
  35. 35. Batch DOM Operations Thursday, November 3, 2011
  36. 36. setup <span id="test"></span> var span = document.getElementById('test'); Thursday, November 3, 2011
  37. 37. multiple ops span.innerHTML = ''; for (var i = 0; i < 10; i++) { span.innerHTML += 'Line #' + (i+1) + '<br />'; } single op span.innerHTML = ''; var buffer = ''; for (var i = 0; i < 10; i++) { buffer += 'Line #' + (i+1) + '<br />'; } span.innerHTML = buffer; Thursday, November 3, 2011
  38. 38. multiple ops span.innerHTML = ''; for (var i = 0; i < 10; i++) { span.innerHTML += 'Line #' + (i+1) + '<br />'; } slow fast single op span.innerHTML = ''; var buffer = ''; for (var i = 0; i < 10; i++) { buffer += 'Line #' + (i+1) + '<br />'; } span.innerHTML = buffer; Thursday, November 3, 2011
  39. 39. Batch DOM Operations http://jsperf.com/batch-dom-operations Thursday, November 3, 2011
  40. 40. Reuse & Recycle Thursday, November 3, 2011
  41. 41. Netflix Video Carousel Thursday, November 3, 2011
  42. 42. current pane current pane Thursday, November 3, 2011
  43. 43. transition pane current pane transition pane current pane Thursday, November 3, 2011
  44. 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
  45. 45. Variable Caching Thursday, November 3, 2011
  46. 46. setup <script> Some = { Deeply: { Nested: { array: [1, 2, 3, 4, 5] } } }; </script> Thursday, November 3, 2011
  47. 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. 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. 49. Variable Caching http://jsperf.com/variable-reference-caching Thursday, November 3, 2011
  50. 50. Enumeration Thursday, November 3, 2011
  51. 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. 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. 53. Enumeration http://jsperf.com/optimal-array-enumeration Thursday, November 3, 2011
  54. 54. Dirty Math Hack Thursday, November 3, 2011
  55. 55. setup <script> var myArray = []; for (var i = 0; i < 65535; i++) { myArray.push(Math.random() * 10000); } </script> Thursday, November 3, 2011
  56. 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. 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. 58. Math http://jsperf.com/jit-part-2 Thursday, November 3, 2011
  59. 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
  60. 60. Don’t Trust Intuition! Thursday, November 3, 2011
  61. 61. Code Analysis Thursday, November 3, 2011
  62. 62. Demo Thursday, November 3, 2011
  63. 63. "type": "IfStatement", "test": { "type": "BinaryExpression", "operator": "==", "left": { "type": "Identifier", "name": "x" }, "right": { "type": "Identifier", "name": "y" } if (x == y) foo(); }, "consequent": { "type": "ExpressionStatement", "expression": { "type": "CallExpression", "callee": { "type": "Identifier", "name": "foo" }, "arguments": [] } }, "alternate": null Thursday, November 3, 2011
  64. 64. "type": "IfStatement", "test": { "type": "BinaryExpression", "operator": "==", "left": { "type": "Identifier", "name": "x" }, "right": { "type": "Identifier", "name": "y" } if (x == y) foo(); }, "consequent": { "type": "ExpressionStatement", "expression": { "type": "CallExpression", "callee": { "type": "Identifier", "name": "foo" }, "arguments": [] } }, "alternate": null Thursday, November 3, 2011
  65. 65. "type": "IfStatement", "test": { "type": "BinaryExpression", "operator": "==", "left": { "type": "Identifier", "name": "x" }, "right": { "type": "Identifier", "name": "y" } if (x == y) foo(); }, "consequent": { "type": "ExpressionStatement", "expression": { Danger! "type": "CallExpression", "callee": { "type": "Identifier", "name": "foo" }, "arguments": [] } }, "alternate": null Thursday, November 3, 2011
  66. 66. Wrap Up Thursday, November 3, 2011
  67. 67. THANK YOU! Thursday, November 3, 2011
  68. 68. QUESTIONS? ariya @ sencha.com jarred @ sencha.com ariya.ofilabs.com about.me/jarrednicholls ariyahidayat jarrednicholls Thursday, November 3, 2011
  69. 69. Hardware Acceleration Today 3:00pm Thursday, November 3, 2011
  70. 70. Typical Dynamic Lang. Parser Runtime Interpreter Thursday, November 3, 2011
  71. 71. How does JavaScript talk to the DOM? Thursday, November 3, 2011
  72. 72. How does JavaScript talk to the DOM? BINDINGS! Thursday, November 3, 2011
  73. 73. window.location.href Thursday, November 3, 2011
  74. 74. window.location.href Thursday, November 3, 2011

Editor's Notes

  • Track B 11:15am-12:00pm \nA browser&apos;s JavaScript engine can seem like a magical black box. During this session, we&apos;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&apos;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&amp;#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&amp;#x2019;s news to many!\n
  • Let&amp;#x2019;s first understand what WebKit is, and why it&amp;#x2019;s ubiquitous.\n
  • Let&amp;#x2019;s start by telling you what WebKit isnt...\n
  • it&amp;#x2019;s NOT Safari!\n
  • it&amp;#x2019;s NOT Chrome!\n\nOk now that we&amp;#x2019;ve cleared up that whole mess...\n
  • \n
  • \n
  • Ok so it&amp;#x2019;s a rendering engine...but what exactly does that mean?\nThat&amp;#x2019;s best answered by describing how WebKit is consumed.... \n
  • How is WebKit so ubiquitous?\n
  • WebKit&amp;#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 = &amp;#x201C;implementation of the WebKit API interfaces (template/client methods)&amp;#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 &amp;#x201C;index &lt; length&amp;#x201D;, &amp;#x201C;test index&amp;#x201D; and &amp;#x201C;test value&amp;#x201D; into the same machine code and produce the same results. Chrome is obviously the fastest with &amp;#x201C;index &lt; length&amp;#x201D;.\n\n&amp;#x201C;for in&amp;#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&amp;#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&amp;#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&amp;#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
  • \n
  • benchmark benchmark benchmark!!\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • ×