Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Selectively prefetch/preload js bundles (SSR) #6530

Closed
vdraceil opened this issue Mar 2, 2020 · 3 comments
Closed

Selectively prefetch/preload js bundles (SSR) #6530

vdraceil opened this issue Mar 2, 2020 · 3 comments
Assignees

Comments

@vdraceil
Copy link

vdraceil commented Mar 2, 2020

I'm using Quasar with amcharts . Unfortunately for the time being amcharts comes with 3 unwanted dependencies - canvg, xlsx, pdfmake ; all related to export functionality, which I'm not going to use at all.
In their side, those packages are dynamically imported with webpack magic comment to export it as a separate chunk. Like this -

import(/* webpackChunkName: "pdfmake" */ "pdfmake/build/pdfmake.js")

Problem#1
Now, when I just add amcharts as dependency, quasar prod build forcefully bundles up those 3 packages in my vendor.js not respecting those magic comments.

Is this how it is supposed to be? Should the webpack magic comments of the dependent packages be picked up by default?
Nothing wrong with this approach, but just wanted to know. Anyways, I got around this by using the below in quasar.conf.js

build: {
  vendor: {
    remove: [ 'xlsx', 'canvg', 'pdfmake' ]
  }
}

and this produces separate bundles for those each.
Is this the correct way to do it?

Problem#2
Those 3 js bundles are now being pre-fetched automatically - in SSR mode. I'm still not using any part of the amcharts export functionality.
I tried a few ways to get rid of pre-fetching selected bundles.

First by trying to use the preload-webpack-plugin like this in quasar.conf.js

const PreloadWebpackPlugin = require('preload-webpack-plugin')

build: {
  chainWebpack (chain) {
        chain.plugin('prefetch')
          .use(PreloadWebpackPlugin, [{
            rel: 'prefetch',
            include: 'asyncChunks',
            fileBlacklist: [
              /pdfmake.+\.js$/,
              /canvg.+\.js$/,
              /xlsx.+\.js$/,
            ]
          }])
          .after('html-webpack')
  }
}

This required me to install dev dependencies "html-webpack-plugin": "^4.0.0-beta.4" and "preload-webpack-plugin": "^3.0.0-beta.3" - versions matter as any prior version would throw a getHooks error.
This had no effect and the 3 bundles were still being added as <link rel="prefetch">...
Is this even the way to go on for this issue?

Second, I noticed there was this build.preloadChunks option in quasar.conf.js
.. but it is supposed to be a boolean. So, I just can turn on or off the preloading/prefetching and not selectively do it.
I traced the code which uses that config and it led me to node_modules/@quasar/app/lib/ssr/template.prod-webserver.js where we have this -

if (settings.preloadChunks !== true) {
  const fn = () => false
  Object.assign(rendererOptions, {
    shouldPreload: fn,
    shouldPrefetch: fn
  })
}

From https://ssr.vuejs.org/api/#shouldpreload , those options shouldPreload and shouldPrefetch can be functions in which we can selectively skip bundles with regex, but that option is not available at all to users.

So, with Quasar, how should I go on about excluding these bundles from being pre-fetched in the browser?

@vdraceil vdraceil changed the title Selectively prefetch/preload js bundles Selectively prefetch/preload js bundles (SSR) Mar 2, 2020
@rstoenescu rstoenescu self-assigned this Mar 2, 2020
@vdraceil
Copy link
Author

vdraceil commented Apr 13, 2020

@rstoenescu Sorry for the delay.

I just made a demo repo for explaining my issue.
https://gitlab.com/vdraceil/quasar-selective-prefetch

git clone https://gitlab.com/vdraceil/quasar-selective-prefetch.git
cd quasar-selective-prefetch
npm i
quasar build -m ssr
cd dist/ssr
npm start

The build should properly separate unused dependencies (unused by me) of amcharts into separate chunks - xlsx.xxxx.js , canvg.xxxx.js, pdfmake.xxxx.js - did this by adding vendor.remove setting in quasar.conf.js.

Screenshot_13-Apr-2020_T15-08-27_+07

As you can see the chunks are proper and separate.

If you hit the index page http://localhost:3000/ you should see a simple country map.
.. but if you follow up the resources loaded in the Networks tab of DevTools, you can see the chunks xlsx, canvg, pdfmake - the 3 which I never needed and never invoked any functionality regarding it (from amcharts dependency) is also being downloaded or prefetched.

We invoke only the map functionality and no export (PDF, Excel, etc.) functionality - so, ideally those chunks should never be loaded. As amcharts make dynamic imports to them as well.

I though, if I were able to pass in a function for shouldPrefetch, I could have forcefully skipped off these 3 chunks from ever loading or even being put up as part of <link rel="prefetch" ...> tags in the generated pages.
Vue SSR allows it to be a function, but Quasar overrides and allows only a boolean for this?

Is there any way in which I can not have those unnecessary dependency chunks being loaded?

@vladcosorg
Copy link

Fix for SSR mode
src-ssr/index.js

after line
const ssr = require('quasar-ssr')
add

ssr.mergeRendererOptions({
  shouldPreload: (file) => {
    return false
  },
  shouldPrefetch: (file) => {
    return false
  },
})

to disable all prefetching or preloading. Obviously this is a dumb thing to do, so use sparingly and remove only what you need.
https://ssr.vuejs.org/api/#shouldpreload

@IlCallo IlCallo mentioned this issue Dec 1, 2020
36 tasks
@hawkeye64
Copy link
Member

I am closing the issue for inactivity. If this is still a concern, please create a conversation in the Discussions area or feel free to reopen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants