Integrate CSS lazy loading
Edit on GitHubTo implement CSS lazy loading for frontend, do the following:
- Update the
ShopUimodule to version 1.44.0, and update thespryker-shop/shopdependencies for theCatalogPage,HomePage, andProductDetailPagemodules:
COMPOSER_MEMORY_LIMIT=-1 composer update spryker-shop/shop-application spryker-shop/shop-ui spryker-shop/catalog-page spryker-shop/home-page spryker-shop/product-detail-page --with-dependencies
- Add
"@jsdevtools/file-path-filter": "~3.0.2", into thepackage.jsonfile to thedevDependenciessection and run the following:
npm install
-
Make the following adjustments to the
frontend/settings.jsfile:- Define
criticalPatterns:
... // array of patterns for the critical components const criticalPatterns = [ '**/ShopUi/**', '**/CatalogPage/**', '**/HomePage/**', '**/ProductDetailPage/**' ]; ...- Add
criticalPatternsto the returned settings object:
... // return settings return { name, namespaceConfig, theme, paths, urls, imageOptimizationOptions, criticalPatterns, ...- Extend the definition of the setting for the frontend builder with the following style entry point patterns for components
stylesEntryPoints:
... // define settings for suite-frontend-builder finder find: { // entry point patterns (components) componentEntryPoints: { ... }, // style entry point patterns (components) stylesEntryPoints: { core: { // absolute dirs in which look for dirs: [ join(globalSettings.context, paths.core), ], // files/dirs patterns patterns: [`**/Theme/${namespaceConfig.defaultTheme}/**/style.scss`], }, nonCore: { // absolute dirs in which look for dirs: [ join(globalSettings.context, paths.eco), join(globalSettings.context, paths.project), ], // files/dirs patterns patterns: [ `**/Theme/${namespaceConfig.defaultTheme}/components/**/*.scss`, `**/Theme/${namespaceConfig.defaultTheme}/templates/**/*.scss`, `**/Theme/${namespaceConfig.defaultTheme}/views/**/*.scss`, ], }, }, ... - Define
-
Update the
frontend/libs/finder.jsfile with the following code:- Add the
mergeEntryPointsfunction:
... // merge entry points const mergeEntryPoints = async files => Object.values(files.reduce((map, file) => { const dir = path.dirname(file); const name = path.basename(dir); const type = path.basename(path.dirname(dir)); map[`${type}/${name}`] = file; return map; }, {})); ...- Update the
findEntryPointsfunction using themergeEntryPointsas described in the previous step:
... // find entry points const findEntryPoints = async settings => { const files = await find(settings.dirs, settings.patterns, settings.fallbackPatterns, settings.globSettings); return mergeEntryPoints(files); }; ...- Add the
findStyleEntryPointsfunction:
... // find style entry points const findStyleEntryPoints = async settings => { const coreFiles = await find(settings.core.dirs, settings.core.patterns, [], settings.globSettings); const nonCoreFiles = await find(settings.nonCore.dirs, settings.nonCore.patterns, [], settings.globSettings); const files = [...coreFiles, ...nonCoreFiles]; return mergeEntryPoints(files); }; ...- Pass the
findStyleEntryPointsfunction to the exported module:
... module.exports = { findComponentEntryPoints, findStyleEntryPoints, findComponentStyles, findAppEntryPoint, }; - Add the
-
Adjust the
frontend/configs/development.jsfile:- Add the
filePathFilterto the imported stuff at the top of the file:
const filePathFilter = require("@jsdevtools/file-path-filter");- Add
findStyleEntryPointsto the import from theFindermodule:
... const { findComponentEntryPoints, findStyleEntryPoints, findComponentStyles, findAppEntryPoint } = require('../libs/finder'); ...- Add the new local variable
styleEntryPointsPromiseto thegetConfigurationfunction:
... const styleEntryPointsPromise = findStyleEntryPoints(appSettings.find.stylesEntryPoints); ...- Extend the destructuring assignment with the following changes:
From:
const [componentEntryPoints, styles] = await Promise.all([componentEntryPointsPromise, stylesPromise]);To:
const [componentEntryPoints, styleEntryPoints, styles] = await Promise.all([componentEntryPointsPromise, styleEntryPointsPromise, stylesPromise]);- Add new local variables
criticalEntryPointsandnonCriticalEntryPointsto thegetConfigurationfunction:
... const criticalEntryPoints = styleEntryPoints.filter(filePathFilter({ include: appSettings.criticalPatterns, })); const nonCriticalEntryPoints = styleEntryPoints.filter(filePathFilter({ exclude: appSettings.criticalPatterns, })); ...- Extend the
entrysection of the returned Webpack config object into thegetConfigurationfunction with the newcritical,non-critical, andutilpoints:
... entry: { 'vendor': vendorTs, 'app': [ appTs, ...componentEntryPoints, ], 'critical': [ basicScss, ...criticalEntryPoints, ], 'non-critical': [ ...nonCriticalEntryPoints, utilScss, ], 'util': utilScss, }, ... - Add the
-
Update
src/Pyz/Yves/EventDispatcher/EventDispatcherDependencyProvider.phpon the project level:- Add
LastVisitCookieEventDispatcherPluginto using section:
... use SprykerShop\Yves\ShopApplication\Plugin\EventDispatcher\LastVisitCookieEventDispatcherPlugin; ...- Add this plugin to the returned collection of the
getEventDispatcherPluginsfunction:
protected function getEventDispatcherPlugins(): array { return [ ... new LastVisitCookieEventDispatcherPlugin(), ... ]; } - Add
-
Update the
page-blank.twiglayout on the project level insrc/Pyz/Yves/ShopUi/Theme/default/templates/page-blank/page-blank.twigby adding the newisCssLazyLoadSupportedtwig variable:
{% extends template('page-blank', '@SprykerShop:ShopUi') %}
{% block template %}
{% set isCssLazyLoadSupported = true %}
{{ parent() }}
{% endblock %}
Info
Make sure your styles from node_modules are included in .scss files (not in index.ts). For example:
molecules/slick-carousel/slick-carousel.scss:
@import '~slick-carousel/slick/slick.scss';
@mixin shop-ui-slick-carousel($name: '.slick-carousel') {
...
- Rebuild the frontend with the new settings:
npm run yves
Thank you!
For submitting the form