Skip to content

Commit

Permalink
perf(general): Trim fat (#35) 🐎
Browse files Browse the repository at this point in the history
* perf(pencil): Over 90% reduction in file size and over 80% reduction in Gzipped file after refactoring and reducing dependency footprint.

Before:
Stat: 611.06KB
Parsed: 105.41KB
Gzipped: 32.8KB

After:
Stat: 56.67KB
Parsed: 22.38KB
Gzipped: 6.02KB
  • Loading branch information
mrchief committed Jan 20, 2018
1 parent 48ec7e5 commit 4c036f5
Show file tree
Hide file tree
Showing 20 changed files with 2,341 additions and 2,760 deletions.
5 changes: 4 additions & 1 deletion .babelrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"presets": [["es2015", { "modules": false }], "stage-0", "react"],
"plugins": ["transform-class-properties"],
"plugins": [
"transform-class-properties",
"transform-react-remove-prop-types"
],
"env": {
"test": {
"presets": ["es2015", "stage-0", "react"],
Expand Down
2 changes: 1 addition & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
docs/bundle.js
docs/**/bundle.js
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,5 @@ dist
*.tgz

# Webstorm cache
.idea
.idea
/webpack-stats.json
7 changes: 4 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ cache:
- node_modules
node_js:
- '8'
- '7'
- '6'
before_install:
- npm install -g npm@5
- npm install -g greenkeeper-lockfile@1
install:
- yarn install --ignore-engines
before_script: greenkeeper-lockfile-update
after_script: greenkeeper-lockfile-upload
after_success:
- npm run coveralls
- npm run semantic-release
- npm run coveralls
- npm run travis-deploy-once "npm run semantic-release"
branches:
except:
- /^v\d+\.\d+\.\d+$/
2,074 changes: 852 additions & 1,222 deletions docs/examples/bootstrap/bundle.js

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions docs/examples/bootstrap/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ const onAction = ({action, node}) => { console.log(`onAction:: [${action}]`, nod
const onNodeToggle = (curNode) => { console.log('onNodeToggle::', curNode) }

ReactDOM.render(
<DropdownTreeSelect
data={data}
onChange={onChange}
onAction={onAction}
onNodeToggle={onNodeToggle}
<DropdownTreeSelect
data={data}
onChange={onChange}
onAction={onAction}
onNodeToggle={onNodeToggle}
className="bootstrap-demo"
/>, document.getElementById('app'))
/>, document.getElementById('app'))
2,074 changes: 852 additions & 1,222 deletions docs/examples/material/bundle.js

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions docs/examples/material/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ const onAction = ({action, node}) => { console.log(`onAction:: [${action}]`, nod
const onNodeToggle = (curNode) => { console.log('onNodeToggle::', curNode) }

ReactDOM.render(
<DropdownTreeSelect
data={data}
onChange={onChange}
onAction={onAction}
onNodeToggle={onNodeToggle}
<DropdownTreeSelect
data={data}
onChange={onChange}
onAction={onAction}
onNodeToggle={onNodeToggle}
className="mdl-demo"
/>, document.getElementById('app'))
/>, document.getElementById('app'))
11 changes: 8 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"demo": "webpack-dev-server --config docs/webpack.config.js",
"prepublishOnly": "npm run build",
"lint": "eslint --fix src docs webpack.config.js",
"semantic-release": "semantic-release pre && npm publish && semantic-release post",
"semantic-release": "semantic-release",
"travis-deploy-once": "travis-deploy-once",
"test": "cross-env NODE_ENV=test ava",
"test:cov": "rimraf .nyc_output && nyc npm test"
},
Expand All @@ -21,7 +22,7 @@
],
"dependencies": {
"classnames": "^2.2.5",
"lodash": "^4.17.4",
"lodash.debounce": "^4.0.8",
"prop-types": "^15.5.8",
"react-simple-dropdown": "^3.2.0"
},
Expand All @@ -32,6 +33,8 @@
"babel-loader": "^7.1.2",
"babel-plugin-istanbul": "^4.1.3",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-imports": "^1.4.1",
"babel-plugin-transform-react-remove-prop-types": "^0.4.12",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
Expand All @@ -57,10 +60,12 @@
"react-dom": "^16.0.0",
"react-test-renderer": "^16.0.0",
"rimraf": "^2.6.1",
"semantic-release": "^11.0.2",
"semantic-release": "^12.2.2",
"sinon": "^4.0.0",
"style-loader": "^0.19.0",
"travis-deploy-once": "^4.3.2",
"webpack": "^3.5.6",
"webpack-bundle-analyzer": "^2.9.2",
"webpack-dev-server": "^2.9.4"
},
"peerDependencies": {
Expand Down
8 changes: 4 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,10 @@ class DropdownTreeSelect extends Component {
{this.state.allNodesHidden
? <span className='no-matches'>No matches found</span>
: (<Tree data={this.state.tree}
searchModeOn={this.state.searchModeOn}
onAction={this.onAction}
onCheckboxChange={this.onCheckboxChange}
onNodeToggle={this.onNodeToggle} />)
searchModeOn={this.state.searchModeOn}
onAction={this.onAction}
onCheckboxChange={this.onCheckboxChange}
onNodeToggle={this.onNodeToggle} />)
}
</DropdownContent>
</Dropdown>
Expand Down
114 changes: 59 additions & 55 deletions src/input/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { Component } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import cn from 'classnames/bind'
import debounce from 'lodash/debounce'
Expand All @@ -7,66 +7,70 @@ import styles from './index.css'

const cx = cn.bind(styles)

class Input extends Component {
static propTypes = {
tags: PropTypes.array,
value: PropTypes.string,
placeholderText: PropTypes.string,
onInputChange: PropTypes.func,
onFocus: PropTypes.func,
onBlur: PropTypes.func,
onTagRemove: PropTypes.func,
inputRef: PropTypes.func
}
const getTags = (tags = [], onDelete) => {
return tags.map(
(tag, i) => {
const { _id, label, tagClassName } = tag
return (
<li className={cx('tag-item', tagClassName)} key={`tag-${i}`}>
<Tag
label={label}
id={_id}
onDelete={onDelete}
/>
</li>
)
}
)
}

constructor (props) {
super(props)
this.delayedCallback = debounce((e) => {
this.props.onInputChange(e.target.value)
}, 50, {
leading: true
})
}
const Input = (props) => {
const {
tags,
onTagRemove,
inputRef,
placeholderText = 'Choose...',
onFocus,
onBlur
} = props

const delayedCallback = debounce((e) => {
props.onInputChange(e.target.value)
}, 50, {
leading: true
})

onInputChange = (e) => {
const onInputChange = (e) => {
e.persist()
this.delayedCallback(e)
delayedCallback(e)
}

getTags (tags = [], onDelete) {
return tags.map(
(tag, i) => {
const { _id, label, tagClassName } = tag
return (
<li className={cx('tag-item', tagClassName)} key={`tag-${i}`}>
<Tag
label={label}
id={_id}
onDelete={onDelete}
/>
</li>
)
}
)
}
return (
<span>
<ul className={cx('tag-list')}>
{getTags(tags, onTagRemove)}
<li className={cx('tag-item')}>
<input type='text'
ref={inputRef}
placeholder={placeholderText}
onChange={onInputChange}
onFocus={onFocus}
onBlur={onBlur} />
</li>
</ul>
</span>
)
}

render () {
return (
<span>
<ul className={cx('tag-list')}>
{this.getTags(this.props.tags, this.props.onTagRemove)}
<li className={cx('tag-item')}>
<input type='text'
ref={this.props.inputRef}
placeholder={this.props.placeholderText || 'Choose...'}
onChange={this.onInputChange}
onFocus={this.props.onFocus}
onBlur={this.props.onBlur} />
</li>
</ul>
</span>
)
}
Input.propTypes = {
tags: PropTypes.array,
value: PropTypes.string,
placeholderText: PropTypes.string,
onInputChange: PropTypes.func,
onFocus: PropTypes.func,
onBlur: PropTypes.func,
onTagRemove: PropTypes.func,
inputRef: PropTypes.func
}

export default Input
8 changes: 8 additions & 0 deletions src/isEmpty.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* Simplified implmentation of isEmpty.
* Note: This is not complete and will return false positives for empty objects and likes.
* However, it suffices for the limited use-case of this project.
*/
const isEmpty = o => !o || (Array.isArray(o) && !o.length)

export default isEmpty
46 changes: 16 additions & 30 deletions src/tag/index.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,31 @@
import React, { Component } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import cn from 'classnames/bind'
import styles from './index.css'

const cx = cn.bind(styles)

class Button extends Component {
static propTypes = {
id: PropTypes.string.isRequired,
onDelete: PropTypes.func
}

render () {
return (
<button onClick={this.onClick} className={cx('tag-remove')} type='button'>x</button>
)
}
const Tag = (props) => {
const { id, label, onDelete } = props

onClick = (e) => {
const onClick = (e) => {
// this is needed to stop the drawer from closing
e.stopPropagation()
this.props.onDelete(this.props.id)
onDelete(id)
}
}

class Tag extends Component {
static propTypes = {
id: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
onDelete: PropTypes.func
}
return (
<span className={cx('tag')}>
{label}
<button onClick={onClick} className={cx('tag-remove')} type='button'>x</button>
</span>
)
}

render () {
const { id, label, onDelete } = this.props
return (
<span className={cx('tag')}>
{label}
<Button id={id} onDelete={onDelete} />
</span>
)
}
Tag.propTypes = {
id: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
onDelete: PropTypes.func
}

export default Tag
5 changes: 2 additions & 3 deletions src/tree-manager/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import isEmpty from 'lodash/isEmpty'
import cloneDeep from 'lodash/cloneDeep'
import isEmpty from '../isEmpty'
import flattenTree from './flatten-tree'

class TreeManager {
constructor (tree) {
this._src = tree
this.tree = flattenTree(cloneDeep(tree))
this.tree = flattenTree(JSON.parse(JSON.stringify(tree)))
this.tree.forEach(node => { this.setInitialCheckState(node) })
this.searchMaps = new Map()
}
Expand Down
31 changes: 15 additions & 16 deletions src/tree-node/action.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
import React, { Component } from 'react'
import React from 'react'
import PropTypes from 'prop-types'

class Action extends Component {
static propTypes = {
title: PropTypes.string,
text: PropTypes.string,
className: PropTypes.string,
actionData: PropTypes.object,
onAction: PropTypes.func
}
const Action = (props) => {
const { title, className, text, onAction, actionData } = props

onClick = (e) => {
if (typeof this.props.onAction === 'function') {
this.props.onAction(this.props.actionData)
const onClick = (e) => {
if (typeof onAction === 'function') {
onAction(actionData)
}
}

render () {
const { title, className, text } = this.props
return <i title={title} className={className} onClick={this.onClick}>{text}</i>
}
return <i title={title} className={className} onClick={onClick}>{text}</i>
}

Action.propTypes = {
title: PropTypes.string,
text: PropTypes.string,
className: PropTypes.string,
actionData: PropTypes.object,
onAction: PropTypes.func
}

export default Action
Loading

0 comments on commit 4c036f5

Please sign in to comment.