Lazy-load "Beautiful Drag-N-Drop" (#859)

Code-splits the module into "dnd.js", reducing the ui.js bundle size. This module is only needed when viewing lists.

## Room for improvement
`ClaimList` can probably improve further by only using the dnd components in "edit" mode.

## Implementation notes
- The modules are not default exports, so the additional chaining to `React.lazy` was required.
- Experimenting with using an Object to store the import so that a single "prettier-ignore" can be used to make it not wrap.
- The FlowFixMe came from the original code. It is unclear why it is needed to resolve the module, but Haffa mentioned it's something related to .flowconfig.
This commit is contained in:
infinite-persistence 2022-02-14 11:54:23 -08:00 committed by GitHub
parent ecc3599a85
commit b3020b6cfb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 100 additions and 80 deletions

View file

@ -1,8 +1,4 @@
// @flow
// $FlowFixMe
import { Draggable } from 'react-beautiful-dnd';
import { MAIN_CLASS } from 'constants/classnames';
import type { Node } from 'react';
import React, { useEffect } from 'react';
@ -14,6 +10,11 @@ import usePersistedState from 'effects/use-persisted-state';
import debounce from 'util/debounce';
import ClaimPreviewTile from 'component/claimPreviewTile';
const Draggable = React.lazy(() =>
// $FlowFixMe
import('react-beautiful-dnd' /* webpackChunkName: "dnd" */).then((module) => ({ default: module.Draggable }))
);
const DEBOUNCE_SCROLL_HANDLER_MS = 150;
const SORT_NEW = 'new';
const SORT_OLD = 'old';
@ -250,31 +251,33 @@ export default function ClaimList(props: Props) {
{sortedUris.map((uri, index) =>
droppableProvided ? (
<Draggable key={uri} draggableId={uri} index={index}>
{(draggableProvided, draggableSnapshot) => {
// Restrict dragging to vertical axis
// https://github.com/atlassian/react-beautiful-dnd/issues/958#issuecomment-980548919
let transform = draggableProvided.draggableProps.style.transform;
<React.Suspense fallback={null}>
<Draggable key={uri} draggableId={uri} index={index}>
{(draggableProvided, draggableSnapshot) => {
// Restrict dragging to vertical axis
// https://github.com/atlassian/react-beautiful-dnd/issues/958#issuecomment-980548919
let transform = draggableProvided.draggableProps.style.transform;
if (draggableSnapshot.isDragging && transform) {
transform = transform.replace(/\(.+,/, '(0,');
}
if (draggableSnapshot.isDragging && transform) {
transform = transform.replace(/\(.+,/, '(0,');
}
const style = {
...draggableProvided.draggableProps.style,
transform,
};
const style = {
...draggableProvided.draggableProps.style,
transform,
};
return (
<li ref={draggableProvided.innerRef} {...draggableProvided.draggableProps} style={style}>
{/* https://github.com/atlassian/react-beautiful-dnd/issues/1756 */}
<div style={{ display: 'none' }} {...draggableProvided.dragHandleProps} />
return (
<li ref={draggableProvided.innerRef} {...draggableProvided.draggableProps} style={style}>
{/* https://github.com/atlassian/react-beautiful-dnd/issues/1756 */}
<div style={{ display: 'none' }} {...draggableProvided.dragHandleProps} />
{getClaimPreview(uri, index, draggableProvided)}
</li>
);
}}
</Draggable>
{getClaimPreview(uri, index, draggableProvided)}
</li>
);
}}
</Draggable>
</React.Suspense>
) : (
getClaimPreview(uri, index)
)

View file

@ -1,8 +1,4 @@
// @flow
// $FlowFixMe
import { DragDropContext, Droppable } from 'react-beautiful-dnd';
import React from 'react';
import classnames from 'classnames';
import ClaimList from 'component/claimList';
@ -13,6 +9,14 @@ import * as COLLECTIONS_CONSTS from 'constants/collections';
import Icon from 'component/common/icon';
import * as ICONS from 'constants/icons';
// prettier-ignore
const Lazy = {
// $FlowFixMe
DragDropContext: React.lazy(() => import('react-beautiful-dnd' /* webpackChunkName: "dnd" */).then((module) => ({ default: module.DragDropContext }))),
// $FlowFixMe
Droppable: React.lazy(() => import('react-beautiful-dnd' /* webpackChunkName: "dnd" */).then((module) => ({ default: module.Droppable }))),
};
type Props = {
id: string,
url: string,
@ -105,22 +109,24 @@ export default function CollectionContent(props: Props) {
)
}
body={
<DragDropContext onDragEnd={handleOnDragEnd}>
<Droppable droppableId="list__ordering">
{(DroppableProvided) => (
<ClaimList
isCardBody
type="small"
activeUri={url}
uris={collectionUrls}
collectionId={id}
empty={__('List is Empty')}
showEdit={showEdit}
droppableProvided={DroppableProvided}
/>
)}
</Droppable>
</DragDropContext>
<React.Suspense fallback={null}>
<Lazy.DragDropContext onDragEnd={handleOnDragEnd}>
<Lazy.Droppable droppableId="list__ordering">
{(DroppableProvided) => (
<ClaimList
isCardBody
type="small"
activeUri={url}
uris={collectionUrls}
collectionId={id}
empty={__('List is Empty')}
showEdit={showEdit}
droppableProvided={DroppableProvided}
/>
)}
</Lazy.Droppable>
</Lazy.DragDropContext>
</React.Suspense>
}
/>
);

View file

@ -1,8 +1,4 @@
// @flow
// $FlowFixMe
import { DragDropContext, Droppable } from 'react-beautiful-dnd';
import { DOMAIN } from 'config';
import React from 'react';
import classnames from 'classnames';
@ -27,6 +23,14 @@ import SUPPORTED_LANGUAGES from 'constants/supported_languages';
import * as PAGES from 'constants/pages';
import analytics from 'analytics';
// prettier-ignore
const Lazy = {
// $FlowFixMe
DragDropContext: React.lazy(() => import('react-beautiful-dnd' /* webpackChunkName: "dnd" */).then((module) => ({ default: module.DragDropContext }))),
// $FlowFixMe
Droppable: React.lazy(() => import('react-beautiful-dnd' /* webpackChunkName: "dnd" */).then((module) => ({ default: module.Droppable }))),
};
const LANG_NONE = 'none';
const MAX_TAG_SELECT = 5;
@ -374,19 +378,21 @@ function CollectionForm(props: Props) {
</div>
</TabPanel>
<TabPanel>
<DragDropContext onDragEnd={handleOnDragEnd}>
<Droppable droppableId="list__ordering">
{(DroppableProvided) => (
<ClaimList
uris={collectionUrls}
collectionId={collectionId}
empty={__('This list has no items.')}
showEdit
droppableProvided={DroppableProvided}
/>
)}
</Droppable>
</DragDropContext>
<React.Suspense fallback={null}>
<Lazy.DragDropContext onDragEnd={handleOnDragEnd}>
<Lazy.Droppable droppableId="list__ordering">
{(DroppableProvided) => (
<ClaimList
uris={collectionUrls}
collectionId={collectionId}
empty={__('This list has no items.')}
showEdit
droppableProvided={DroppableProvided}
/>
)}
</Lazy.Droppable>
</Lazy.DragDropContext>
</React.Suspense>
</TabPanel>
<TabPanel>
<Card

View file

@ -1,8 +1,4 @@
// @flow
// $FlowFixMe
import { DragDropContext, Droppable } from 'react-beautiful-dnd';
import React from 'react';
import ClaimList from 'component/claimList';
import Page from 'component/page';
@ -20,6 +16,14 @@ import Icon from 'component/common/icon';
import * as ICONS from 'constants/icons';
import Spinner from 'component/spinner';
// prettier-ignore
const Lazy = {
// $FlowFixMe
DragDropContext: React.lazy(() => import('react-beautiful-dnd' /* webpackChunkName: "dnd" */).then((module) => ({ default: module.DragDropContext }))),
// $FlowFixMe
Droppable: React.lazy(() => import('react-beautiful-dnd' /* webpackChunkName: "dnd" */).then((module) => ({ default: module.Droppable }))),
};
export const PAGE_VIEW_QUERY = 'view';
export const EDIT_PAGE = 'edit';
@ -225,20 +229,21 @@ export default function CollectionPage(props: Props) {
{editing}
<div className={classnames('section card-stack')}>
{info}
<DragDropContext onDragEnd={handleOnDragEnd}>
<Droppable droppableId="list__ordering">
{(DroppableProvided) => (
<ClaimList
uris={collectionUrls}
collectionId={collectionId}
showEdit={showEdit}
droppableProvided={DroppableProvided}
unavailableUris={unavailableUris}
/>
)}
</Droppable>
</DragDropContext>
<React.Suspense fallback={null}>
<Lazy.DragDropContext onDragEnd={handleOnDragEnd}>
<Lazy.Droppable droppableId="list__ordering">
{(DroppableProvided) => (
<ClaimList
uris={collectionUrls}
collectionId={collectionId}
showEdit={showEdit}
droppableProvided={DroppableProvided}
unavailableUris={unavailableUris}
/>
)}
</Lazy.Droppable>
</Lazy.DragDropContext>
</React.Suspense>
</div>
</Page>
);