Skip to content
This repository has been archived by the owner on May 3, 2024. It is now read-only.

feat(styleLoader): aggregate stylesheets and dedupe if already loaded #1099

Merged
merged 6 commits into from
Sep 5, 2023

Conversation

eddhurst
Copy link
Member

Description

This PR:

  • fixes a cascade ordering issue between server and client bundles, leading to style inconsistencies when hydrated.
  • enables deduplication between modules for identical styles, i.e. if a component library imports styles via css modules.
  • provides the ability for SSR generated styles to directly match the expected output of CSR styles, preventing a flash of restyling as the browser processes the Recalculate Styles task.

Motivation and Context

When using a component library (or any dependency) that imports styles via CSS Modules, the bundler output generates a server bundle that is inconsistent with the client side bundle, as well as resulting in it being difficult to provide style overrides without resorting to CSS hacks (like !important).

In order to resolve this and match the client side bundle output it's necessary to split the styles into multiple style tags, and then order them to allow for cascade overrides. However, the OneApp styles loader currently wraps all SSR styles in a single style tag.

This change retains the existing functionality in order to provide backwards compatibility for modules generated with older bundlers, whilst allowing for bundlers to provide a new key: aggregatedStyles.

How Has This Been Tested?

Generated a root module and three child modules that share a component library dependency, with each child module rendering two instances of the same component. The first one unchanged, the second with style overrides applied.

Multiple modules helped to prove that deduplication happened as intended, with only a single instance of the component library styles being rendered, with overrides applying with the expected cascade priority.

This was additionally run with an older version of OneApp, and an older bundle to prove backwards compatibility is unaffected.

Screenshot 2023-08-29 at 16 10 37 Screenshot 2023-08-29 at 22 30 17

Types of Changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation (adding or updating documentation)
  • Dependency update
  • Security update

Checklist:

  • My change requires a change to the documentation and I have updated the documentation accordingly.
  • These changes should be applied to a maintenance branch.
  • This change requires cross browser checks.
  • Performance tests should be ran against the server prior to merging.
  • This change impacts caching for client browsers.
  • This change impacts HTTP headers.
  • This change adds additional environment variable requirements for One App users.
  • I have added the Apache 2.0 license header to any new files created.

What is the Impact to Developers Using One App?

This allows developers to provide overrides to styles imported via CSS modules within their applications without resorting to CSS hacks and forcing specificity.

@github-actions
Copy link
Contributor

github-actions bot commented Aug 29, 2023

Size Change: 0 B

Total Size: 689 kB

ℹ️ View Unchanged
Filename Size
./build/app/app.js 164 kB
./build/app/app~vendors.js 389 kB
./build/app/runtime.js 7.07 kB
./build/app/service-worker-client.js 7.26 kB
./build/app/vendors.js 122 kB

compressed-size-action

Copy link
Contributor

@JAdshead JAdshead left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool feature. apart from the small refactoring looks good!!

@JAdshead JAdshead requested a review from a team August 30, 2023 17:52
@eddhurst
Copy link
Member Author

Cool feature. apart from the small refactoring looks good!!

Thanks! and thanks for the feedback, addressed all comments

@@ -1,7 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`renderModuleStyles should handle a mix of modules with and without SSR styles 1`] = `"<style class="ssr-css">.test-module-b_class { color: red; }</style><style class="ssr-css">.test-module-d_class { color: red; }</style>"`;
exports[`renderModuleStyles should deduplicate aggregatedStyles that have the same digest hash 1`] = `"<style id="shared_hash_deps" data-ssr="true">.test-module-a_deps { color: blue; }</style><style id="shared_hash_local" data-ssr="true">.test-module-a_local { color: rebeccapurple; }</style><style id="unique-hash_deps" data-ssr="true">.test-module-c_deps { color: blue; }</style><style id="unique-hash_local" data-ssr="true">.test-module-c_local { color: rebeccapurple; }</style>"`;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the difference between data-ssr="true' and class="ssr-css" ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strictly speaking none - although a style tag ought not have a class name because we're not applying styles onto the element. The idea here was more of a debug step to allow us to more easily track which styles are being hydrated and which are not. We could dispense with this entirely, but it felt like that might still be a useful step for more easily debugging / visualising the changes.

@JAdshead JAdshead requested a review from a team August 31, 2023 20:22
@JAdshead JAdshead enabled auto-merge (squash) September 5, 2023 15:31
@JAdshead JAdshead merged commit a74a5ba into main Sep 5, 2023
19 checks passed
@JAdshead JAdshead deleted the feature/aggregate-ssr-styles-loader branch September 5, 2023 15:46
zacowan added a commit that referenced this pull request Feb 5, 2024
zacowan added a commit that referenced this pull request Feb 7, 2024
JAdshead added a commit that referenced this pull request Feb 19, 2024
#1291)

Lift and shift of #1099 for v5.

Co-authored-by: Jonny Adshead <JAdshead@users.noreply.github.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants