vue-grid-layout icon indicating copy to clipboard operation
vue-grid-layout copied to clipboard

Question: why is the unzipped version over 1.7 MB in size?

Open nikos opened this issue 7 years ago • 15 comments

Just wondering after I added vue-grid-layout to my dependencies, I received a warning from webpack report:

                                                  Asset       Size  Chunks                    Chunk Names
               static/js/vendor.e0edbedd8d1dfc9f9886.js     1.9 MB       0  [emitted]  [big]  vendor

was before:

                                                  Asset       Size  Chunks             Chunk Names
               static/js/vendor.2b8e22f0b833885a5a5f.js    83.5 kB       0  [emitted]  vendor

Surely I can switch to the minified version which seems currently at 183KB, but I am still curious what (probably other dependency) makes vue-grid-layout so big? :-)

Thanks for all your efforts in releasing this lib open-source.

nikos avatar Jun 05 '17 12:06 nikos

Thats because the non-minified version includes all the dev dependencies. I'm not a webpack expert, but I think thats normal :)

gmsa avatar Jun 05 '17 18:06 gmsa

Hmm, I'm not quite sure (and neither an webpack expert ;) but I did install vue-tables-2 and vuedraggable(which both seem to have a small-medium 3rd party dependencies on their own). The vendor js size (non-minified) increased from 83,5kB to 104kB for vuedraggable and in case of vue-tables-2 to 189kB, which is still factor 10 less than for vue-grid-layout. My guess would be that something big in the (transitive) dependency tree for grid layout is included, which might not be necessary at the end of the day. May be there are tools around which lets you double check or constrain what is included or not with package.json means?

For reference: I used webpack version 2.6.1 with npm 5.0.2 and node 6.10.3

nikos avatar Jun 05 '17 21:06 nikos

Yes, probably there is something wrong in the webpack project configuration, but I don't really have that much free time right now to try and figure out what it is. I'll keep this open for later.

gmsa avatar Jun 06 '17 08:06 gmsa

With current webpack configuration library is so big because all dependencies are statically included (i don't take into account dev-dependencies like babel core etc.). So when you build your own project, output bundle will technically contain two Vue copies, one required for project and one required for vue-grid-layout. And these two copies are not the same. Check this article: https://medium.com/webpack/webpack-bits-getting-the-most-out-of-the-commonschunkplugin-ab389e5f318

To resolve this, use common chunks plugin like in article above.

Another solution is to exclude dependencies like Vue by using "externals" directive in webpack config: https://webpack.js.org/configuration/externals/

For example if some library has dependencies like vue, vuex, vue-resource, we can exclude them from distribution file by defining in webpack configuration (configuration for this library, not your application!): externals: { 'vue': 'vue', 'vuex': 'vuex', 'vue-resource': 'vue-resource', },

Libraries listed above are now treaten like they are present in current javascript environment (for example browser), so in application that uses library, must provide these libraries explicitly like:

import Vue from 'vue'; import Vuex from 'vuex'; import VueResource from 'vue-resource'; imoprt SomeLibrary from 'some-library';

So if vue-grid-layout would be in webpack config defined externals with Vue and Interact, usage of grid for end user would be: import Vue from 'vue'; import interact from 'interact.js'; import VueGridLayout from 'vue-grid-layout';

Ranmus avatar Jun 09 '17 11:06 Ranmus

Thanks for the help @Ranmus, I will take a look into it when I have some free time.

gmsa avatar Jun 09 '17 11:06 gmsa

@gmsa No problem, i think that will be fine to also add new dist version of library like vue has (vue.esm.js). This file should expose some simple mapping to library without transpiling and bundling. Specially for users that use own node environment with babel and webpack for building theirs applications. :)

Ranmus avatar Jun 09 '17 11:06 Ranmus

Any update on this the webpack bundle size is still very large.

Dave3of5 avatar Jul 29 '19 22:07 Dave3of5

Main problem now is interact.js, which is about 300kb uncompressed

gmsa avatar Jul 30 '19 09:07 gmsa

Yeah that's what i've found now as well, seems that interactjs lib is around 125kb (minimized)

https://bundlephobia.com/[email protected]

Along with the element-resize-detector dependency (~16kb) it brings this library to around 150kb in size minimized (before vue, vuex or any other dependencies are added to the list) https://bundlephobia.com/[email protected]

The issue for me is going to be that my project is something being loaded on a user's site (on top of their existing applications), so adding ~500kb-1mb to the page load is worrisome

I'm not worried about this for the admin user designing and editing the layout, I was just going to use the lib to handle output the grid, and just disable editing or moving of anything by setting static (for their end users) -- may just have to figure out a way to parse the grid data to CSS so i only load this lib when an admin user is editing the layout design.

tripflex avatar Sep 03 '19 21:09 tripflex

I know this may be a long-shot, but does anybody know who is probably more familiar with this lib, if it would even be possible to maybe fork this lib to something like vue-grid-layout-display removing the interactjs dependency to just display the grid (or chunking out interactjs so only loaded when needed)

I see the styles are generated here: https://github.com/jbaysolutions/vue-grid-layout/blob/master/src/components/GridItem.vue#L395

And interact is initialized on tryMakeDraggable: https://github.com/jbaysolutions/vue-grid-layout/blob/master/src/components/GridItem.vue#L706

and tryMakeResizable: https://github.com/jbaysolutions/vue-grid-layout/blob/master/src/components/GridItem.vue#L730

Ideally chunking it out to only load when static is false would be the best solution, then you could knock the size of this lib down tremendously -- maybe @Ranmus would know better? Still learning webpack myself (now moving to 4 where it's no longer a plugin) ... so maybe for now i'll just deal with the extra bundle size and once i have some time to dig into this see if it would be possible to chunk it out to only load the vendor lib when needed (basically interactjs)

tripflex avatar Sep 03 '19 22:09 tripflex

@gmsa If you build vue-grid-layout with the latest interact.js the bundle size is substantially smaller.

With interact.js 1.6.3: image

With interact.js 1.9.22: image

Any chance you could do a new build and update npm with the smaller bundle?

thecontrarycat avatar Sep 23 '20 10:09 thecontrarycat

I'll try and make a new build this week

gmsa avatar Sep 23 '20 10:09 gmsa

I ended up just setting this up in my own fork to chunk it out with webpack to only load it when editing is enabled on the frontend:

tryMakeDraggable: async function(){
    const self = this;
    if (this.draggable && !this.static) {
        if ( this.interactObj === null || this.interactObj === undefined ) {
            const interact = await import( /* webpackChunkName: "interact-js" */  'interactjs' );
            // webpack 4 uses .default @see https://webpack.js.org/guides/code-splitting/
            this.interactObj = interact.default( this.$refs.item );
        }
...

tripflex avatar Sep 25 '20 13:09 tripflex

Looks like tree shaking was added in later releases through https://github.com/taye/interact.js/issues/800 but this doesn't really handle anything referenced in this issue (lazy loading with webpack).

Figured I would mention it here just for reference.

The reason I went with the lazy loading for webpack is because i'm using this plugin to allow users to dynamically build grids the way they want, but once they're done building them, they will not need to be changed (by users visiting the site), so using the lazy loading only loads it when it's needed

tripflex avatar Dec 02 '20 22:12 tripflex

@tripflex lazy loading is what you did on the code snippet in you previous comment?

gmsa avatar Dec 04 '20 14:12 gmsa