Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[docs] Add Performance section for Modal #23168

Merged
merged 6 commits into from
Oct 20, 2020
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/src/pages/components/dialogs/dialogs.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ Try the demo below to see what we mean:

{{"demo": "pages/components/dialogs/ScrollDialog.js"}}

## Performance

Follow the [Modal performance section](/components/modal/#performance).

## Limitations

Follow the [Modal limitations section](/components/modal/#limitations).
Expand Down
15 changes: 15 additions & 0 deletions docs/src/pages/components/drawers/drawers.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,21 @@ const iOS = process.browser && /iPad|iPhone|iPod/.test(navigator.userAgent);
<SwipeableDrawer disableBackdropTransition={!iOS} disableDiscovery={iOS} />;
```

### Keep mounted

To ensure a temporary drawer is not unmounted, specify the `ModalProps` prop like
oliviertassinari marked this conversation as resolved.
Show resolved Hide resolved

```jsx
<Drawer
variant="temporary"
ModalProps={{
keepMounted: true,
}}
/>
```

More details in the [Modal performance section](/components/modal/#performance).

## Responsive drawer

The `Hidden` responsive helper component allows showing different types of drawer depending on the screen width.
Expand Down
66 changes: 66 additions & 0 deletions docs/src/pages/components/modal/KeepMountedModal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import * as React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Modal from '@material-ui/core/Modal';

function rand() {
return Math.round(Math.random() * 20) - 10;
}

function getModalStyle() {
const top = 50 + rand();
const left = 50 + rand();

return {
top: `${top}%`,
left: `${left}%`,
transform: `translate(-${top}%, -${left}%)`,
};
}

const useStyles = makeStyles((theme) => ({
paper: {
position: 'absolute',
width: 400,
backgroundColor: theme.palette.background.paper,
border: '2px solid #000',
boxShadow: theme.shadows[5],
padding: theme.spacing(2, 4, 3),
},
}));

export default function KeepMountedModal() {
const classes = useStyles();
// getModalStyle is not a pure function, we roll the style only on the first render
const [modalStyle] = React.useState(getModalStyle);
const [open, setOpen] = React.useState(false);

const handleOpen = () => {
setOpen(true);
};

const handleClose = () => {
setOpen(false);
};

return (
<div>
<button type="button" onClick={handleOpen}>
Open Modal
</button>
<Modal
keepMounted
open={open}
onClose={handleClose}
aria-labelledby="keep-mounted-modal-title"
aria-describedby="keep-mounted-modal-description"
>
<div style={modalStyle} className={classes.paper}>
<h2 id="keep-mounted-modal-title">Text in a modal</h2>
<p id="keep-mounted-modal-description">
Duis mollis, est non commodo luctus, nisi erat porttitor ligula.
</p>
</div>
</Modal>
</div>
);
}
68 changes: 68 additions & 0 deletions docs/src/pages/components/modal/KeepMountedModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import * as React from 'react';
import { makeStyles, Theme, createStyles } from '@material-ui/core/styles';
import Modal from '@material-ui/core/Modal';

function rand() {
return Math.round(Math.random() * 20) - 10;
}

function getModalStyle() {
const top = 50 + rand();
const left = 50 + rand();

return {
top: `${top}%`,
left: `${left}%`,
transform: `translate(-${top}%, -${left}%)`,
};
}

const useStyles = makeStyles((theme: Theme) =>
createStyles({
paper: {
position: 'absolute',
width: 400,
backgroundColor: theme.palette.background.paper,
border: '2px solid #000',
boxShadow: theme.shadows[5],
padding: theme.spacing(2, 4, 3),
},
}),
);

export default function KeepMountedModal() {
const classes = useStyles();
// getModalStyle is not a pure function, we roll the style only on the first render
const [modalStyle] = React.useState(getModalStyle);
const [open, setOpen] = React.useState(false);

const handleOpen = () => {
setOpen(true);
};

const handleClose = () => {
setOpen(false);
};

return (
<div>
<button type="button" onClick={handleOpen}>
Open Modal
</button>
<Modal
keepMounted
open={open}
onClose={handleClose}
aria-labelledby="keep-mounted-modal-title"
aria-describedby="keep-mounted-modal-description"
>
<div style={modalStyle} className={classes.paper}>
<h2 id="keep-mounted-modal-title">Text in a modal</h2>
<p id="keep-mounted-modal-description">
Duis mollis, est non commodo luctus, nisi erat porttitor ligula.
</p>
</div>
</Modal>
</div>
);
}
15 changes: 15 additions & 0 deletions docs/src/pages/components/modal/modal.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,21 @@ Alternatively, you can use [react-spring](https://github.com/react-spring/react-

{{"demo": "pages/components/modal/SpringModal.js"}}

## Performance

The content of modal is unmounted when closed.
If you need to make the content available to search engines or render expensive component trees inside your modal while optimizing for interaction responsiveness
it might be a good idea to change this default behavior by enabling the `keepMounted` prop:

```jsx
<Modal keepMounted />
```

{{"demo": "pages/components/modal/KeepMountedModal.js", "defaultCodeOpen": false}}

As with any performance optimization this is not a silver bullet. Be sure to identify
bottlenecks first and then try out these optimization strategies.

## Server-side modal

React [doesn't support](https://github.com/facebook/react/issues/13097) the [`createPortal()`](https://reactjs.org/docs/portals.html) API on the server.
Expand Down
2 changes: 1 addition & 1 deletion test/regressions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const blacklist = [
'docs-components-modal/SimpleModal.png', // Needs interaction
'docs-components-modal/SpringModal.png', // Needs interaction
'docs-components-modal/TransitionsModal.png', // Needs interaction
'docs-components-modal/TransitionsModal.png', // Needs interaction
'docs-components-modal/KeepMountedModal.png', // Needs interaction
'docs-components-no-ssr/FrameDeferring.png', // Needs interaction
'docs-components-popover/AnchorPlayground.png', // Redux isolation
'docs-components-popover/MouseOverPopover.png', // Needs interaction
Expand Down