diff --git a/package.json b/package.json index c785e9a..e253543 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,6 @@ "babylon": "6.14.1", "convert-source-map": "1.3.0", "escape-string-regexp": "1.0.5", - "object.entries": "1.0.4", "source-map": "0.5.6", "string-hash": "1.1.1", "stylis": "1.2.3" diff --git a/src/render.js b/src/render.js index 10bc8ae..09d00d9 100644 --- a/src/render.js +++ b/src/render.js @@ -1,48 +1,40 @@ -import entries from 'object.entries' - -const {hasOwnProperty} = Object.prototype -const tags = {} -let prevStyles = {} +const tags = new Map() +let prevStyles = new Map() export default typeof window === 'undefined' ? renderOnServer : renderOnClient function renderOnServer() {} -function renderOnClient(components) { - const styles = {} - for (const c of components) { - styles[c.props.styleId] = c - } - +function renderOnClient(styles) { patch(diff(prevStyles, styles)) - prevStyles = styles } function diff(a, b) { - const added = entries(b).filter(([k]) => !hasOwnProperty.call(a, k)) - const removed = entries(a).filter(([k]) => !hasOwnProperty.call(b, k)) + const added = Array.from(b.entries()).filter(([k]) => !a.has(k)) + const removed = Array.from(a.entries()).filter(([k]) => !b.has(k)) return [added, removed] } -const fromServer = {} +const fromServer = new Map() function patch([added, removed]) { for (const [id, c] of added) { // avoid duplicates from server-rendered markup - if (undefined === fromServer[id]) { - fromServer[id] = document.getElementById(`__jsx-style-${id}`) + if (!fromServer.has(id)) { + fromServer.set(id, document.getElementById(`__jsx-style-${id}`)) } - tags[id] = fromServer[id] || makeStyleTag(c.props.css) + const tag = fromServer.get(id) || makeStyleTag(c.props.css) + tags.set(id, tag) } for (const [id] of removed) { - const t = tags[id] - delete tags[id] + const t = tags.get(id) + tags.delete(id) t.parentNode.removeChild(t) // avoid checking the DOM later on - fromServer[id] = null + fromServer.delete(id) } } diff --git a/src/server.js b/src/server.js index 25e5dd2..12b1286 100644 --- a/src/server.js +++ b/src/server.js @@ -1,22 +1,18 @@ import React from 'react' import {flush} from './style' -const {hasOwnProperty} = Object.prototype - export default function flushToReact() { const mem = flush() const arr = [] - for (const id in mem) { - if (hasOwnProperty.call(mem, id)) { - arr.push(React.createElement('style', { - id: `__jsx-style-${id}`, - // avoid warnings upon render with a key - key: `__jsx-style-${id}`, - dangerouslySetInnerHTML: { - __html: mem[id] - } - })) - } + for (const [id, c] of mem) { + arr.push(React.createElement('style', { + id: `__jsx-style-${id}`, + // avoid warnings upon render with a key + key: `__jsx-style-${id}`, + dangerouslySetInnerHTML: { + __html: c.props.css + } + })) } return arr } @@ -24,10 +20,8 @@ export default function flushToReact() { export function flushToHTML() { const mem = flush() let html = '' - for (const id in mem) { - if (hasOwnProperty.call(mem, id)) { - html += `` - } + for (const [id, c] of mem) { + html += `` } return html } diff --git a/src/style.js b/src/style.js index fdf59b6..db8f5e9 100644 --- a/src/style.js +++ b/src/style.js @@ -21,15 +21,17 @@ export default class extends Component { } } -export function flush() { - const ret = {} - - for (const {props} of components) { - ret[props.styleId] = props.css +function componentMap() { + const ret = new Map() + for (const c of components) { + ret.set(c.props.styleId, c) } + return ret +} +export function flush() { + const ret = componentMap() components = [] - return ret } @@ -49,5 +51,5 @@ function unmount(component) { } function update() { - render(components) + render(componentMap()) } diff --git a/yarn.lock b/yarn.lock index 047467a..b1e93f8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1122,11 +1122,11 @@ babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.21.0, babel-types@^6.22 lodash "^4.2.0" to-fast-properties "^1.0.1" -babylon@6.14.1, babylon@^6.11.0: +babylon@6.14.1, babylon@^6.1.0, babylon@^6.11.0: version "6.14.1" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.14.1.tgz#956275fab72753ad9b3435d7afe58f8bf0a29815" -babylon@^6.1.0, babylon@^6.15.0: +babylon@^6.15.0: version "6.15.0" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.15.0.tgz#ba65cfa1a80e1759b0e89fb562e27dccae70348e" @@ -1530,13 +1530,6 @@ defaults@^1.0.0: dependencies: clone "^1.0.2" -define-properties@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" - dependencies: - foreach "^2.0.5" - object-keys "^1.0.8" - del@^2.0.2: version "2.2.2" resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" @@ -1639,23 +1632,6 @@ error-ex@^1.2.0: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.6.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.7.0.tgz#dfade774e01bfcd97f96180298c449c8623fb94c" - dependencies: - es-to-primitive "^1.1.1" - function-bind "^1.1.0" - is-callable "^1.1.3" - is-regex "^1.0.3" - -es-to-primitive@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" - dependencies: - is-callable "^1.1.1" - is-date-object "^1.0.1" - is-symbol "^1.0.1" - es5-ext@^0.10.7, es5-ext@^0.10.8, es5-ext@~0.10.11, es5-ext@~0.10.2, es5-ext@~0.10.7: version "0.10.12" resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.12.tgz#aa84641d4db76b62abba5e45fd805ecbab140047" @@ -2072,10 +2048,6 @@ for-own@^0.1.4: dependencies: for-in "^0.1.5" -foreach@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" - forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -2124,7 +2096,7 @@ fstream@^1.0.0, fstream@^1.0.2, fstream@~1.0.10: mkdirp ">=0.5 0" rimraf "2" -function-bind@^1.0.2, function-bind@^1.1.0: +function-bind@^1.0.2: version "1.1.0" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771" @@ -2605,20 +2577,12 @@ is-builtin-module@^1.0.0: dependencies: builtin-modules "^1.0.0" -is-callable@^1.1.1, is-callable@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" - is-ci@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.0.10.tgz#f739336b2632365061a9d48270cd56ae3369318e" dependencies: ci-info "^1.0.0" -is-date-object@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" - is-dotfile@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d" @@ -2763,10 +2727,6 @@ is-redirect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" -is-regex@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.3.tgz#0d55182bddf9f2fde278220aec3a75642c908637" - is-relative@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-0.2.1.tgz#d27f4c7d516d175fb610db84bbeef23c3bc97aa5" @@ -2787,10 +2747,6 @@ is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" -is-symbol@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" - is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" @@ -3401,19 +3357,6 @@ object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" -object-keys@^1.0.8: - version "1.0.11" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" - -object.entries@1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.0.4.tgz#1bf9a4dd2288f5b33f3a993d257661f05d161a5f" - dependencies: - define-properties "^1.1.2" - es-abstract "^1.6.1" - function-bind "^1.1.0" - has "^1.0.1" - object.omit@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" @@ -4307,6 +4250,10 @@ strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" +stylis@1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-1.2.3.tgz#57c97b2a71f835b00b92460d751b2aca4355b91b" + supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"