Skip to content

Commit

Permalink
feat: style deduplication (#5264)
Browse files Browse the repository at this point in the history
* chore: reintroduce locker logic

* Update packages/@lwc/integration-karma/test/component/LightningElement/index.spec.js

Co-authored-by: Will Harney <[email protected]>

* feat: added style dedup in ssr (not working yet)

* fix: reference to runtime context on emit fn

* chore: rename CompilationContext to RuntimeContext (it was wrong before)

* chore: update SSR fixtures with dedupe keys

* feat: accept prefix for style dedupe identifiers

* feat: create @lwc/ssr-client-utils package with pre-hydration dedupe mechanism

* chore: add big TODO comment

* feat(lwc-style): add register util

TODO: make it actually get bundled

* feat(lwc-style): replace dummies with dumber dummies

* test: the SSRv1 fixture tests against SSRv2 fixtures

* chore: fix tests and test config

* chore: get all SSRv1 tests to pass with new lwc-style stuff

* chore: comments

* chore: more comments

* refactor: make it possible to disable style dedupe in SSRv2

* chore: provide `@lwc/ssr-client-utils/register` import

* chore: add comment about bare import

Co-authored-by: Will Harney <[email protected]>

* chore: use FIXME instead of "Followup needed"

Co-authored-by: Will Harney <[email protected]>

* refactor: destructure for better readability

* chore: add TODO

* refactor: make createMistmatchError generic

Co-authored-by: Will Harney <[email protected]>

* chore: add comment explaining regexp

Co-authored-by: Will Harney <[email protected]>

* chore: fix imprecision in code comment

Co-authored-by: Will Harney <[email protected]>

* chore: add comment explaining why we need repeated exec on regexp

* chore: indentation is 0 when falsey instead of null

* chore: address nit

Co-authored-by: Will Harney <[email protected]>

* chore: remove console.log

Co-authored-by: Will Harney <[email protected]>

* chore: add comment

* chore: bump CI

* chore: add skip file for flakey test

---------

Co-authored-by: John Hefferman <[email protected]>
Co-authored-by: jhefferman-sfdc <[email protected]>
Co-authored-by: Will Harney <[email protected]>
Co-authored-by: Will Harney <[email protected]>
  • Loading branch information
5 people authored Mar 5, 2025
1 parent 73066cc commit 5989bf0
Show file tree
Hide file tree
Showing 59 changed files with 851 additions and 266 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
"*.{css,js,json,md,mjs,ts,yaml,yml}": "prettier --write",
"{packages/**/package.json,scripts/tasks/check-and-rewrite-package-json.js}": "node ./scripts/tasks/check-and-rewrite-package-json.js",
"{LICENSE-CORE.md,**/LICENSE.md,yarn.lock,scripts/tasks/generate-license-files.js,scripts/shared/bundled-dependencies.js}": "node ./scripts/tasks/generate-license-files.js",
"*.{only,skip}": "eslint --cache --no-eslintrc --plugin '@lwc/eslint-plugin-lwc-internal' --rule '@lwc/lwc-internal/forbidden-filename: error'"
"*.{only,skip}": "eslint --cache --plugin '@lwc/eslint-plugin-lwc-internal' --rule '@lwc/lwc-internal/forbidden-filename: error'"
},
"workspaces": [
"packages/@lwc/*",
Expand Down
7 changes: 6 additions & 1 deletion packages/@lwc/engine-core/src/framework/hydration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,12 @@ function hydrateElement(elm: Node, vnode: VElement, renderer: RendererAPI): Node

patchElementPropsAndAttrsAndRefs(vnode, renderer);

if (!isDomManual) {
// When <lwc-style> tags are initially encountered at the time of HTML parse, the <lwc-style> tag is
// replaced with an empty <style> tag. Additionally, the styles are attached to the shadow root as a
// constructed stylesheet at the same time. So, the shadow will be styled correctly and the only
// difference between what's in the DOM and what's in the VDOM is the string content inside the
// <style> tag. We can simply ignore that during hyration.
if (!isDomManual && vnode.elm.tagName !== 'STYLE') {
const { getFirstChild } = renderer;
hydrateChildren(getFirstChild(elm), vnode.children, elm, owner, false);
}
Expand Down
1 change: 1 addition & 0 deletions packages/@lwc/engine-server/src/__tests__/fixtures.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ function testFixtures(options?: RollupLwcOptions) {
testFixtureDir<FixtureConfig>(
{
root: path.resolve(__dirname, 'fixtures'),
ssrVersion: 1,
pattern: '**/config.json',
},
async ({ dirname, config }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
<template shadowrootmode="open">
<x-child class="lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
<style class="lwc-5h3d35cke7v" id="lwc-style--0" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="lwc-5h3d35cke7v">
</div>
<x-grandchild class="lwc-5h3d35cke7v">
Expand All @@ -15,9 +17,8 @@
</x-child>
<x-child class="lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="lwc-5h3d35cke7v">
</div>
<x-grandchild class="lwc-5h3d35cke7v">
Expand All @@ -28,9 +29,8 @@
</x-child>
<x-child class="lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="lwc-5h3d35cke7v">
</div>
<x-grandchild class="lwc-5h3d35cke7v">
Expand All @@ -41,9 +41,8 @@
</x-child>
<x-child class="lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="lwc-5h3d35cke7v">
</div>
<x-grandchild class="lwc-5h3d35cke7v">
Expand All @@ -54,9 +53,8 @@
</x-child>
<x-child class="lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="lwc-5h3d35cke7v">
</div>
<x-grandchild class="lwc-5h3d35cke7v">
Expand All @@ -67,9 +65,8 @@
</x-child>
<x-child class="lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="lwc-5h3d35cke7v">
</div>
<x-grandchild class="lwc-5h3d35cke7v">
Expand All @@ -80,9 +77,8 @@
</x-child>
<x-child class="lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="lwc-5h3d35cke7v">
</div>
<x-grandchild class="lwc-5h3d35cke7v">
Expand All @@ -93,9 +89,8 @@
</x-child>
<x-child class="lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="lwc-5h3d35cke7v">
</div>
<x-grandchild class="lwc-5h3d35cke7v">
Expand All @@ -106,9 +101,8 @@
</x-child>
<x-child class="lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="lwc-5h3d35cke7v">
</div>
<x-grandchild class="lwc-5h3d35cke7v">
Expand All @@ -119,9 +113,8 @@
</x-child>
<x-child class="lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="lwc-5h3d35cke7v">
</div>
<x-grandchild class="lwc-5h3d35cke7v">
Expand All @@ -132,9 +125,8 @@
</x-child>
<x-child class="lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="bar foo lwc-5h3d35cke7v">
</div>
<x-grandchild class="bar foo lwc-5h3d35cke7v">
Expand All @@ -145,9 +137,8 @@
</x-child>
<x-child class="lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="baz foo lwc-5h3d35cke7v">
</div>
<x-grandchild class="baz foo lwc-5h3d35cke7v">
Expand All @@ -158,9 +149,8 @@
</x-child>
<x-child class="lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="bar foo lwc-5h3d35cke7v">
</div>
<x-grandchild class="bar foo lwc-5h3d35cke7v">
Expand All @@ -171,9 +161,8 @@
</x-child>
<x-child class="lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="bar foo lwc-5h3d35cke7v">
</div>
<x-grandchild class="bar foo lwc-5h3d35cke7v">
Expand All @@ -184,9 +173,8 @@
</x-child>
<x-child class="lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="BaR FOO lwc-5h3d35cke7v">
</div>
<x-grandchild class="BaR FOO lwc-5h3d35cke7v">
Expand All @@ -197,9 +185,8 @@
</x-child>
<x-child class="lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="foo lwc-5h3d35cke7v">
</div>
<x-grandchild class="foo lwc-5h3d35cke7v">
Expand All @@ -210,9 +197,8 @@
</x-child>
<x-child class="lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="foo lwc-5h3d35cke7v">
</div>
<x-grandchild class="foo lwc-5h3d35cke7v">
Expand All @@ -223,9 +209,8 @@
</x-child>
<x-child class="lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="&quot;'<&amp; lwc-5h3d35cke7v">
</div>
<x-grandchild class="&quot;'<&amp; lwc-5h3d35cke7v">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,90 +2,83 @@
<template shadowrootmode="open">
<x-child class="lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
<style class="lwc-5h3d35cke7v" id="lwc-style--0" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="lwc-5h3d35cke7v">
</div>
</template>
</x-child>
<x-child class="lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="lwc-5h3d35cke7v">
</div>
</template>
</x-child>
<x-child class="lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="lwc-5h3d35cke7v">
</div>
</template>
</x-child>
<x-child class="foo lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="lwc-5h3d35cke7v">
</div>
</template>
</x-child>
<x-child class="foo lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="lwc-5h3d35cke7v">
</div>
</template>
</x-child>
<x-child class="bar foo lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="lwc-5h3d35cke7v">
</div>
</template>
</x-child>
<x-child class="bar foo lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="lwc-5h3d35cke7v">
</div>
</template>
</x-child>
<x-child class="BAR BaZ FoA lwc-5h3d35cke7v-host" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="lwc-5h3d35cke7v">
</div>
</template>
</x-child>
<x-child class="lwc-5h3d35cke7v-host tabs" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="lwc-5h3d35cke7v">
</div>
</template>
</x-child>
<x-child class="lwc-5h3d35cke7v-host newlines" data-lwc-host-scope-token="lwc-5h3d35cke7v-host">
<template shadowrootmode="open">
<style class="lwc-5h3d35cke7v" type="text/css">
:host {background: blue;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<div class="lwc-5h3d35cke7v">
</div>
</template>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
<fixture-test class="lwc-ts1rr7v761-host" data-lwc-host-scope-token="lwc-ts1rr7v761-host">
<template shadowrootmode="open">
<style class="lwc-ts1rr7v761" type="text/css">
<style class="lwc-ts1rr7v761" id="lwc-style--0" type="text/css">
:host {background: green;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<x-child class="lwc-ts1rr7v761">
<template shadowrootmode="open">
<div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
<fixture-test class="lwc-ts1rr7v761-host" data-lwc-host-scope-token="lwc-ts1rr7v761-host">
<template shadowrootmode="open">
<style class="lwc-ts1rr7v761" type="text/css">
<style class="lwc-ts1rr7v761" id="lwc-style--0" type="text/css">
:host {background: green;}
</style>
<lwc-style style-id="lwc-style--0">
</lwc-style>
<x-child class="lwc-ts1rr7v761">
<template shadowrootmode="open">
<div>
Expand Down
Loading

0 comments on commit 5989bf0

Please sign in to comment.