SlideShare a Scribd company logo
Thursday, November 3, 2011
Typical Scenario
                                               This is
                                              awesome!




                                         un
                                  t to r
                             forge tests
                                the




Thursday, November 3, 2011
HACKING WEBKIT & ITS
                        JAVASCRIPT ENGINES
                               Ariya Hidayat & Jarred Nicholls
                                          Sencha




                             Twitter: @ariyahidayat   @jarrednicholls

Thursday, November 3, 2011
What is WebKit?




Thursday, November 3, 2011
Browser at a High Level
                                             User Interface




                                                                         Data Persistence
                                          Browser Engine




                                          Render Engine



                             Networking     JavaScript        Graphics
                                I/O           Engine           Stack




Thursday, November 3, 2011
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
≠
Thursday, November 3, 2011
⊂
Thursday, November 3, 2011
WebKit is
                             EVERYWHERE!




Thursday, November 3, 2011
Even in your living room!
Thursday, November 3, 2011
How?


Thursday, November 3, 2011
Client Interface
Thursday, November 3, 2011
WebKit Components
                                                Render Engine
                                                    CSS
                                  DOM                                  SVG



                   HTML                                                            Canvas

                                                   WebCore




                             Client Interface                JavaScript Engine (JSC/V8)



Thursday, November 3, 2011
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
<input type=”number” />


                                     Paint me
                                    some spin
                                  buttons, STAT!


                                     I know how to
                                         do that!


                WebKit                               Port



Thursday, November 3, 2011
<input type=”number” />



                                           ri
                                         pl ght
                                           ea     th
                                              se     er
                                                 ,k     e
                                                    th
                                                       x



                WebKit



Thursday, November 3, 2011
<input type=”number” />


                                                 Piece of cake!




                                            y!
                                       s ex
                                   ’
                              k in
                        l oo                                      Port



Thursday, November 3, 2011
<input type=”number” />

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




Thursday, November 3, 2011
<input type=”number” />

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




                                            Theme
                  Client Interface
                                     RenderTheme->paint()




                                                            paintInnerSpinButton   Port




Thursday, November 3, 2011
Command Line
                                WebKit
Thursday, November 3, 2011
Demo




Thursday, November 3, 2011
How’d you do that!?




Thursday, November 3, 2011
Headless WebKit



Thursday, November 3, 2011
“Headless”




Thursday, November 3, 2011
Normal Browser


                                      Paint




                             Layout           Display




Thursday, November 3, 2011
Headless


                                         Paint




                                                 X
                             Layout              Display




Thursday, November 3, 2011
What’s in it for me?




Thursday, November 3, 2011
What’s in it for me?
                                Automated “smoke” tests

                                  Continuous integration

                               Pixel-perfect regression tests

                                      Web scraping

                                             ...


Thursday, November 3, 2011
Demo




Thursday, November 3, 2011
JavaScript
                      Optimizations & Best
                           Practices



Thursday, November 3, 2011
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
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
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
Best Practices
       Batching DOM Operations

       Reuse & Recycle DOM

       Cache Variables

       Optimal Enumeration

       Dirty Math Hack




Thursday, November 3, 2011
Batch DOM Operations




Thursday, November 3, 2011
setup

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




Thursday, November 3, 2011
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
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
Batch DOM Operations




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



Thursday, November 3, 2011
Reuse & Recycle




Thursday, November 3, 2011
Netflix Video Carousel
Thursday, November 3, 2011
current pane




                             current pane




Thursday, November 3, 2011
transition pane                                       current pane




                                            transition pane




                             current pane




Thursday, November 3, 2011
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
Variable Caching




Thursday, November 3, 2011
setup

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




Thursday, November 3, 2011
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
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
Variable Caching




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



Thursday, November 3, 2011
Enumeration




Thursday, November 3, 2011
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
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
Enumeration




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



Thursday, November 3, 2011
Dirty Math Hack




Thursday, November 3, 2011
setup

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




Thursday, November 3, 2011
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
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
Math




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



Thursday, November 3, 2011
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
Don’t Trust Intuition!




Thursday, November 3, 2011
Code Analysis




Thursday, November 3, 2011
Demo




Thursday, November 3, 2011
"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
"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
"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
Wrap Up




Thursday, November 3, 2011
THANK YOU!




Thursday, November 3, 2011
QUESTIONS?


            ariya @ sencha.com               jarred @ sencha.com



                  ariya.ofilabs.com          about.me/jarrednicholls


                             ariyahidayat    jarrednicholls



Thursday, November 3, 2011
Hardware Acceleration
                    Today 3:00pm




Thursday, November 3, 2011
Typical Dynamic Lang.


                             Parser                 Runtime




                                      Interpreter




Thursday, November 3, 2011
How does JavaScript
                        talk to the DOM?




Thursday, November 3, 2011
How does JavaScript
                        talk to the DOM?


                             BINDINGS!

Thursday, November 3, 2011
window.location.href




Thursday, November 3, 2011
window.location.href




Thursday, November 3, 2011

More Related Content

Hacking Webkit & Its JavaScript Engines

  • 2. Typical Scenario This is awesome! un t to r forge tests the Thursday, November 3, 2011
  • 3. HACKING WEBKIT & ITS JAVASCRIPT ENGINES Ariya Hidayat & Jarred Nicholls Sencha Twitter: @ariyahidayat @jarrednicholls Thursday, November 3, 2011
  • 4. What is WebKit? Thursday, November 3, 2011
  • 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
  • 9. WebKit is EVERYWHERE! Thursday, November 3, 2011
  • 10. Even in your living room! Thursday, November 3, 2011
  • 13. WebKit Components Render Engine CSS DOM SVG HTML Canvas WebCore Client Interface JavaScript Engine (JSC/V8) Thursday, November 3, 2011
  • 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. <input type=”number” /> Paint me some spin buttons, STAT! I know how to do that! WebKit Port Thursday, November 3, 2011
  • 16. <input type=”number” /> ri pl ght ea th se er ,k e th x WebKit Thursday, November 3, 2011
  • 17. <input type=”number” /> Piece of cake! y! s ex ’ k in l oo Port Thursday, November 3, 2011
  • 18. <input type=”number” /> Theme Interface bool paintInnerSpinButton(RenderObject*, const PaintInfo&, const IntRect&); Thursday, November 3, 2011
  • 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. Command Line WebKit Thursday, November 3, 2011
  • 22. How’d you do that!? Thursday, November 3, 2011
  • 25. Normal Browser Paint Layout Display Thursday, November 3, 2011
  • 26. Headless Paint X Layout Display Thursday, November 3, 2011
  • 27. What’s in it for me? Thursday, November 3, 2011
  • 28. What’s in it for me? Automated “smoke” tests Continuous integration Pixel-perfect regression tests Web scraping ... 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
  • 35. Batch DOM Operations Thursday, November 3, 2011
  • 36. setup <span id="test"></span> var span = document.getElementById('test'); Thursday, November 3, 2011
  • 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. 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. Batch DOM Operations http://jsperf.com/batch-dom-operations Thursday, November 3, 2011
  • 40. Reuse & Recycle 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
  • 46. setup <script> Some = { Deeply: { Nested: { array: [1, 2, 3, 4, 5] } } }; </script> 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
  • 54. Dirty Math Hack 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
  • 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. "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. "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
  • 68. QUESTIONS? ariya @ sencha.com jarred @ sencha.com ariya.ofilabs.com about.me/jarrednicholls ariyahidayat jarrednicholls Thursday, November 3, 2011
  • 69. Hardware Acceleration Today 3:00pm Thursday, November 3, 2011
  • 70. Typical Dynamic Lang. Parser Runtime Interpreter Thursday, November 3, 2011
  • 71. How does JavaScript talk to the DOM? Thursday, November 3, 2011
  • 72. How does JavaScript talk to the DOM? BINDINGS! Thursday, November 3, 2011

Editor's Notes

  1. 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
  2. \n
  3. 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
  4. \n
  5. traditional desktop browsers and frameworks\n
  6. mobile devices (smartphones, tablets, etc.)\n
  7. set top boxes (like Apple TV, Google TV, etc.), game consoles and hand helds, Netflix\n
  8. and yes, on the server and command line\n
  9. \n
  10. 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
  11. Let&amp;#x2019;s first understand what WebKit is, and why it&amp;#x2019;s ubiquitous.\n
  12. Let&amp;#x2019;s start by telling you what WebKit isnt...\n
  13. it&amp;#x2019;s NOT Safari!\n
  14. it&amp;#x2019;s NOT Chrome!\n\nOk now that we&amp;#x2019;ve cleared up that whole mess...\n
  15. \n
  16. \n
  17. 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
  18. How is WebKit so ubiquitous?\n
  19. 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
  20. Port = &amp;#x201C;implementation of the WebKit API interfaces (template/client methods)&amp;#x201D;\n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. 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
  28. \n
  29. \n
  30. \n
  31. VQA = Visual Quality Assurance\n\nNeat little pyramid eh?\n
  32. VQA = Visual Quality Assurance\n\nNeat little pyramid eh?\n
  33. VQA = Visual Quality Assurance\n\nNeat little pyramid eh?\n
  34. VQA = Visual Quality Assurance\n\nNeat little pyramid eh?\n
  35. VQA = Visual Quality Assurance\n\nNeat little pyramid eh?\n
  36. VQA = Visual Quality Assurance\n\nNeat little pyramid eh?\n
  37. VQA = Visual Quality Assurance\n\nNeat little pyramid eh?\n
  38. VQA = Visual Quality Assurance\n\nNeat little pyramid eh?\n
  39. VQA = Visual Quality Assurance\n\nNeat little pyramid eh?\n
  40. jasmine tests\npixel comparison for visual regression testing\n
  41. \n
  42. parser, runtime, interpreter/VM\n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. 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
  67. \n
  68. \n
  69. it&amp;#x2019;s even easier to read too\n
  70. \n
  71. 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
  72. 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
  73. \n
  74. \n
  75. \n
  76. avoiding the inner loop function calls will speed up your performance sensitive mathematical operations.\n
  77. Avoid native function calls in tight loops doing mathematic calculations.\nPut major math operations in a helper function to be JIT friendly.\n
  78. \n
  79. \n
  80. \n
  81. \n
  82. 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
  83. \n
  84. \n
  85. \n
  86. 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
  87. \n
  88. benchmark benchmark benchmark!!\n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n
  104. \n
  105. \n