Lazy Modules
Lazy Modules available from Framework7 version 3.4.0.
Lazy modules provide a way to make your web app startup time much faster, by loading initially only functionality required for home page/view, and load additional modules/components when navigating to pages that use them. This will make your initial app scripts and styles a way more smaller size, which is significant when you build a web app or PWA.
There are two type of modules available with Framework7. ES-modules and “browser modules”. To use ES-modules you need to use bundler with support like Webpack or Rollup. Browser modules are designed only to be used when you don’t use any bundler.
To load Framework7 modules after it was initialized we need to use following app methods:
app.loadModule(module) - load module
- module - one of the following:
- object with Framework7 Plugin
- function that returns
- string with module name to load (e.g.'searchbar'
)
- string with module path to load (e.g.'path/to/components/searchbar.js'
)
Method returns Promise
app.loadModules(modules) - load modules
- modules - array with modules, where each array item one of the described above
Method returns Promise
Firs of all, we need to realize what modules our app requires to display initial page and import them:
Later when we need to install additional F7 module we can use dynamic imports:
import('framework7/components/gauge/gauge.js')
.then(module => app.loadModule(module.default))
.then(() => {
// module loaded and we can use gauge api
app.gauge.create(/* ... */)
})
If we need to load few modules at a time:
Promise
.all([
import('framework7/components/gauge/gauge.js'),
import('framework7/components/calendar/calendar.js')
])
.then((modules) => {
// loaded module will be at ".default" prop of import result
var modulesToLoad = modules.map(module => module.default);
return app.loadModules(modulesToLoad);
})
.then(() => {
// modules loaded and we can use their api
app.gauge.create(/* ... */)
app.calendar.create(/* ... */)
})
It may be not very convenient to write it every time so we can make a function for that:
function loadF7Modules(moduleNames) {
var modulesToLoad = moduleNames.map((moduleName) => {
return import(`framework7/components/${moduleName}/${moduleName}.js`);
});
return Promise.all(modulesToLoad)
.then((modules) => {
return app.loadModules(modules.map(module => module.default));
})
}
And we can use it like:
If we need to preload modules for specific route then route’s async
is the best fit for it:
var routes = [
{
path: '/',
url: './index.html',
},
/* Page where we need Gauge and Calendar modules to be loaded */
{
path: '/gauge-calendar/',
async: function (routeTo, routeFrom, resolve, reject) {
// load modules
// resolve route
resolve({
componentUrl: './gauge-calendar.html',
});
});
}
}
]
The following ES-module components are available for importing (all other components are part of the core):
Browser modules are intended to be used in development setup without bundlers (like Webpack or Rollup).
<!DOCTYPE html>
<html>
<head>
...
<!-- Path to Framework7 Core Library CSS -->
<link rel="stylesheet" href="path/to/framework7/css/framework7.min.css">
<!-- Path to your custom app styles-->
<link rel="stylesheet" href="path/to/my-app.css">
</head>
<body>
<div id="app">
...
</div>
<!-- Path to Framework7 Core Library JS-->
<script type="text/javascript" src="path/to/framework7/js/framework7.min.js"></script>
<!-- Path to your app js-->
<script type="text/javascript" src="path/to/my-app.js"></script>
</body>
</html>
We also need to inclued modules/components that we need on initial page after framework7
styles and script. If we need Searchbar and Accordion then we need to include them in app layout:
<!DOCTYPE html>
<html>
<head>
...
<!-- Path to Framework7 Core Library CSS -->
<link rel="stylesheet" href="path/to/framework7/css/framework7.min.css">
<!-- Include modules required for initial page -->
<link rel="stylesheet" href="path/to/framework7/components/accordion.css">
<link rel="stylesheet" href="path/to/framework7/components/searchbar.css">
<!-- Path to your custom app styles-->
<link rel="stylesheet" href="path/to/my-app.css">
</head>
<body>
<div id="app">
...
</div>
<!-- Path to Framework7 Core Library JS-->
<script type="text/javascript" src="path/to/framework7/js/framework7.min.js"></script>
<script type="text/javascript" src="path/to/framework7/components/accordion.js"></script>
<script type="text/javascript" src="path/to/framework7/components/searchbar.js"></script>
<!-- Path to your app js-->
<script type="text/javascript" src="path/to/my-app.js"></script>
</body>
</html>
Now when we init Framework7 app we need to specify where is the rest of modules in lazyModulesPath
parameter (path to /components/
folder):
Now we can just load module by its name (it will automatically fetch file with such file name in specified lazyModulesPath
location):
app.loadModules(['calendar', 'gauge']).then(() => {
// modules loaded and we can use their api
app.gauge.create(/* ... */)
app.calendar.create(/* ... */)
});
Note, that browser modules also load modules styles automatically. So loading gauge.js
will also automatically load gauge.css
stylesheet.
So the above expression app.loadModules(['calendar', 'gauge'])
will load the following files:
- path/to/framework7/components/calendar.js
- path/to/framework7/components/calendar.css
- path/to/framework7/components/gauge.js
- path/to/framework7/components/gauge.css
When we need to preload modules for specific route and we use browser modules, then we can just use route’s modules
property:
var routes = [
{
path: '/',
url: './index.html',
},
/* Page where we need Gauge and Calendar modules to be loaded */
{
path: '/gauge-calendar/',
modules: ['gauge', 'calendar'], // will load these components before loading route
componentUrl: './gauge-calendar.html',
}
]
Or the same but using async
route like in example with ES modules:
var routes = [
{
path: '/',
url: './index.html',
},
/* Page where we need Gauge and Calendar modules to be loaded */
{
path: '/gauge-calendar/',
modules: ['gauge', 'calendar'], // will load these components before loading route
async: function(routeTo, routeFrom, resolve, reject) {
app.loadModules(['gauge', 'calendar']).then(() => {
resolve({
componentUrl: './gauge-calendar.html',
});
});
},
}
]
The following browser modules-components are available for loading (all other components are part of the core):
Component | Name | Path |
---|---|---|
Dialog | framework7/components/dialog.js | |
Popup | popup | framework7/components/popup.js |
LoginScreen | login-screen | framework7/components/login-screen.js |
Popover | popover | framework7/components/popover.js |
Actions | actions | framework7/components/actions.js |
Sheet | sheet | framework7/components/sheet.js |
Toast | toast | framework7/components/toast.js |
Preloader | preloader | framework7/components/preloader.js |
Progressbar | progressbar | framework7/components/progressbar.js |
Sortable | sortable | framework7/components/sortable.js |
Swipeout | swipeout | framework7/components/swipeout.js |
Accordion | accordion | framework7/components/accordion.js |
ContactsList | contacts-list | framework7/components/contacts-list.js |
VirtualList | virtual-list | framework7/components/virtual-list.js |
ListIndex | list-index | framework7/components/list-index.js |
Timeline | timeline | framework7/components/timeline.js |
Tabs | tabs | framework7/components/tabs.js |
Panel | panel | framework7/components/panel.js |
Card | card | framework7/components/card.js |
Chip | chip | framework7/components/chip.js |
Form | form | framework7/components/form.js |
Input | input | framework7/components/input.js |
Checkbox | checkbox | framework7/components/checkbox.js |
Radio | radio | framework7/components/radio.js |
Toggle | toggle | framework7/components/toggle.js |
Range | range | framework7/components/range.js |
Stepper | stepper | framework7/components/stepper.js |
SmartSelect | smart-select | framework7/components/smart-select.js |
Grid | grid | framework7/components/grid.js |
Calendar | calendar | framework7/components/calendar.js |
Picker | picker | framework7/components/picker.js |
InfiniteScroll | infinite-scroll | framework7/components/infinite-scroll.js |
PullToRefresh | pull-to-refresh | framework7/components/pull-to-refresh.js |
Lazy | lazy | framework7/components/lazy.js |
DataTable | data-table | framework7/components/data-table.js |
Fab | fab | framework7/components/fab.js |
Searchbar | searchbar | framework7/components/searchbar.js |
Messages | messages | framework7/components/messages.js |
Messagebar | messagebar | framework7/components/messagebar.js |
Swiper | swiper | framework7/components/swiper.js |
PhotoBrowser | photo | framework7/components/browser/photo-browser.js |
Notification | notification | framework7/components/notification.js |
Autocomplete | autocomplete | framework7/components/autocomplete.js |
Tooltip | tooltip | framework7/components/tooltip.js |
Gauge | gauge | framework7/components/gauge.js |
Skeleton | skeleton | framework7/components/skeleton.js |
Menu | menu | framework7/components/menu.js |
Vi | vi | framework7/components/vi.js |
Typography | framework7/components/typography.js |