Skip to content

Commit 1e96cbc

Browse files
committed
Initial commit
0 parents  commit 1e96cbc

19 files changed

+7747
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
yarn-error.log

dist/after.dcb8920f2fed4dffac6d.js

+441
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/after.html

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Webpack App</title>
6+
</head>
7+
<body>
8+
<div id="root"></div>
9+
<script type="text/javascript" src="/dist/after.dcb8920f2fed4dffac6d.js"></script></body>
10+
</html>

dist/before.fd85aec433329da0f9dc.js

+441
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/before.html

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Webpack App</title>
6+
</head>
7+
<body>
8+
<div id="root"></div>
9+
<script type="text/javascript" src="/dist/before.fd85aec433329da0f9dc.js"></script></body>
10+
</html>

package.json

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "optimizind-react-demo",
3+
"version": "1.0.0",
4+
"main": "index.js",
5+
"scripts": {
6+
"build": "yarn run webpack --mode=development",
7+
"start": "yarn run webpack-dev-server --mode=development"
8+
},
9+
"license": "MIT",
10+
"dependencies": {
11+
"react": "^16.2.0",
12+
"react-dom": "^16.2.0"
13+
},
14+
"devDependencies": {
15+
"css-loader": "^0.28.11",
16+
"html-webpack-plugin": "^3.1.0",
17+
"style-loader": "^0.20.3",
18+
"webpack": "^4.2.0",
19+
"webpack-cli": "^2.0.13",
20+
"webpack-dev-server": "^3.1.1"
21+
}
22+
}

readme.md

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
## Optimizing React demo
2+
3+
This is a demo for an article [Optimizing React]() in Evil Martians [blog](https://evilmartians.com/chronicles).
4+
5+
There is two subfolders in `src` directory - `before` is for app with standard components and `after` for the version with `PureComponent` in table rows.
6+
7+
### Demo in action
8+
9+
- [Before demo](https://iadramelk.github.in/optimizing-react-demo/dist/before.html)
10+
- [After demo](https://iadramelk.github.in/optimizing-react-demo/dist/after.html)
11+
12+
### Local experiments
13+
14+
- `yarn install` to install dependencies.
15+
- `yarn start` to start dev server.
16+
- `yarn build` to created static demo files in `dist` dir.

src/after/app.js

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React from 'react';
2+
3+
import Table from './table';
4+
5+
export default class App extends React.Component {
6+
constructor(props) {
7+
super(props);
8+
9+
this.state = {
10+
rows: [
11+
{
12+
id: 0,
13+
title: 'Title 0',
14+
},
15+
]
16+
};
17+
18+
this.handleAddRow = this.handleAddRow.bind(this);
19+
}
20+
21+
handleAddRow() {
22+
const { rows } = this.state;
23+
24+
this.setState({ rows: rows.concat([ { id: rows.length, title: `Title ${rows.length}` } ]) });
25+
}
26+
27+
render() {
28+
return React.createElement('div', { className: 'app' },
29+
React.createElement('button', { onClick: this.handleAddRow, className: 'button' }, 'Add row'),
30+
React.createElement('br'),
31+
React.createElement('br'),
32+
React.createElement(Table, { rows: this.state.rows })
33+
);
34+
}
35+
}

src/after/button.js

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React from 'react';
2+
3+
export default class Button extends React.Component {
4+
constructor(props) {
5+
super(props);
6+
7+
this.state = {
8+
count: 0,
9+
};
10+
11+
this.handleIncrement = this.handleIncrement.bind(this);
12+
}
13+
14+
handleIncrement() {
15+
this.setState({ count: this.state.count + 1 });
16+
}
17+
18+
render() {
19+
return React.createElement(
20+
'button',
21+
{
22+
onClick: this.handleIncrement,
23+
className: 'button'
24+
},
25+
`Count: ${this.state.count}`
26+
);
27+
}
28+
}

src/after/index.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import '../style.css';
2+
3+
import React from 'react/cjs/react.development';
4+
import ReactDOM from 'react-dom/cjs/react-dom.development';
5+
6+
import App from './app';
7+
8+
ReactDOM.render(
9+
React.createElement(App),
10+
document.querySelector('#root')
11+
)

src/after/table.js

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import React from 'react';
2+
3+
import Button from './button';
4+
5+
class TableRow extends React.PureComponent {
6+
render() {
7+
return React.createElement('tr', { className: 'row' },
8+
React.createElement('td', { className: 'cell' }, this.props.title),
9+
React.createElement('td', { className: 'cell' }, React.createElement(Button)),
10+
);
11+
}
12+
};
13+
14+
export default class Table extends React.Component {
15+
render() {
16+
return React.createElement(
17+
'table',
18+
{ className: 'table' },
19+
React.createElement(
20+
'tbody',
21+
{ className: 'body' },
22+
this.props.rows.map(({ id, title }) => React.createElement(TableRow, { key: id, title }))
23+
)
24+
);
25+
}
26+
};

src/before/app.js

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React from 'react';
2+
3+
import Table from './table';
4+
5+
export default class App extends React.Component {
6+
constructor(props) {
7+
super(props);
8+
9+
this.state = {
10+
rows: [
11+
{
12+
id: 0,
13+
title: 'Title 0',
14+
},
15+
]
16+
};
17+
18+
this.handleAddRow = this.handleAddRow.bind(this);
19+
}
20+
21+
handleAddRow() {
22+
const { rows } = this.state;
23+
24+
this.setState({ rows: rows.concat([ { id: rows.length, title: `Title ${rows.length}` } ]) });
25+
}
26+
27+
render() {
28+
return React.createElement('div', { className: 'app' },
29+
React.createElement('button', { onClick: this.handleAddRow, className: 'button' }, 'Add row'),
30+
React.createElement('br'),
31+
React.createElement('br'),
32+
React.createElement(Table, { rows: this.state.rows })
33+
);
34+
}
35+
}

src/before/button.js

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React from 'react';
2+
3+
export default class Button extends React.Component {
4+
constructor(props) {
5+
super(props);
6+
7+
this.state = {
8+
count: 0,
9+
};
10+
11+
this.handleIncrement = this.handleIncrement.bind(this);
12+
}
13+
14+
handleIncrement() {
15+
this.setState({ count: this.state.count + 1 });
16+
}
17+
18+
render() {
19+
return React.createElement(
20+
'button',
21+
{
22+
onClick: this.handleIncrement,
23+
className: 'button'
24+
},
25+
`Count: ${this.state.count}`
26+
);
27+
}
28+
}

src/before/index.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import '../style.css';
2+
3+
import React from 'react/cjs/react.development';
4+
import ReactDOM from 'react-dom/cjs/react-dom.development';
5+
6+
import App from './app';
7+
8+
ReactDOM.render(
9+
React.createElement(App),
10+
document.querySelector('#root')
11+
);

src/before/table.js

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import React from 'react';
2+
3+
import Button from './button';
4+
5+
class TableRow extends React.Component {
6+
render() {
7+
return React.createElement('tr', { className: 'row' },
8+
React.createElement('td', { className: 'cell' }, this.props.title),
9+
React.createElement('td', { className: 'cell' }, React.createElement(Button)),
10+
);
11+
}
12+
};
13+
14+
export default class Table extends React.Component {
15+
render() {
16+
return React.createElement(
17+
'table',
18+
{ className: 'table' },
19+
React.createElement(
20+
'tbody',
21+
{ className: 'body' },
22+
this.props.rows.map(({ id, title }) => React.createElement(TableRow, { key: id, title }))
23+
)
24+
);
25+
}
26+
};

src/style.css

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
.app {
2+
margin: 20px;
3+
padding: 20px;
4+
font: 20px Arial;
5+
}
6+
7+
.table {
8+
border: 1px solid #ddd;
9+
border-spacing: 10px;
10+
}
11+
12+
.body {
13+
}
14+
15+
.row {
16+
border: 1px solid #ddd;
17+
}
18+
19+
.cell {
20+
padding: 10px;
21+
border: 1px solid #ddd;
22+
}
23+
24+
.button {
25+
font: 20px Arial;
26+
}

template.ejs

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<title><%= htmlWebpackPlugin.options.title %></title>
6+
</head>
7+
<body>
8+
<div id="root"></div>
9+
</body>
10+
</html>

webpack.config.js

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
const webpack = require('webpack');
2+
3+
const HtmlWebpackPlugin = require('html-webpack-plugin');
4+
5+
const path = require('path');
6+
7+
module.exports = {
8+
entry: {
9+
before: path.join(process.cwd(), 'src', 'before', 'index.js'),
10+
after: path.join(process.cwd(), 'src', 'after', 'index.js'),
11+
},
12+
output: {
13+
path: path.join(process.cwd(), 'dist/'),
14+
filename: '[name].[chunkhash].js',
15+
publicPath: '/dist/',
16+
},
17+
module: {
18+
rules: [
19+
{
20+
test: /\.css$/,
21+
use: [
22+
'style-loader',
23+
'css-loader'
24+
]
25+
}
26+
]
27+
},
28+
devServer: {
29+
publicPath: '/dist',
30+
host: 'localhost',
31+
port: 5555,
32+
headers: {
33+
'Access-Control-Allow-Origin': '*',
34+
},
35+
stats: {
36+
colors: true,
37+
},
38+
},
39+
plugins: [
40+
new HtmlWebpackPlugin({
41+
template: './template.ejs',
42+
filename: 'before.html',
43+
chunks: ['before'],
44+
}),
45+
new HtmlWebpackPlugin({
46+
template: './template.ejs',
47+
filename: 'after.html',
48+
chunks: ['after'],
49+
})
50+
],
51+
};

0 commit comments

Comments
 (0)