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 import/export support like Webpack or Rollup. Browser modules are designed only to be used when you don't use any bundler.

    Modules API

    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 Framework7 Plugin
      - string with module name to load (e.g. 'searchbar')
      - string with module path to load (e.g. 'path/to/lazy-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

    ES Modules

    This method will only work if you use bundler like Webpack or Rollup.

    Firs of all, we need to realize what modules our app requires to display initial page and import them:

    // import core framework with core components only:
    import Framework7 from 'framework7';
    
    // import framework7 modules/components we need on initial page
    import Searchbar from 'framework7/components/searchbar/searchbar.js';
    import Accordion from 'framework7/components/accordion/accordion.js';
    
    // install core modules
    Framework7.use([Searchbar, Accordion]);
    
    // init app
    var app = new Framework7({
      // f7 params
    });

    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:

    loadF7Modules(['gauge', 'calendar']).then(() => {
      // modules loaded and we can use their api
      app.gauge.create(/* ... */)
      app.calendar.create(/* ... */)
    });

    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
          loadF7Modules(['gauge', 'calendar']).then(() => {
            // resolve route
            resolve({
              componentUrl: './gauge-calendar.html',
            });
          });
        }
      }
    ]

    The following ES-module components are available for importing (all other components are part of the core):

    Component Path
    Dialog framework7/components/dialog/dialog.js
    Popup framework7/components/popup/popup.js
    LoginScreen framework7/components/login-screen/login-screen.js
    Popover framework7/components/popover/popover.js
    Actions framework7/components/actions/actions.js
    Sheet framework7/components/sheet/sheet.js
    Toast framework7/components/toast/toast.js
    Preloader framework7/components/preloader/preloader.js
    Progressbar framework7/components/progressbar/progressbar.js
    Sortable framework7/components/sortable/sortable.js
    Swipeout framework7/components/swipeout/swipeout.js
    Accordion framework7/components/accordion/accordion.js
    ContactsList framework7/components/contacts-list/contacts-list.js
    VirtualList framework7/components/virtual-list/virtual-list.js
    ListIndex framework7/components/list-index/list-index.js
    Timeline framework7/components/timeline/timeline.js
    Tabs framework7/components/tabs/tabs.js
    Panel framework7/components/panel/panel.js
    Card framework7/components/card/card.js
    Chip framework7/components/chip/chip.js
    Form framework7/components/form/form.js
    Input framework7/components/input/input.js
    Checkbox framework7/components/checkbox/checkbox.js
    Radio framework7/components/radio/radio.js
    Toggle framework7/components/toggle/toggle.js
    Range framework7/components/range/range.js
    Stepper framework7/components/stepper/stepper.js
    SmartSelect framework7/components/smart-select/smart-select.js
    Grid framework7/components/grid/grid.js
    Calendar framework7/components/calendar/calendar.js
    Picker framework7/components/picker/picker.js
    InfiniteScroll framework7/components/infinite-scroll/infinite-scroll.js
    PullToRefresh framework7/components/pull-to-refresh/pull-to-refresh.js
    Lazy framework7/components/lazy/lazy.js
    DataTable framework7/components/data-table/data-table.js
    Fab framework7/components/fab/fab.js
    Searchbar framework7/components/searchbar/searchbar.js
    Messages framework7/components/messages/messages.js
    Messagebar framework7/components/messagebar/messagebar.js
    Swiper framework7/components/swiper/swiper.js
    PhotoBrowser framework7/components/photo-browser/photo-browser.js
    Notification framework7/components/notification/notification.js
    Autocomplete framework7/components/autocomplete/autocomplete.js
    Tooltip framework7/components/tooltip/tooltip.js
    Gauge framework7/components/gauge/gauge.js
    Vi framework7/components/vi/vi.js
    Typography framework7/components/typography/typography.js

    Browser Modules

    Browser modules are intended to be used in development setup without bundlers (like Webpack or Rollup).

    First of all, in our main app layout we need to use so called "framework7-lazy" library instead of framework7.js and framework7.css scripts and styles that contains whole framework.

    <!DOCTYPE html>
    <html>
      <head>
        ...
        <!-- Path to Framework7 Lazy Library CSS -->
        <link rel="stylesheet" href="path/to/framework7/css/framework7-lazy.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 Lazy Library JS-->
        <script type="text/javascript" src="path/to/framework7/js/framework7-lazy.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-lazy 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 Lazy Library CSS -->
        <link rel="stylesheet" href="path/to/framework7/css/framework7-lazy.min.css">
        <!-- Include modules required for initial page -->
        <link rel="stylesheet" href="path/to/framework7/lazy-components/accordion.css">
        <link rel="stylesheet" href="path/to/framework7/lazy-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 Lazy Library JS-->
        <script type="text/javascript" src="path/to/framework7/js/framework7-lazy.min.js"></script>
        <!-- Include modules required for initial page -->
        <script type="text/javascript" src="path/to/framework7/lazy-components/accordion.js"></script>
        <script type="text/javascript" src="path/to/framework7/lazy-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 /lazy-components/ folder):

    var app = new Framework7({
      // ...
      lazyModulesPath: 'path/to/framework7/lazy-components',
    });

    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/lazy-components/calendar.js
    • path/to/framework7/lazy-components/calendar.css
    • path/to/framework7/lazy-components/gauge.js
    • path/to/framework7/lazy-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 dialog framework7/lazy-components/dialog.js
    Popup popup framework7/lazy-components/popup.js
    LoginScreen login-screen framework7/lazy-components/login-screen.js
    Popover popover framework7/lazy-components/popover.js
    Actions actions framework7/lazy-components/actions.js
    Sheet sheet framework7/lazy-components/sheet.js
    Toast toast framework7/lazy-components/toast.js
    Preloader preloader framework7/lazy-components/preloader.js
    Progressbar progressbar framework7/lazy-components/progressbar.js
    Sortable sortable framework7/lazy-components/sortable.js
    Swipeout swipeout framework7/lazy-components/swipeout.js
    Accordion accordion framework7/lazy-components/accordion.js
    ContactsList contacts-list framework7/lazy-components/contacts-list.js
    VirtualList virtual-list framework7/lazy-components/virtual-list.js
    ListIndex list-index framework7/lazy-components/list-index.js
    Timeline timeline framework7/lazy-components/timeline.js
    Tabs tabs framework7/lazy-components/tabs.js
    Panel panel framework7/lazy-components/panel.js
    Card card framework7/lazy-components/card.js
    Chip chip framework7/lazy-components/chip.js
    Form form framework7/lazy-components/form.js
    Input input framework7/lazy-components/input.js
    Checkbox checkbox framework7/lazy-components/checkbox.js
    Radio radio framework7/lazy-components/radio.js
    Toggle toggle framework7/lazy-components/toggle.js
    Range range framework7/lazy-components/range.js
    Stepper stepper framework7/lazy-components/stepper.js
    SmartSelect smart-select framework7/lazy-components/smart-select.js
    Grid grid framework7/lazy-components/grid.js
    Calendar calendar framework7/lazy-components/calendar.js
    Picker picker framework7/lazy-components/picker.js
    InfiniteScroll infinite-scroll framework7/lazy-components/infinite-scroll.js
    PullToRefresh pull-to-refresh framework7/lazy-components/pull-to-refresh.js
    Lazy lazy framework7/lazy-components/lazy.js
    DataTable data-table framework7/lazy-components/data-table.js
    Fab fab framework7/lazy-components/fab.js
    Searchbar searchbar framework7/lazy-components/searchbar.js
    Messages messages framework7/lazy-components/messages.js
    Messagebar messagebar framework7/lazy-components/messagebar.js
    Swiper swiper framework7/lazy-components/swiper.js
    PhotoBrowser photo framework7/lazy-components/browser/photo-browser.js
    Notification notification framework7/lazy-components/notification.js
    Autocomplete autocomplete framework7/lazy-components/autocomplete.js
    Tooltip tooltip framework7/lazy-components/tooltip.js
    Gauge gauge framework7/lazy-components/gauge.js
    Vi vi framework7/lazy-components/vi.js
    Typography typography framework7/lazy-components/typography.js