Skip to content

Commit 35a2c5a

Browse files
committed
fix: Only consider output styles that can possibly apply.
At service startup we construct a lookup map that maps from style ids to possible optimized class entries. Then for a given set of styles being applied to the current element, we construct a list of the optimization entries that might evaluate to true because the style expressions mention the input styles in some way.
1 parent 860c823 commit 35a2c5a

File tree

1 file changed

+47
-2
lines changed

1 file changed

+47
-2
lines changed

Diff for: packages/@css-blocks/ember-app/runtime/app/services/css-blocks.ts

+47-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import type { ObjectDictionary } from "@opticss/util";
66

77
/// @ts-ignore
88
import { data as _data } from "./-css-blocks-data";
9-
import type { AggregateRewriteData, ConditionalStyle, ImpliedStyles, StyleExpression, StyleRequirements } from "./AggregateRewriteData";
9+
import type { AggregateRewriteData, ConditionalStyle, GlobalBlockIndex, ImpliedStyles, OptimizationEntry, StyleExpression, StyleRequirements } from "./AggregateRewriteData";
1010

1111
const data: AggregateRewriteData = _data;
1212

@@ -95,8 +95,17 @@ const enum FalsySwitchBehavior {
9595
default = 2,
9696
}
9797

98+
interface StyleIdToOptimizationsMap {
99+
[styleId: number]: Array<number>;
100+
}
101+
98102
// tslint:disable-next-line:no-default-export
99103
export default class CSSBlocksService extends Service {
104+
possibleOptimizations!: StyleIdToOptimizationsMap;
105+
constructor() {
106+
super(...arguments);
107+
this.possibleOptimizations = getOptimizationInverseMap(data.optimizations);
108+
}
100109
classNamesFor(argv: Array<string | number | boolean | null>): string {
101110
let args = argv.slice();
102111
args.reverse(); // pop() is faster than shift()
@@ -222,7 +231,7 @@ export default class CSSBlocksService extends Service {
222231
let classNameIndices = new Set<number>();
223232
// TODO: Only iterate over the subset of optimizations that might match this
224233
// element's styles.
225-
for (let [clsIdx, expr] of data.optimizations) {
234+
for (let [clsIdx, expr] of this.getPossibleOptimizations(stylesApplied)) {
226235
if (evaluateExpression(expr, stylesApplied)) {
227236
classNameIndices.add(clsIdx);
228237
}
@@ -234,6 +243,17 @@ export default class CSSBlocksService extends Service {
234243
let result = classNames.join(" ");
235244
return result;
236245
}
246+
247+
getPossibleOptimizations(stylesApplied: Set<number>): Array<OptimizationEntry> {
248+
let optimizations: Array<number> = [];
249+
for (let style of stylesApplied) {
250+
let possibleOpts = this.possibleOptimizations[style];
251+
if (possibleOpts) {
252+
optimizations.push(...possibleOpts);
253+
}
254+
}
255+
return [...new Set(optimizations)].map(i => data.optimizations[i]);
256+
}
237257
}
238258

239259
function evaluateExpression(expr: StyleExpression, stylesApplied: Set<number>, stylesApplied2?: Set<number>): boolean {
@@ -315,3 +335,28 @@ function applyImpliedStyles(stylesApplied: Set<number>, impliedStyles: ImpliedSt
315335
}
316336
return aliases;
317337
}
338+
339+
function getOptimizationInverseMap(optimizations: Array<OptimizationEntry>): StyleIdToOptimizationsMap {
340+
let inverseMap: StyleIdToOptimizationsMap = {};
341+
for (let i = 0; i < optimizations.length; i++) {
342+
for (let styleId of new Set(extractStyleIds(optimizations[i][1]))) {
343+
if (inverseMap[styleId] === undefined) {
344+
inverseMap[styleId] = [];
345+
}
346+
inverseMap[styleId].push(i);
347+
}
348+
}
349+
return inverseMap;
350+
}
351+
352+
function extractStyleIds(expr: StyleExpression): Array<GlobalBlockIndex> {
353+
if (typeof expr === "number") {
354+
return [expr];
355+
} else {
356+
let result = new Array<GlobalBlockIndex>();
357+
for (let i = 1; i < expr.length; i++) {
358+
result.push(...extractStyleIds(expr[i]));
359+
}
360+
return result;
361+
}
362+
}

0 commit comments

Comments
 (0)