How to prevent loading all tabbed view components at once upon app render

Hello all,

I am grateful for the framework7 family, and all the effort put into this project thus far.

I am new to it (7 months now). I recently started a framework7 Vue CLI tabbed view app, with the structure of the home page shown below.

My question or confusion is, upon render of the home page all the components of each tab are rendered at the same time, and my thought is that this can impact performance especially when you need to load large datasets or there’s a large number of request made in each component.

How can I make only one component (that is the active tab) to load first, while the others are only brought into view when their respective tab is active (i.e. clicked), is it something that is already available and I may not know about.

Cheers!!!. @nolimits4web

The home page code

<template>
<f7-page name="template">

    <!-- Views/Tabs container -->
    <f7-views tabs class="safe-areas">

        <!-- Tabbar for switching views-tabs -->
        <f7-toolbar tabbar labels bottom class="o-visible">
            <f7-link tab-link="#view-home" tab-link-active icon-ios="f7:compass" icon-md="f7:compass" text="Explore"></f7-link>
            <f7-link tab-link="#view-vacancies" icon-ios="f7:bed_double" icon-md="f7:bed_double" text="Vacancies"></f7-link>
            <f7-link tab-link="#view-hostels" icon-ios="f7:placemark" icon-md="f7:placemark" text="Groups"></f7-link>
            <f7-link tab-link="#view-profile" icon-ios="f7:person" icon-md="f7:person" text="Profile"></f7-link>
        </f7-toolbar>

        <!-- Your main view/tab, should have "view-main" class. It also has "tab-active" class -->
        <f7-view id="view-home" main tab tab-active url="/home/"></f7-view>

        <!-- Catalog View -->
        <f7-view id="view-vacancies" name="vacancies" tab url="/vacancies/"></f7-view>

        <!-- Settings View -->
        <f7-view id="view-hostels" name="hostels" tab url="/hostels/"></f7-view>

        <!-- Settings View -->
        <f7-view id="view-profile" name="profile" tab url="/profile/"></f7-view>

    </f7-views>

</f7-page>

https://framework7.io/docs/view.html
loadInitialPage

@shastox I am trying that prop on a view component but it gets mounted at the start of the app anyway…

Hi @shastox, where do i add this parameter?

Any help with this please…@nolimits4web

You can’t use tabbed View inside of Page, it is supported only in main App component as app layout.

My question or confusion is, upon render of the home page all the components of each tab are rendered at the same time, and my thought is that this can impact performance especially when you need to load large datasets or there’s a large number of request made in each component.

No any issues here. You can listend for tab:show event on View and based on that (when tab become visible) do your heavy database loading

Is there a way to listen for the tab:show event inside the Page that is viewed? Or to avoid to mounting the page until the tab:show event is triggered?

It is possible, by listening it on parent tab of current page.
For example (if it is a F7-Core router component), you can add something like this in page:init handler:

this.$el.parents('.tab').on('tab:show', () => {
  // parent tab becomes visible
})

I am using F7-Vue, how can i initiate this on page load, basically when a routed to the main app component.

Cheers!!!

@nolimits4web please can u give me an example of how to implement this, I have looked all through the documentation and couldn’t find an implementation of this. Please help

Show the related code of the app layout and of the page where you want to do it

I have succeeded in implementing it in my F7-Vue-app, based on @nolimits4web suggestion.

<f7-toolbar tabbar labels bottom class="o-visible">
            <f7-link tab-link="#view-home" tab-link-active icon-ios="f7:compass" icon-md="f7:compass" text="Explore"></f7-link>
            <f7-link tab-link="#view-vacancies" icon-ios="f7:bed_double" icon-md="f7:bed_double" text="Vacancies"></f7-link>
            <f7-link tab-link="#view-hostels" icon-ios="f7:placemark" icon-md="f7:placemark" text="Groups"></f7-link>
            <f7-link tab-link="#view-profile" icon-ios="f7:person" icon-md="f7:person" text="Profile"></f7-link>
</f7-toolbar>  

<f7-tabs>
            <f7-tab id="view-home" tab-active @tab:show="tabActive('view-home')">
                <div v-if="activeTab === 'view-home' ">
                    <home-view />
                </div>
            </f7-tab>
            <f7-tab id="view-vacancies" @tab:show="tabActive('view-vacancies')">
                <div v-if="activeTab === 'view-vacancies' ">
                    <vacancies-view />
                </div>
            </f7-tab>
            <f7-tab id="view-hostels" @tab:show="tabActive('view-hostels')">
                <div v-if="activeTab === 'view-hostels' ">
                    <hostels-view />
                </div>
            </f7-tab>
            <f7-tab id="view-profile" @tab:show="tabActive('view-profile')">
                <div v-if="activeTab === 'view-profile' ">
                    <profile-view />
                </div>
            </f7-tab>
        </f7-tabs>

On page mount the app listens for the active tab to show, then i created a method to show other tabs only when clicked

export default {
    data() {
        return {
            activeTab: 'view-home'
        }
    },
 methods: {
        tabActive(tab) {
            this.activeTab = tab
        },
},
}

Hope this helps someone as well. Cheers!!!

1 Like

How do I do this in a Vue component?

see my solution above

Thanks but I want to listen on the tab:show in the children vue component, not in the app. Or all the code for each tab will be in the app.vue file, but I need local logic

So if I could understand the usage of for this lazy-loading routes is wrong…
To have routes loaded separated, we should architecture our application into tabs instead!

Did anyone face any further limitation due to this approach?

I create my whole application with views… and now I have an App loading 12 different screens and consuming my API at same time as soon user clicks on it :frowning:

For future references:

When I changed all my views to tabs, I faced the limitation with routes and links!
I couldn’t control anymore different views on the App (since they don’t exists anymore) and lost also the opening animation for all links!

The best solution I’ve found is:

initRouterOnTabShow="true"

It makes your view component be mounted only when this view (working as tab) is visible!
And you can still using all views properties! :+1: