Overview
We used to import all our components from the root index file. There was no way for bundlers (vite) to tree shake unused code. This led to larger bundle sizes and performance issues. PR
Available imports / sub-paths
frappe-ui- Most commonly used components, composables, types & utilities.frappe-ui/frappe- All components, composables & utilities related to Frappe Apps.frappe-ui/icons- All icons exported from Frappe UI, can be found here.
frappe-ui configuration imports
frappe-ui/tailwind- Tailwind preset for Frappe UI. Import it in your tailwind.config.jsfrappe-ui/vite- Vite configuration for Frappe UI. Import it in your vite.config filefrappe-ui/style.css- Global styles for Frappe UI. Import it in your main CSS filefrappe-ui/tsconfig.base.json- Base tsconfig for Frappe UI. Extend it in your tsconfig.json. This file configures how the TS compiler will behave. Provides this via "compilerOptions". Can be extended in your project's tsconfig.json. To override specific options, you can specify them in your tsconfig.json file of your app.
Migration steps
- Change imports like
import Badge from "frappe-ui/src/components/Badge/Badge.vue"toimport { Badge } from "frappe-ui"
Most of the nested imports will be covered like this. If by chance some file / function is missed, please raise an issue or add that file into root index.ts file.
Checkout this section to see the changed imports.
-
Import all icons from
frappe-ui/icons -
In tailwind.config.js, change
import frappeUIPreset from "frappe-ui/src/tailwind/preset";toimport frappeUIPreset from "frappe-ui/tailwind";
- In your index.css or main css file, change
@import "frappe-ui/src/style.css";to@import "frappe-ui/style.css";
- For ts projects, frappe-ui now provides a base tsconfig. To use it, extend it in your tsconfig.json like this
{
"extends": "frappe-ui/tsconfig.base.json",
"compilerOptions": {
// your overrides here
}
}
Results
All apps using frappe-ui should see a significant reduction in bundle size almost 2.5x times.
Local site testing:
| App name | Before | After | Times |
|---|---|---|---|
| Helpdesk | 2540 KBs | 816KBs | ~3x |
| CRM | ~2450 KBs | ~620KBs | ~4x |
| Drive | ~3000 KBs | ~1200 KBs | ~3x |
Production site testing:
Before
After
793 KBs to 227 KBs ~2.5x reduction in bundle size
Changes to make
1. Components
-
import LoadingIndicator from "frappe-ui/src/components/LoadingIndicator.vue" → import { LoadingIndicator } from 'frappe-ui'
-
import Input from "frappe-ui/src/components/Input.vue" → import { Input } from 'frappe-ui'
-
import Popover from 'frappe-ui/src/components/Popover.vue' → import { Popover } from 'frappe-ui'
-
import ConfirmDialog from 'frappe-ui/src/components/ConfirmDialog.vue' → import { ConfirmDialog } from 'frappe-ui'
-
import TextInput from 'frappe-ui/src/components/TextInput/TextInput.vue' → import { TextInput } from 'frappe-ui'
-
import DatePicker from 'frappe-ui/src/components/DatePicker/DatePicker.vue' → import { DatePicker } from 'frappe-ui'
-
import FormLabel from "frappe-ui/src/components/FormLabel.vue" → import { FormLabel } from 'frappe-ui'
2. Utils
-
import { useDoctype } from 'frappe-ui/src/data-fetching' → import { useDoctype } from 'frappe-ui'
-
import { useNewDoc } from 'frappe-ui/src/data-fetching' → import { useNewDoc } from 'frappe-ui'
-
import { useFileUpload } from 'frappe-ui/src/utils/useFileUpload' → import { useFileUpload } from 'frappe-ui'
-
import { useCall } from 'frappe-ui/src/data-fetching' → import { useCall } from 'frappe-ui'
-
import FileUploadHandler from 'frappe-ui/src/utils/fileUploadHandler' → import { FileUploadHandler } from 'frappe-ui'
3. Types
-
import { UseListOptions } from 'frappe-ui/src/data-fetching/useList/types' → import { UseListOptions } from 'frappe-ui'
-
import type { OrderBy } from 'frappe-ui/src/data-fetching/useList/types' → import type { OrderBy } from 'frappe-ui'
-
import { ImageExtension } from 'frappe-ui/src/components/TextEditor/extensions/image' → import { ImageExtension } from 'frappe-ui'
4. Icons
-
import CircleCheck from 'frappe-ui/src/icons/CircleCheck.vue' → import { CircleCheckIcon } from 'frappe-ui/icons'
-
import HelpIcon from "frappe-ui/frappe/Icons/HelpIcon.vue" → import { HelpIcon } from "frappe-ui/icons"