Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create-emotion-server: refactor inline for performance #725

Merged
merged 1 commit into from
Jun 14, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 48 additions & 51 deletions packages/create-emotion-server/src/inline.js
Original file line number Diff line number Diff line change
@@ -1,77 +1,74 @@
// @flow
import type { Emotion } from 'create-emotion'

function toTag(
emotion: Emotion,
ids: Array<string>,
thing: { keys: Array<string> },
function generateStyleTag(
cssKey: string,
ids: string,
styles: string,
nonceString: string
) {
let idhash = ids.reduce((o, x) => {
o[x] = true
return o
}, {})
let styles = ''
let idHydration = ''
thing.keys = thing.keys.filter(id => {
if (idhash[id] !== undefined && emotion.caches.inserted[id] !== true) {
styles += emotion.caches.inserted[id]
idHydration += ` ${id}`
}
return true
})
return `<style data-emotion-${emotion.caches.key}="${idHydration.substring(
return `<style data-emotion-${cssKey}="${ids.substring(
1
)}"${nonceString}>${styles}</style>`
}

const createRenderStylesToString = (emotion: Emotion, nonceString: string) => (
html: string
): string => {
let regex = new RegExp(`<|${emotion.caches.key}-([a-zA-Z0-9-]+)`, 'gm')
const { inserted, key: cssKey, registered } = emotion.caches
const regex = new RegExp(`<|${cssKey}-([a-zA-Z0-9-]+)`, 'gm')

const seen = {}

let match
let lastBackIndex = 0
let idBuffer = []
let result = ''
let insed = {}
let keys = Object.keys(emotion.caches.inserted)
let globalStyles = ''
let globalIds = ''
keys = keys.filter(id => {
if (
emotion.caches.registered[`${emotion.caches.key}-${id}`] === undefined &&
emotion.caches.inserted[id] !== true
) {
globalStyles += emotion.caches.inserted[id]
globalIds += ` ${id}`
return false
let globalStyles = ''

for (const id in inserted) {
if (inserted.hasOwnProperty(id)) {
const style = inserted[id]
const key = `${cssKey}-${id}`
if (style !== true && registered[key] === undefined) {
globalStyles += style
globalIds += ` ${id}`
}
}
return true
})
}

if (globalStyles !== '') {
result += `<style data-emotion-${emotion.caches.key}="${globalIds.substring(
1
)}"${nonceString}>${globalStyles}</style>`
result = generateStyleTag(cssKey, globalIds, globalStyles, nonceString)
}
const thing = { keys }

let ids = ''
let styles = ''
let lastInsertionPoint = 0
let match

while ((match = regex.exec(html)) !== null) {
if (match[0] === '<') {
idBuffer = idBuffer.filter(x => !insed[x])
if (idBuffer.length > 0) {
result += toTag(emotion, idBuffer, thing, nonceString)
if (ids !== '') {
result += generateStyleTag(cssKey, ids, styles, nonceString)
ids = ''
styles = ''
}
result += html.substring(lastBackIndex, match.index)
lastBackIndex = match.index
idBuffer.forEach(x => {
insed[x] = true
})
idBuffer = []
} else {
idBuffer.push(match[1])
result += html.substring(lastInsertionPoint, match.index)
lastInsertionPoint = match.index
continue
}

const id = match[1]
const style = inserted[id]
if (style === true || seen[id]) {
continue
}

seen[id] = true
styles += style
ids += ` ${id}`
}
result += html.substring(lastBackIndex, html.length)

result += html.substring(lastInsertionPoint)

return result
}

Expand Down