Last active
March 18, 2025 09:12
-
-
Save acdha/092c6d79f9ebb888496c to your computer and use it in GitHub Desktop.
Comparing performance adding rows to a large table using innerHTML, the DOM API, React JSX and, eventually, React.createElement
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Render using innerHTML took:0.140s; tbody height=536364px | |
| Render using DOM took:0.076s; tbody height=536364px | |
| Render using React took:1.443s; tbody height=536364px |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> | |
| <meta charset="utf-8"> | |
| <title> | |
| Dropper – JavaScript Experiment | |
| </title> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap.min.css"> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap-theme.min.css"> | |
| <link rel="stylesheet" href="http://127.0.0.1:8000/main.css"> | |
| </head> | |
| <body> | |
| <div id="bagger" class="container"> | |
| <button id="add-files-innerhtml" class="btn btn-primary">Add rows using innerHTML</button> | |
| <button id="add-files-dom" class="btn btn-primary">Add rows using DOM</button> | |
| <button id="add-files-jsx" class="btn btn-primary">Add rows using React + JSX</button> | |
| <table class="table table-striped"><caption>Current Contents</caption><thead><tr><th class="file-name">Filename</th><th class="file-size">Size</th><th class="file-hash sha1">SHA-1</th><th class="file-hash sha256">SHA-256</th></tr></thead><tbody></tbody></table> | |
| </div> | |
| <script> | |
| var benchmarkRows = 10000; | |
| function displayElapsed(label, endTime, startTime) { | |
| var tbody = document.querySelector('tbody'); | |
| // Force layout by hitting tbody.clientHeight: | |
| alert('Render using ' + label + ' took:' + ((endTime - startTime) / 1000).toFixed(3) + 's; tbody height=' + tbody.clientHeight + 'px'); | |
| // Reset for back-to-back benchmarks: | |
| tbody.innerHTML = ''; | |
| } | |
| document.getElementById('add-files-innerhtml').addEventListener('click', function () { | |
| var startTime = Date.now(); | |
| var rowHTML = '<tr><td class="file-name">2015-02-17 21.37.05.jpg</td><td class="file-size">1.58 MB</td><td class="file-hash sha1" title="735388c2a781711009426e4f2952e069afcd6f50">735388c2a781711009426e4f2952e069afcd6f50</td><td class="file-hash sha256" title="fbe056c48fa92a618c0133648676a844187848f7f940a377338ab01410682f2c">fbe056c48fa92a618c0133648676a844187848f7f940a377338ab01410682f2c</td></tr>'; | |
| var tbody = document.querySelector('tbody'); | |
| var rows = []; | |
| for (var i = 0; i < benchmarkRows; i++) { | |
| rows.push(rowHTML); | |
| } | |
| tbody.innerHTML = rows.join('\n'); | |
| displayElapsed('innerHTML', Date.now(), startTime); | |
| }); | |
| document.getElementById('add-files-dom').addEventListener('click', function () { | |
| var startTime = Date.now(); | |
| var tbody = document.querySelector('tbody'); | |
| for (var i = 0; i < benchmarkRows; i++) { | |
| var tr = document.createElement('tr'); | |
| var fileName = document.createElement('td'); | |
| fileName.className = 'file-name' | |
| fileName.textContent = '2015-02-17 21.37.05.jpg' | |
| tr.appendChild(fileName); | |
| var fileSize = document.createElement('td'); | |
| fileSize.className = 'file-size'; | |
| fileSize.textContent = '1.58 MB' | |
| tr.appendChild(fileSize); | |
| var sha1 = document.createElement('td'); | |
| sha1.className = 'file-hash sha1' | |
| sha1.attributes.title='735388c2a781711009426e4f2952e069afcd6f50' | |
| sha1.textContent = '735388c2a781711009426e4f2952e069afcd6f50' | |
| tr.appendChild(sha1); | |
| var sha256 = document.createElement('td'); | |
| sha256.className = 'file-hash sha256' | |
| sha256.attributes.title='fbe056c48fa92a618c0133648676a844187848f7f940a377338ab01410682f2c'; | |
| sha256.textContent = 'fbe056c48fa92a618c0133648676a844187848f7f940a377338ab01410682f2c'; | |
| tr.appendChild(sha256); | |
| tbody.appendChild(tr); | |
| } | |
| displayElapsed('DOM', Date.now(), startTime); | |
| }); | |
| </script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/react.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/JSXTransformer.js"></script> | |
| <script type="text/jsx"> | |
| var TableComponent = React.createClass({ | |
| getInitialState: function () { | |
| return {displayRows: false}; | |
| }, | |
| showRows: function () { | |
| var startTime = Date.now(); | |
| this.setState({displayRows: true}); | |
| this.forceUpdate(function () { | |
| displayElapsed('React JSX', Date.now(), startTime); | |
| }); | |
| }, | |
| render: function () { | |
| var rows; | |
| if (!this.state.displayRows) { | |
| rows = <tr><td colspan="4"><button className='btn btn-primary' onClick={this.showRows}>Display Rows</button></td></tr>; | |
| } else { | |
| rows = this.props.data.map(function (row, idx) { | |
| return ( | |
| <tr key={idx}> | |
| <td className="file-name">{row[0]}</td> | |
| <td class="file-size">{row[1]}</td> | |
| <td class="file-hash sha1" title="{row[2]}">{row[2]}</td> | |
| <td class="file-hash sha256" title="{row[3]}">{row[3]}</td> | |
| </tr> | |
| ); | |
| }); | |
| } | |
| return ( | |
| <table className="table table-striped"> | |
| <caption>Current Contents</caption> | |
| <thead> | |
| <tr><th className="file-name">Filename</th><th className="file-size">Size</th><th className="file-hash sha1">SHA-1</th><th className="file-hash sha256">SHA-256</th></tr> | |
| </thead> | |
| <tbody> | |
| {rows} | |
| </tbody> | |
| </table> | |
| ) | |
| } | |
| }); | |
| document.getElementById('add-files-jsx').addEventListener('click', function () { | |
| var row = ['2015-02-17 21.37.05.jpg', '1.58 MB', '735388c2a781711009426e4f2952e069afcd6f50', | |
| 'fbe056c48fa92a618c0133648676a844187848f7f940a377338ab01410682f2c'], | |
| rows = []; | |
| for (var i = 0; i < benchmarkRows; i++) { | |
| rows.push(row); | |
| } | |
| React.render(React.createElement(TableComponent, {data: rows}), | |
| document.querySelector('table')); | |
| }); | |
| </script> | |
| </body></html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment