rnunez
(Rafael Nunez)
August 22, 2024, 4:30pm
1
Is there a particular reason why Volto does not use @loadable /component or React.lazy to load component?
All visitors would benefit if these are lazy load: e.g. ControlPanel, Widgets, Contents, Form, Toolbar, Sidebar, Rules, Sharing, Editing, Diff, History, BlockChooser.
Lazy Loading these component will reduce the size of the client.js and improve the performance for every user.
(edited question and title)
h
davisagli
(David Glick)
August 23, 2024, 4:30am
2
Volto uses @loadable /component instead of React.lazy for lazy-loading. There is some documentation here: Lazy loading – Frontend – Development — Plone Documentation v6.0
My understanding is that React.lazy does not work with server-side rendering.
I'm sure there are more components that would make sense to switch to lazy loading, if someone is willing to put in the effort.
rnunez
(Rafael Nunez)
August 23, 2024, 12:34pm
3
Thanks, I refactor all the component I implemented react.lazy to use @loadable /component. while on development mode react.lazy worked fine but once I build it it gave me the error.
My point is that ControlPanel, Widgets, Contents, Form, Toolbar, Sidebar, Rules, Sharing, Editing, Diff, History, BlockChooser are not using @loadable /component and they are loaded by everybody that visit the site when 99% will not use this code
pnicolli
(Piero Nicolli)
August 25, 2024, 7:09am
4
In Volto 18 a good chunk (hehe) of those components are indeed loaded lazily, and we plan to work more on that soon at Salamina Sprint
See all the discussion and the work that has been done in this PLIP and the PR linked inside:
opened 11:22AM - 21 Nov 23 UTC
03 type: feature (plip)
04 type: enhancement
## PLIP (Plone Improvement Proposal)
## Responsible Persons
Piero Nicolli … (@pnicolli)
### Proposer
Piero Nicolli (@pnicolli)
### Seconder
Victor Fernandez de Alba (@sneridagh)
Tiberiu Ichim (@tiberiuichim)
## Abstract
This PLIP aims at optimizing the main javascript bundle that is downloaded by the client for every page load. It got quite big (~580kb gzipped) and most of it is really not needed, most of it is actually only needed by logged in users (e.g. controlpanels).
## Motivation
Web vitals, as measured by Lighthouse for example, are becoming more and more important as a selling point. Some clients reportedly required specific scores. We need to provide a good starting point with Volto core and better examples for client projects.
## Assumptions
The first assumption made here is that this will result in a breaking change for Volto, therefore only targeting version 18. We will definitely try to find a way to avoid a breaking change, but we should assume that it is for now, for release planning purposes.
## Proposal & Implementation
There is a PR with a proposal of how to load parts of the code lazily #5295
A brief explanation of a the implementation details:
We should try to avoid "just lazy loading", we should group javascript chunks into appropriate ones. For example, all widgets will be lazy-loaded but it would be better if only one javascript chunk is downloaded with all the widgets.
Example code:
```javascript
import loadable from '@loadable/component';
export const Field = loadable(
() =>
import(
/* webpackChunkName: "Form" */ '@plone/volto/components/manage/Form/Field'
),
);
export const InlineForm = loadable(
() =>
import(
/* webpackChunkName: "Form" */ '@plone/volto/components/manage/Form/InlineForm'
),
);
export const ModalForm = loadable(
() =>
import(
/* webpackChunkName: "Form" */ '@plone/volto/components/manage/Form/ModalForm'
),
);
export const UndoToolbar = loadable(
() =>
import(
/* webpackChunkName: "Form" */ '@plone/volto/components/manage/Form/UndoToolbar'
),
);
```
By specifying the magic comment `webpackChunkName`, webpack knows that we are asking to put those things in the same javascript chunk and it actually does IF this is the only way that these components are imported elsewhere.
In other words, every time a component is lazy-loaded, a check should be done to see if it is actually split and if the split chunk is the only way it is used.
The command `yarn analyze` helps with that: after changing the import and adding lazy loading, the web page of the report allows to search. Searching "Form" for example highlights every occurrence of the word Form in the javascript chunks and we are able to see if a single copy of the Form component is there and if it is in its own new chunk or if is left in the main chunk for some mistake that we made or some fix that we need to do.
## Deliverables
- lazy loading things is a lot of work because of all the bundle analysis checks that need to be done, so multiple incremental PRs will be proposed towards this goal in order to have short term results to show and also a longer term major improvement
- due to the specifics of how web vitals work, we cannot have a specific goal for those, in numbers, and it would not be super important to have one since the final numbers in client projects depend on the theme that is built on top of volto
- documentation on how to properly lazy load components in order to guide integrators in creating their themes with better web vitals results
## Risks
If a solution is not found for keeping the main `src/components/index.js` index, a big breaking change would happen. If it happens, we could discuss an addition to the deliverables, which is a codemod tool to update the affected imports in client projects.
## Participants
@plone/volto-team
@plone/documentation-team
1 Like
rnunez
(Rafael Nunez)
August 25, 2024, 4:48pm
5
Thanks, this is exactly what I was looking for, I was going to add a PLIP on this if there wasn't one, can I participate remotely?
pnicolli
(Piero Nicolli)
September 3, 2024, 3:57pm
6
Of course you can! You can find the info in the page linked above or at https://salaminasprint.redturtle.it/