grafana / oncall

Developer-friendly incident response with brilliant Slack integration
GNU Affero General Public License v3.0
3.49k stars 288 forks source link

Frontend: Code split the plugin for improved performance #5018

Closed jackw closed 2 weeks ago

jackw commented 1 month ago

What would you like to see!

Hello! 👋

Whilst auditing Grafana javascript payloads we've noticed that your Grafana app plugin is not taking advantage of code splitting. This is resulting it a large amount of unused Javascript being preloaded before the Grafana application can render anything. We're aware applications grow over time and generally we're not great at keeping on top of this but we would really appreciate it if you could put some time into code splitting this app plugin to help us reduce the amount of javascript code we're loading up front.

The following are worth considering when taking on this task:

  1. The module.js is the entrypoint. It's worth keeping in mind that the smaller this file is the less effect it has on the performance of Grafana as a whole during the app preload phase which is currently render blocking.
  2. Rename your module.ts to module.tsx and take advantage of Suspense, lazy, and webpacks dynamic import to lazy load your apps rootPage and (if it has one) its config page too.
  3. If your app contains additional routes and pages they are likely the quickest way to reduce bundle size further by lazy loading them.
  4. Any component registry (i.e. an array of objects that contain components) should be considered a target for code splitting with Suspense / lazy to further reduce bundle size.
  5. Any components used with the plugin ui extensions api should be considered a target for code splitting with Suspense and lazy to remove them from the bundled module.js file.

Below are two examples of Grafana plugins that have recently been code split or are in the process of being code split. The motions are generally the same for all app plugins as the module.js revolves mostly around the AppPlugin class. These should help give you a better understanding of what's involved:

Further information:

Product Area

Other

Anything else to add?

No response

github-actions[bot] commented 1 month ago

The current version of Grafana OnCall, at the time this issue was opened, is v1.9.25. If your issue pertains to an older version of Grafana OnCall, please be sure to list it in the PR description. Thank you :smile:!

leeoniya commented 1 month ago

btw, this is what we're seeing when loading up an empty dashboard on an ephemeral instance, to give you an idea of potential impact on overall load times:

https://ephemeral1511182192959leeoniy.grafana-dev.net/d/cdwx3aa48mvb4d/empty?from=now-6h&to=now&timezone=browser

Image

teodosii commented 3 weeks ago

Has been merged to IRM, will close it once it's been released

leeoniya commented 3 weeks ago

hey, @teodosii , thanks!

it's been released / deployed, and there is good improvement but we're still seeing a 1.3MB module.tsx bundle for oncall-app. it looks like there's no Suspense or lazy in grafana-oncall-app/src/module.tsx ?

Image

teodosii commented 3 weeks ago

Hey @leeoniya

I did merge another PR regarding this

Not entirely familiar with how the Coverage tool works on a minified version, but after these changes when we build the plugin the largest file is much smaller than what he had in the past.

Network tab on oncalldev environment Image

As for the coverage tab this is the result Image

I'm not sure how accurate is the coverage tab, as if you look closely it's saying that a huge chunk of it is taken by the library tinycolor, but that's not true, as if you inspect the bundle closely with tools such as bundle-analyzer, it's actually moment-timezone taking the biggest chunk (which would be the next step in reducing the bundle size by removing dep of that, as most of our date handling is in dayjs)

teodosii commented 2 weeks ago

Last PR regarding momentjs has been merged and the bundle size decreased by another ~700kb. Here's a screenshot of it in ops environment. From 2.8mb to 235kb

Image