From 0631851b7bea5ec2a3a548098dd3437683cfca49 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Sun, 16 Aug 2020 14:48:00 +0200 Subject: [PATCH] introduce a useMemo utility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Naming is hard so I took this name from the React hook 😎 Also use this useMemoy utility to make sure that the extractUtilityNames is cached. There is no need to re-compute the utility names all the time. --- src/flagged/applyComplexClasses.js | 26 ++++++++++++-------------- src/util/useMemo.js | 16 ++++++++++++++++ 2 files changed, 28 insertions(+), 14 deletions(-) create mode 100644 src/util/useMemo.js diff --git a/src/flagged/applyComplexClasses.js b/src/flagged/applyComplexClasses.js index 8d8f7194c..ee710d91d 100644 --- a/src/flagged/applyComplexClasses.js +++ b/src/flagged/applyComplexClasses.js @@ -8,6 +8,7 @@ import substituteResponsiveAtRules from '../lib/substituteResponsiveAtRules' import convertLayerAtRulesToControlComments from '../lib/convertLayerAtRulesToControlComments' import substituteScreenAtRules from '../lib/substituteScreenAtRules' import prefixSelector from '../util/prefixSelector' +import { useMemo } from '../util/useMemo' function hasAtRule(css, atRule) { let foundAtRule = false @@ -39,7 +40,7 @@ const tailwindApplyPlaceholder = selectorParser.attribute({ }) function generateRulesFromApply({ rule, utilityName: className, classPosition }, replaceWith) { - const processor = selectorParser(selectors => { + const parser = selectorParser(selectors => { let i = 0 selectors.walkClasses(c => { if (classPosition === i++ && c.value === className) { @@ -52,7 +53,7 @@ function generateRulesFromApply({ rule, utilityName: className, classPosition }, // You could argue we should make this replacement at the AST level, but if we believe // the placeholder string is safe from collisions then it is safe to do this is a simple // string replacement, and much, much faster. - return processor.processSync(selector).replace('[__TAILWIND-APPLY-PLACEHOLDER__]', replaceWith) + return parser.processSync(selector).replace('[__TAILWIND-APPLY-PLACEHOLDER__]', replaceWith) }) const cloned = rule.clone() @@ -72,19 +73,16 @@ function generateRulesFromApply({ rule, utilityName: className, classPosition }, return current } -function extractUtilityNames(selector) { - const processor = selectorParser(selectors => { - let classes = [] +const extractUtilityNamesParser = selectorParser(selectors => { + let classes = [] + selectors.walkClasses(c => classes.push(c.value)) + return classes +}) - selectors.walkClasses(c => { - classes.push(c) - }) - - return classes.map(c => c.value) - }) - - return processor.transformSync(selector) -} +const extractUtilityNames = useMemo( + selector => extractUtilityNamesParser.transformSync(selector), + selector => selector +) function buildUtilityMap(css) { let index = 0 diff --git a/src/util/useMemo.js b/src/util/useMemo.js new file mode 100644 index 000000000..a70c397f0 --- /dev/null +++ b/src/util/useMemo.js @@ -0,0 +1,16 @@ +export function useMemo(cb, keyResolver) { + const cache = new Map() + + return (...args) => { + const key = keyResolver(...args) + + if (cache.has(key)) { + return cache.get(key) + } + + const result = cb(...args) + cache.set(key, result) + + return result + } +}