gridsome / gridsome

⚡️ The Jamstack framework for Vue.js
https://gridsome.org
MIT License
8.53k stars 489 forks source link

[Perf] A page with a lot of g-link's is degrading render #1230

Open atilacamurca opened 4 years ago

atilacamurca commented 4 years ago

Description

A page with a lot of g-link's is degrading render. I have a website that show statistics about a fantasy soccer game from Brazil.

Steps to reproduce

I create a codesandbox with the minimal to run and perf the page that is degrading:

https://codesandbox.io/s/gridsome-perf-g-link-tr44x

image

And the component who is consuming more time is router-link, which is basically g-link.

image

Expected result

The page should not slow down render in a page with a lot of links.

Actual result

The render is degrading

Environment

  System:
    OS: Linux 4.19 Debian GNU/Linux 10 (buster) 10 (buster)
    CPU: (12) x64 Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz
  Binaries:
    Node: 10.20.1 - /usr/local/bin/node
    Yarn: 1.22.4 - /usr/local/bin/yarn
    npm: 6.14.4 - /usr/local/bin/npm
  npmPackages:
    @gridsome/source-filesystem: 0.6.2 => 0.6.2
    @gridsome/transformer-json: 0.2.1 => 0.2.1
    gridsome: 0.7.17 => 0.7.17
hjvedvik commented 4 years ago

@atilacamurca I'll try to do some debugging tomorrow :) But does it help if you use the <router-link> directly instead of <g-link>?

atilacamurca commented 4 years ago

Yes, even if you use router-link directly the slow down occurs.

The file that contains the links is src/components/atleta/DadosAtleta.vue (sorry about the extensive code). Lines 6 and 17 has router-link component (I want to permit the users to click on the name or avatar).

So, the page has 10 matches. Each match shows 8 athletes per team. Each athlete has 2 links, one in his name and another in his avatar. So this page has 2 8 10 * 2 = 320 links.

atilacamurca commented 4 years ago

I was able to change the router-link component with a simple a. The slow down was reduced significantly.

image

image

But the remaining router-link's of the page is still consuming most of the render time.

tonyketcham commented 3 years ago

I also had this problem really terribly and figured out that the following trick cut down the <g-link> render time by nearly 10x for my home page which has over a hundred <g-link> elements:

Before

import SidebarNav from '@/components/Sidebar-Nav.vue';
import SessionsFeed from '@/components/sessions/Sessions-Feed.vue';

export default {
  components: {
    SidebarNav,
    SessionsFeed,
  },
}

After

export default {
  components: {
    SidebarNav: () => import('@/components/Sidebar-Nav.vue'),
    SessionsFeed: () => import('@/components/sessions/Sessions-Feed.vue'),
  },
}

Next, I'm going to add in more lazy loading to cut down on the elements in the DOM and I expect some solid gains from that, too. Cutting out less-likely to be clicked <g-link> elements with regular <a> tags is also a good practice since there's a chance secondary or tertiary content isn't as important to pre-load and can be comfortably dropped down to <a> tags.