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-infra] POC Bundle size docs #40592

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all 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
1 change: 0 additions & 1 deletion docs/.link-check-errors.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
Broken links found by `pnpm docs:link-check` that exist:

2 changes: 2 additions & 0 deletions docs/data/base/components/autocomplete/autocomplete.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/combobox/

{{"component": "modules/components/ComponentPageTabs.js"}}

- 📦 [4.5 kB gzipped](https://bundlephobia.com/package/@mui/base).

## Introduction

An autocomplete component is an enhanced text input that shows a list of suggested options as users type, and lets them select an option from the list.
Expand Down
2 changes: 2 additions & 0 deletions docs/data/base/components/button/button.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/button/

{{"component": "modules/components/ComponentPageTabs.js"}}

- 📦 [3.3 kB gzipped](https://bundlephobia.com/package/@mui/base).

## Introduction

The Button component replaces the native HTML `<button>` element, and offers expanded options for styling and accessibility.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ githubLabel: 'component: ClickAwayListener'

{{"component": "modules/components/ComponentPageTabs.js"}}

- 📦 [0.9 kB gzipped](https://bundlephobia.com/package/@mui/base).

## Introduction

Click-Away Listener is a utility component that listens for click events outside of its child.
Expand Down
2 changes: 2 additions & 0 deletions docs/data/base/components/focus-trap/focus-trap.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ githubLabel: 'component: FocusTrap'

{{"component": "modules/components/ComponentPageTabs.js"}}

- 📦 [1.6 kB gzipped](https://bundlephobia.com/package/@mui/base).

## Introduction

Focus Trap is a utility component that's useful when implementing an overlay such as a [modal dialog](/base-ui/react-modal/), which should block all interactions outside of it while open.
Expand Down
2 changes: 2 additions & 0 deletions docs/data/base/components/input/input.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ githubLabel: 'component: input'

{{"component": "modules/components/ComponentPageTabs.js"}}

- 📦 [3.3 kB gzipped](https://bundlephobia.com/package/@mui/base).

## Introduction

An input is a UI element that accepts text data from the user.
Expand Down
2 changes: 2 additions & 0 deletions docs/data/base/components/modal/modal.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/

{{"component": "modules/components/ComponentPageTabs.js"}}

- 📦 [5.1 kB gzipped](https://bundlephobia.com/package/@mui/base).

## Introduction

Modal is a utility component that renders its children in front of a backdrop.
Expand Down
2 changes: 2 additions & 0 deletions docs/data/base/components/number-input/number-input.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ githubLabel: 'component: number input'

{{"component": "modules/components/ComponentPageTabs.js"}}

- 📦 [4.3 kB gzipped](https://bundlephobia.com/package/@mui/base).

## Introduction

A number input is a UI element that accepts numeric values from the user.
Expand Down
2 changes: 2 additions & 0 deletions docs/data/base/components/select/select.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-sel

{{"component": "modules/components/ComponentPageTabs.js"}}

- 📦 [16.8 kB gzipped](https://bundlephobia.com/package/@mui/base).

## Introduction

A select is a UI element that gives users a list of options to choose from.
Expand Down
2 changes: 2 additions & 0 deletions docs/data/base/components/slider/slider.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/slider-multithumb/

{{"component": "modules/components/ComponentPageTabs.js"}}

- 📦 [6.8 kB gzipped](https://bundlephobia.com/package/@mui/base).

## Introduction

The Slider component lets users make selections from a range of values along a horizontal or vertical bar.
Expand Down
2 changes: 2 additions & 0 deletions docs/data/material/components/autocomplete/autocomplete.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ The `useAutocomplete` hook is also reexported from @mui/material for convenience
import useAutocomplete from '@mui/material/useAutocomplete';
```

- 📦 [4.6 kB gzipped](https://bundlephobia.com/package/@mui/material).

{{"demo": "UseAutocomplete.js", "defaultCodeOpen": false}}

### Customized hook
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Some of the key features:

- ⚛️ It has an idiomatic React API.
- 🚀 It's performant, it observes the document to detect when its media queries change, instead of polling the values periodically.
- 📦 [1.1 kB gzipped](https://bundlephobia.com/package/@mui/material).
- 🤖 It supports server-side rendering.

{{"component": "modules/components/ComponentLinkHeader.js", "design": false}}
Expand Down
43 changes: 24 additions & 19 deletions docs/pages/_app.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import generalDocsPages from 'docs/data/docs/pages';
import basePages from 'docs/data/base/pages';
import docsInfraPages from 'docs/data/docs-infra/pages';
import materialPages from 'docs/data/material/pages';
import InitialPropsContext from 'docs/src/docs-infra/InitialPropsContext';
import joyPages from 'docs/data/joy/pages';
import systemPages from 'docs/data/system/pages';
import PageContext from 'docs/src/modules/components/PageContext';
Expand Down Expand Up @@ -137,7 +138,7 @@ Tip: you can access the documentation \`theme\` object directly in the console.
);
}
function AppWrapper(props) {
const { children, emotionCache, pageProps } = props;
const { children, emotionCache, pageProps, initialProps } = props;

const router = useRouter();
// TODO move productId & productCategoryId resolution to page layout.
Expand Down Expand Up @@ -294,38 +295,42 @@ function AppWrapper(props) {
<meta name="mui:productId" content={productId} />
<meta name="mui:productCategoryId" content={productCategoryId} />
</NextHead>
<UserLanguageProvider defaultUserLanguage={pageProps.userLanguage}>
<CodeCopyProvider>
<CodeStylingProvider>
<CodeVariantProvider>
<PageContext.Provider value={pageContextValue}>
<ThemeProvider>
<DocsStyledEngineProvider cacheLtr={emotionCache}>
{children}
<GoogleAnalytics />
</DocsStyledEngineProvider>
</ThemeProvider>
</PageContext.Provider>
</CodeVariantProvider>
</CodeStylingProvider>
</CodeCopyProvider>
</UserLanguageProvider>
<InitialPropsContext.Provider value={initialProps}>
<UserLanguageProvider defaultUserLanguage={pageProps.userLanguage}>
<CodeCopyProvider>
<CodeStylingProvider>
<CodeVariantProvider>
<PageContext.Provider value={pageContextValue}>
<ThemeProvider>
<DocsStyledEngineProvider cacheLtr={emotionCache}>
{children}
<GoogleAnalytics />
</DocsStyledEngineProvider>
</ThemeProvider>
</PageContext.Provider>
</CodeVariantProvider>
</CodeStylingProvider>
</CodeCopyProvider>
</UserLanguageProvider>
</InitialPropsContext.Provider>
</React.Fragment>
);
}

AppWrapper.propTypes = {
children: PropTypes.node.isRequired,
emotionCache: PropTypes.object.isRequired,
initialProps: PropTypes.object,
pageProps: PropTypes.object.isRequired,
};

export default function MyApp(props) {
const { Component, emotionCache = clientSideEmotionCache, pageProps } = props;
const { Component, emotionCache = clientSideEmotionCache, pageProps: pagePropsProp } = props;
const getLayout = Component.getLayout ?? ((page) => page);
const { initialProps, ...pageProps } = pagePropsProp;

return (
<AppWrapper emotionCache={emotionCache} pageProps={pageProps}>
<AppWrapper emotionCache={emotionCache} pageProps={pageProps} initialProps={initialProps}>
{getLayout(<Component {...pageProps} />)}
</AppWrapper>
);
Expand Down
8 changes: 8 additions & 0 deletions docs/pages/base-ui/react-slider/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as React from 'react';
import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2';
import getModuleSize from 'docs/src/modules/components/getModuleSize';
import AppFrame from 'docs/src/modules/components/AppFrame';
import * as pageProps from 'docs/data/base/components/slider/slider.md?@mui/markdown';

Expand All @@ -11,3 +12,10 @@ export default function Page(props) {
Page.getLayout = (page) => {
return <AppFrame>{page}</AppFrame>;
};

Page.getInitialProps = async () => {
const moduleSize = await getModuleSize(pageProps);
return {
initialProps: { moduleSize },
};
};
2 changes: 1 addition & 1 deletion docs/public/_redirects
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/spam / 301
/sign-up / 301

/size-snapshot https://s3.eu-central-1.amazonaws.com/mui-org-ci/artifacts/master/latest/size-snapshot.json 200
/size-snapshot/ https://s3.eu-central-1.amazonaws.com/mui-org-ci/artifacts/master/latest/size-snapshot.json 200

# To add when we finish work on v6
# https://next.mui.com/* https://mui.com/:splat 301!
Expand Down
16 changes: 16 additions & 0 deletions docs/src/docs-infra/InitialPropsContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import * as React from 'react';

/**
* @typedef {Array<{ version: string; url: string }>} InitialPropsContextValue
*/

/**
* @type {React.Context<InitialPropsContextValue}
*/
const InitialPropsContext = React.createContext(null);

if (process.env.NODE_ENV !== 'production') {
InitialPropsContext.displayName = 'InitialPropsContext';
}

export default InitialPropsContext;
40 changes: 40 additions & 0 deletions docs/src/docs-infra/createGetModuleSize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const cache = new Map();

async function fetchBundlephobia(packageName: string, packageVersion: string) {
if (false && process.env.DEPLOY_ENV !== 'production' && process.env.DEPLOY_ENV !== 'staging') {
return {
assets: [],
};
}

if (cache.has(packageName)) {
return cache.get(packageName);
}

const bundlephobiaResponse = await fetch(`https://bundlephobia.com/api/exports-sizes?package=${packageName}@${packageVersion}`);
const data = await bundlephobiaResponse.json();
cache.set(packageName, data);
return data;
}

export default function createGetModuleSize({ packageVersion, productIdPackage }: { packageVersion: Object, productIdPackage: Object }) {
return async (pageProps: any) => {
const markdownHeader = pageProps.docs.en.headers;

// @ts-ignore
const packageName = productIdPackage[markdownHeader.productId];
// @ts-ignore
const data = await fetchBundlephobia(packageName, packageVersion[packageName]);

const modules = markdownHeader.components.concat(markdownHeader.hooks);

const sizes = data.assets.reduce((acc: any, asset: any) => {
if (modules.includes(asset.name)) {
acc[asset.name] = asset.gzip;
}
return acc;
}, {});

return sizes;
}
}
22 changes: 20 additions & 2 deletions docs/src/modules/components/ComponentLinkHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,17 @@ import AdobeXDIcon from 'docs/src/modules/components/AdobeXDIcon';
import BundleSizeIcon from 'docs/src/modules/components/BundleSizeIcon';
import W3CIcon from 'docs/src/modules/components/W3CIcon';
import MaterialDesignIcon from 'docs/src/modules/components/MaterialDesignIcon';
import InitialPropsContext from 'docs/src/docs-infra/InitialPropsContext';
import { useTranslate } from 'docs/src/modules/utils/i18n';

function formatBytes(bytes, decimals = 2) {
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'kB', 'MB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}

const Root = styled('ul')({
margin: 0,
padding: 0,
Expand All @@ -37,10 +46,19 @@ export default function ComponentLinkHeader(props) {
design,
} = props;
const t = useTranslate();

const initialProps = React.useContext(InitialPropsContext);
const modules = headers.components.concat(headers.hooks);
const packageName =
headers.packageName ?? defaultPackageNames[headers.productId] ?? '@mui/material';

let bundleSizeLabel = t('bundleSize');

console.log(initialProps.moduleSize);

if (Object.keys(initialProps.moduleSize).length > 0) {
bundleSizeLabel = `${bundleSizeLabel}: ${formatBytes(initialProps.moduleSize[modules[0]])}`;
}

return (
<Root>
{headers.githubLabel ? (
Expand Down Expand Up @@ -79,7 +97,7 @@ export default function ComponentLinkHeader(props) {
data-ga-event-action="click"
data-ga-event-label={t('bundleSize')}
data-ga-event-split="0.1"
label={t('bundleSize')}
label={bundleSizeLabel}
/>
</Tooltip>
</li>
Expand Down
22 changes: 22 additions & 0 deletions docs/src/modules/components/getModuleSize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import createGetModuleSize from 'docs/src/docs-infra/createGetModuleSize';
import materialPkgJson from 'packages/mui-material/package.json';
import joyPkgJson from 'packages/mui-joy/package.json';
import systemPkgJson from 'packages/mui-system/package.json';
import basePkgJson from 'packages/mui-base/package.json';

const getModuleSize = createGetModuleSize({
packageVersion: {
'@mui/material': materialPkgJson.version,
'@mui/joy': joyPkgJson.version,
'@mui/system': systemPkgJson.version,
'@mui/base': basePkgJson.version,
},
productIdPackage: {
'material-ui': '@mui/material',
'joy-ui': '@mui/joy',
'base-ui': '@mui/base',
system: '@mui/system',
},
});

export default getModuleSize;
2 changes: 1 addition & 1 deletion docs/src/pages/versions/ReleasedVersions.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import TableCell from '@mui/material/TableCell';
import TableRow from '@mui/material/TableRow';
import Typography from '@mui/material/Typography';
import Link from 'docs/src/modules/components/Link';
import VersionsContext from './VersionsContext';
import VersionsContext from 'docs/src/pages/versions/VersionsContext';

const GITHUB_RELEASE_BASE_URL = 'https://github.com/mui/material-ui/releases/tag/';

Expand Down
3 changes: 1 addition & 2 deletions packages/markdown/prepareMarkdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ function resolveComponentApiUrl(productId, componentPkg, component) {
function prepareMarkdown(config) {
const { fileRelativeContext, translations, componentPackageMapping = {}, options } = config;

const demos = {};
/**
* @type {Record<string, { rendered: Array<string | { component: string } | { demo:string }> }>}
*/
Expand Down Expand Up @@ -253,7 +252,7 @@ ${headers.hooks
}
}

return { demos, docs };
return { docs };
}

module.exports = prepareMarkdown;
Loading