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

[webpack] setup lazy loading for all visualizations #4727

Merged
merged 16 commits into from
Jun 15, 2018

Conversation

williaster
Copy link
Contributor

This PR adds lazy loading to all visualizations to partially address #4705 to reduce JS bundle size. This reduces the explore and dashboard bundle sizes by half, with the idea that the user would then fetch visualization bundles as needed, depending on what's present on a dashboard or as they toggle vis types in explore.

We want to do some empirical testing with some of our internal dashboards next week, and will update then. In the meantime feel free to pull the branch or comment on the code.

before

after

@graceguo-supercat @mistercrunch

[VIZ_TYPES.event_flow]: () => loadVis(import(/* webpackChunkName: "EventFlow" */ './EventFlow.jsx')),
[VIZ_TYPES.paired_ttest]: () => loadVis(import(/* webpackChunkName: "paired_ttest" */ './paired_ttest.jsx')),
[VIZ_TYPES.partition]: () => loadVis(import(/* webpackChunkName: "partition" */ './partition.js')),
[VIZ_TYPES.deck_scatter]: () => loadVis(import(/* webpackChunkName: "deckgl/layers/scatter" */ './deckgl/layers/scatter.jsx')),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use the same webpackChunkName for all deck_*?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the goal here? for readability or to have all of that code in one chunk?

I think using the same chunk name would only work if the same code was imported which is currently not possible since there are multiple index files for the various deck gl layers, right?

@mistercrunch
Copy link
Member

Wondering why the webpackChunkName doesn't show as such on entry file names, there's probably a way to hook that up.

We should probably have one webpackChunkName for all the visualizations that are mostly just d3 and small libs.

@mistercrunch
Copy link
Member

But this is awesome btw!

@williaster
Copy link
Contributor Author

fyi hitting some issues testing this with prod data, still working on it. should be able to get the chunk files to have names that match the name in the code 👍

@vibinsv09
Copy link

@williaster Did the issue around testing with Prod data resolve?
Thanks for all the great work. This is awesome.

@williaster
Copy link
Contributor Author

sorry progress has been slower than expected, have been slammed with other projects including a focused sprint this week. will make this a priority to test early next week.

@williaster williaster force-pushed the chris--lazy-load-visualizations branch from 2102987 to 7fe5243 Compare May 1, 2018 00:00
@williaster
Copy link
Contributor Author

I got chunk names to update (see exact webpack input / output below) and wanted to post some numbers from local dashboard testing which all look pretty good:

  • average total payload decreased by 5 MB
  • DOM content load time decreased 3.4s
  • Page load time decreased 1.1s
  • the average # requests increased by 6
  Total payload (MB)    
Dashboard Before After  
Births example 12.4 6.9 -5.5
World data example 12.4 8.7 -3.7
Misc charts example 14.9 8.5 -6.4
Misc charts example w Deck gl 15.4 11.1 -4.3
  DOM content loaded (seconds)    
Dashboard Before After Delta
Births example 7.69 2.93 -4.76
World data example 6.58 2.63 -3.95
Misc charts example 6.38 3.88 -2.50
Misc charts example w Deck gl 6.20 2.71 -3.49
  Total time (seconds)    
Dashboard Before After Delta
Births example 9.25 6.87 -2.38
World data example 9.22 6.78 -2.44
Misc charts example 7.69 5.53 -2.16
Misc charts example w Deck gl 7.73 10.19 +2.45
  Requests (count)    
Dashboard Before After Delta
Births example 32 36 +4
World data example 29 34 +5
Misc charts example 45 53 +8
Misc charts example w Deck gl 59 67 +8

webpack output before

Hash: 09e816a63d54c8a794f4
Version: webpack 3.10.0
Time: 44176ms (44s)
                                  Asset       Size  Chunks                    Chunk Names
  welcome.f1949d0f24772fdd90be.entry.js    8.49 MB    5, 6  [emitted]  [big]  welcome
   f4769f9bdb7466be65088239c12046d1.eot    20.1 kB          [emitted]
  fa2772327f55d8198301fdb8bcfc8158.woff    23.4 kB          [emitted]
   e18bbf611f2a2e43afc071aa2f4e1512.ttf    45.4 kB          [emitted]
   89889688147bd7575d6327160d64e760.svg     109 kB          [emitted]
dashboard.7aae3890d2f0d6521e6e.entry.js    48.1 MB    0, 6  [emitted]  [big]  dashboard
  explore.7876f80fe4be57a17e6c.entry.js    46.3 MB    1, 6  [emitted]  [big]  explore
   sqllab.80cb1149088d4df08c50.entry.js    17.8 MB    2, 6  [emitted]  [big]  sqllab
  profile.87ba695abcd8682ad921.entry.js    8.57 MB    3, 6  [emitted]  [big]  profile
 addSlice.f27f6a8368fce90f27ca.entry.js    9.18 MB    4, 6  [emitted]  [big]  addSlice
 448c34a56d699c29117adc64c43affeb.woff2      18 kB          [emitted]
   common.540032da3aeaf1cdc78e.entry.js    3.85 MB       6  [emitted]  [big]  common
    theme.912f2edddcf1890cf5f2.entry.js    6.12 kB       7  [emitted]         theme
         theme.912f2edddcf1890cf5f2.css     321 kB       7  [emitted]  [big]  theme
       explore.7876f80fe4be57a17e6c.css    85.5 kB    1, 6  [emitted]         explore
     dashboard.7aae3890d2f0d6521e6e.css    92.9 kB    0, 6  [emitted]         dashboard
        sqllab.80cb1149088d4df08c50.css    7.01 kB    2, 6  [emitted]         sqllab
       welcome.f1949d0f24772fdd90be.css  846 bytes    5, 6  [emitted]         welcome
       profile.87ba695abcd8682ad921.css    1.04 kB    3, 6  [emitted]         profile
                          manifest.json    1.17 kB          [emitted]
  [31] ./src/locales.jsx 5.63 kB {0} {1} {2} {3} {4} {5} {6} [built]
 [544] ./src/common.js 1.52 kB {0} {1} {2} {3} {4} {5} {6} [built]
[2877] ./src/theme.js 152 bytes {7} [built]
[2879] ./stylesheets/react-select/select.less 41 bytes {7} [built]
[2881] multi babel-polyfill ./src/addSlice/index.jsx 40 bytes {4} [built]
[2882] ./src/addSlice/index.jsx 793 bytes {4} [built]
[2884] multi babel-polyfill ./src/explore/index.jsx 40 bytes {1} [built]
[2885] ./src/explore/index.jsx 3.53 kB {1} [built]
[2910] multi babel-polyfill ./src/dashboard/index.jsx 40 bytes {0} [built]
[2911] ./src/dashboard/index.jsx 1.47 kB {0} [built]
[2976] multi babel-polyfill ./src/SqlLab/index.jsx 40 bytes {2} [built]
[2977] ./src/SqlLab/index.jsx 1.55 kB {2} [built]
[3062] multi babel-polyfill ./src/welcome/index.jsx 40 bytes {5} [built]
[3066] multi babel-polyfill ./src/profile/index.jsx 40 bytes {3} [built]
[3067] ./src/profile/index.jsx 775 bytes {3} [built]
    + 3119 hidden modules

webpack output after

Hash: 460ae189f7f00025375d
Version: webpack 3.11.0
Time: 45052ms
                                                 Asset       Size                        Chunks                    Chunk Names
    parallel_coordinates.e19f30010f7bbf13546b.chunk.js     204 kB                            22  [emitted]         parallel_coordinates
                  f4769f9bdb7466be65088239c12046d1.eot    20.1 kB                                [emitted]
                 fa2772327f55d8198301fdb8bcfc8158.woff    23.4 kB                                [emitted]
                  e18bbf611f2a2e43afc071aa2f4e1512.ttf    45.4 kB                                [emitted]
                  89889688147bd7575d6327160d64e760.svg     109 kB                                [emitted]
              big_number.79adb118812eccd063fb.chunk.js    53.5 kB                             0  [emitted]         big_number
                  markup.948cb22fcab6b19f2e4a.chunk.js    19.5 kB                             1  [emitted]         markup
              filter_box.91002d1d9472edde49bf.chunk.js      12 MB                             2  [emitted]  [big]  filter_box
                nvd3_vis.281a1af3a506a8e3884a.chunk.js     6.8 MB                             3  [emitted]  [big]  nvd3_vis
            deckgl/multi.d6e764166d7b4103af7b.chunk.js    9.32 MB  4, 5, 6, 7, 8, 9, 10, 11, 12  [emitted]  [big]  deckgl/multi
   deckgl/layers/scatter.b568ad5250e9d22975d9.chunk.js    9.24 MB                             5  [emitted]  [big]  deckgl/layers/scatter
deckgl/layers/screengrid.1ee238f0aebaf8d8900b.chunk.js    9.21 MB                             6  [emitted]  [big]  deckgl/layers/screengrid
   deckgl/layers/polygon.97570d1ea352ddf510c1.chunk.js    8.82 MB                             7  [emitted]  [big]  deckgl/layers/polygon
      deckgl/layers/path.f323723cf70e8bf1a147.chunk.js    8.82 MB                             8  [emitted]  [big]  deckgl/layers/path
       deckgl/layers/hex.7cb60849a307eb9519ac.chunk.js    8.82 MB                             9  [emitted]  [big]  deckgl/layers/hex
      deckgl/layers/grid.bcf5bdb27ebbb42bc62a.chunk.js    8.82 MB                            10  [emitted]  [big]  deckgl/layers/grid
   deckgl/layers/geojson.cbe273cf0fb9776d61a8.chunk.js    8.82 MB                            11  [emitted]  [big]  deckgl/layers/geojson
       deckgl/layers/arc.39fe4230cf2b9752527d.chunk.js    8.82 MB                            12  [emitted]  [big]  deckgl/layers/arc
              time_table.95406246d98f54294384.chunk.js    1.52 MB                            13  [emitted]  [big]  time_table
                  mapbox.67012446cc08ff6e6d3b.chunk.js    4.44 MB                            14  [emitted]  [big]  mapbox
                  sankey.c1f5d4b1cd7fee7c1df5.chunk.js     268 kB                            15  [emitted]  [big]  sankey
               partition.b8e65a38f2ba807b683c.chunk.js     164 kB                            16  [emitted]         partition
            paired_ttest.a8f0d23de7bf7d03f698.chunk.js     304 kB                            17  [emitted]  [big]  paired_ttest
                 heatmap.d40eccee55ff046c5cbe.chunk.js     121 kB                            18  [emitted]         heatmap
             cal_heatmap.6139e8dce5f6dcba25bb.chunk.js     369 kB                            19  [emitted]  [big]  cal_heatmap
                   table.a2fd3be152bf2fca343d.chunk.js    2.11 MB                            20  [emitted]  [big]  table
             pivot_table.0d04def897b408ec3b1a.chunk.js     2.1 MB                            21  [emitted]  [big]  pivot_table
                448c34a56d699c29117adc64c43affeb.woff2      18 kB                                [emitted]
               world_map.4bd7602539b8b4592dea.chunk.js     945 kB                            23  [emitted]  [big]  world_map
              word_cloud.b0132e63e142e2fd7f59.chunk.js      45 kB                            24  [emitted]         word_cloud
                    rose.a6ba8766b408b3e4f73d.chunk.js    1.71 MB                            25  [emitted]  [big]  rose
               histogram.1c13537ec243db524ad2.chunk.js    1.68 MB                            26  [emitted]  [big]  histogram
                 treemap.794f7dd7d9794550ad1d.chunk.js    35.6 kB                            27  [emitted]         treemap
                sunburst.6ffd5e2a361c18ed0d8e.chunk.js      39 kB                            28  [emitted]         sunburst
                 horizon.8abe55276c7820163e5a.chunk.js    23.6 kB                            29  [emitted]         horizon
          directed_force.49dc8886c3f71bab1449.chunk.js      18 kB                            30  [emitted]         directed_force
             country_map.2778be0dacd7c4394588.chunk.js    22.1 kB                            31  [emitted]         country_map
                   chord.176754155a97063f7613.chunk.js    14.3 kB                            32  [emitted]         chord
               EventFlow.8c353f56f7543defba73.chunk.js    2.57 MB                            33  [emitted]  [big]  EventFlow
                  iframe.b8be5f33d0c7897f3572.chunk.js     1.8 kB                            34  [emitted]         iframe
                 explore.4ef76280c9d4dd518109.entry.js    25.6 MB                        35, 41  [emitted]  [big]  explore
                  sqllab.93043b1fe98d1f6f2b17.entry.js    19.8 MB                        36, 41  [emitted]  [big]  sqllab
               dashboard.2e52929a378e5a3bb690.entry.js    15.4 MB                        37, 41  [emitted]  [big]  dashboard
                 profile.a489b8f49f5417a5d354.entry.js    8.71 MB                        38, 41  [emitted]  [big]  profile
                addSlice.f9974bb068e902b9230c.entry.js    9.32 MB                        39, 41  [emitted]  [big]  addSlice
                 welcome.bd3f186ea503ea87abe2.entry.js    8.64 MB                        40, 41  [emitted]  [big]  welcome
                  common.cfc61ebddf4e3f04d3e4.entry.js    3.99 MB                            41  [emitted]  [big]  common
                   theme.d104d43a3618a91391ee.entry.js    6.15 kB                            42  [emitted]         theme
                        theme.d104d43a3618a91391ee.css     321 kB                            42  [emitted]  [big]  theme
                      explore.4ef76280c9d4dd518109.css    7.43 kB                        35, 41  [emitted]         explore
                    dashboard.2e52929a378e5a3bb690.css    12.6 kB                        37, 41  [emitted]         dashboard
                       sqllab.93043b1fe98d1f6f2b17.css    7.01 kB                        36, 41  [emitted]         sqllab
                      welcome.bd3f186ea503ea87abe2.css  846 bytes                        40, 41  [emitted]         welcome
                      profile.a489b8f49f5417a5d354.css    1.04 kB                        38, 41  [emitted]         profile
                                         manifest.json    3.47 kB                                [emitted]

@mistercrunch
Copy link
Member

mistercrunch commented May 1, 2018

We should use the same webchunk name for all deckgl-related charts, same for nvd3 and same all the ones that only require d3. I'm thinking we could have 4-5 bundles with all the visualizations in them.

The "DeckGL Demo" dashboard should be much fast as it will load one 8mb chunk instead of 6 of them.

Is it just a matter of sharing/reusing webchunknames?

@williaster
Copy link
Contributor Author

It's not as trivial as using the same chunk name. The final name consists of chunk name and hash.

I'd rather do that optimization in another PR because I think you'd have to create an index file that exports all of deckgl and async import that file. I'm not as familiar with the deckgl code organization so you all might be best suited to do that?

@williaster
Copy link
Contributor Author

williaster commented May 1, 2018

I can give deck.gl a shot if you want tho, I think the d3 bundle is almost over optimizing. That'll be harder to untangle potentially as we refactor vis libraries.

@mistercrunch
Copy link
Member

mistercrunch commented May 1, 2018

I'm worried about the way things look here without bundling visualizations together. The sum of all visualization is much more than the original explore bundle.

A simple dashboard with a filter_box , nvd3, table and pivot_table will load like 24mb which is significantly more than the old explore bundle.

I'm guessing the load time improvements have to do with the fact that some of the work can be started upfront while the bundles are downloading. Results may look different on a network-bound scenario.

@mistercrunch
Copy link
Member

We need to fix the fact that filter_box is 12mb. I'm thinking for visualizations that use React, they shouldn't have to import it and should somehow pick it up from global, same goes for jquery and perhaps a set of other things.

We probably need some sort of global_imports package that all apps (explore, dashboard, profile, ...) would import and build, and that visualization would pick from without importing/bundling.

@williaster
Copy link
Contributor Author

I'm guessing the load time improvements have to do with the fact that some of the work can be started upfront while the bundles are downloading

Yes, and this is great from a user perspective because it doesn't block page render like it currently does. I think this will have the effect of making users feel like the page is loading much faster.

I'm thinking for visualizations that use React, they shouldn't have to import it and should somehow pick it up from global, same goes for jquery and perhaps a set of other things.

React is not that large (even smaller if we could actually upgrade to 16.0.0) and I can't tell if you mean literal globals (window.jquery) but we should move away from that pattern (and jquery in general, it's just syntactic sugar for JS and ideally we'd be using fetch not ajax) rather than embrace it.

It seems like the proper way to pull out "globally shared" code is using the webpack CommonChunksPlugin, if chunks share code it will pull them into a new chunk. I used this to create a separate chunk for all shared deck.gl code, and I also added it in a way that it should pull out all shared code into a separate chunk if it is imported by >=2 modules ... BUT this didn't appear to have any effect so the vis chunks must not really share that much code 🤷‍♀️ This is the new final webpack output (note the deckgl layer size decreases, and the new larger deckgl.fb9e56a3bf69cd1ce139.chunk.js):

Version: webpack 3.11.0
Time: 46756ms
                                                 Asset       Size                              Chunks                    Chunk Names
      deckgl/layers/grid.a8beccbf9f5b13e97f98.chunk.js    8.74 kB                                  32  [emitted]         deckgl/layers/grid
                  f4769f9bdb7466be65088239c12046d1.eot    20.1 kB                                      [emitted]
                 fa2772327f55d8198301fdb8bcfc8158.woff    23.4 kB                                      [emitted]
                  e18bbf611f2a2e43afc071aa2f4e1512.ttf    45.4 kB                                      [emitted]
                  89889688147bd7575d6327160d64e760.svg     109 kB                                      [emitted]
                nvd3_vis.7b1466ac696cd8d30467.chunk.js     6.8 MB                                   0  [emitted]  [big]  nvd3_vis
                  sankey.0da04cf564e3607b0313.chunk.js     268 kB                                   1  [emitted]  [big]  sankey
            paired_ttest.d9654f93c94179c43de4.chunk.js     304 kB                                   2  [emitted]  [big]  paired_ttest
             pivot_table.752772a0c72696357184.chunk.js    2.08 MB                                   3  [emitted]  [big]  pivot_table
    parallel_coordinates.0d0923b8adf4d520192a.chunk.js     204 kB                                   4  [emitted]         parallel_coordinates
               EventFlow.04abc2ccfab65027f920.chunk.js    2.57 MB                                   5  [emitted]  [big]  EventFlow
              big_number.39d33798fefe5e02632e.chunk.js    41.8 kB                                   6  [emitted]         big_number
                  markup.0ee56d948bd6cc1366fb.chunk.js    14.7 kB                                   7  [emitted]         markup
              filter_box.f76d5a45eff1c943db92.chunk.js      12 MB                                   8  [emitted]  [big]  filter_box
              time_table.49446835d78c8f19c439.chunk.js    1.51 MB                                   9  [emitted]  [big]  time_table
                  mapbox.b927c5a82390d9078f99.chunk.js    4.43 MB                                  10  [emitted]  [big]  mapbox
               partition.408cf680da8bcce8ad58.chunk.js     159 kB                                  11  [emitted]         partition
            deckgl/multi.bced534d9159ab18934d.chunk.js     512 kB  12, 13, 14, 29, 30, 31, 32, 33, 34  [emitted]  [big]  deckgl/multi
   deckgl/layers/scatter.ce1c712e5113e386fc6a.chunk.js     429 kB                                  13  [emitted]  [big]  deckgl/layers/scatter
deckgl/layers/screengrid.3619502e1991df96e5d5.chunk.js     400 kB                                  14  [emitted]  [big]  deckgl/layers/screengrid
                 heatmap.a587cf5f653617b1305a.chunk.js     108 kB                                  15  [emitted]         heatmap
                   table.48aed4719820c3e79b32.chunk.js    2.09 MB                                  16  [emitted]  [big]  table
             cal_heatmap.ed95b9fdabe40cb02ef1.chunk.js     348 kB                                  17  [emitted]  [big]  cal_heatmap
               world_map.3264a79e4259d761f4d0.chunk.js     941 kB                                  18  [emitted]  [big]  world_map
              word_cloud.477219c719efaab54f7c.chunk.js      45 kB                                  19  [emitted]         word_cloud
                    rose.92eafeac459006bad4bb.chunk.js    1.71 MB                                  20  [emitted]  [big]  rose
               histogram.d7ce608c93c52607b696.chunk.js    1.67 MB                                  21  [emitted]  [big]  histogram
                 treemap.f657e9f0a66f67c589ad.chunk.js      30 kB                                  22  [emitted]         treemap
                sunburst.5f07e304baedb2a39c0b.chunk.js    32.8 kB                                  23  [emitted]         sunburst
                 horizon.e8fba3db7283b0ab2024.chunk.js    18.9 kB                                  24  [emitted]         horizon
          directed_force.fcb6d26cd1fb2ae8add4.chunk.js    13.2 kB                                  25  [emitted]         directed_force
             country_map.c8e1683afb91b70582a1.chunk.js    16.7 kB                                  26  [emitted]         country_map
                   chord.d71d2fe59ff59c02121e.chunk.js    9.73 kB                                  27  [emitted]         chord
                  iframe.69c65c5f3fa42de0c8cf.chunk.js     1.8 kB                                  28  [emitted]         iframe
   deckgl/layers/polygon.3966937d1db2f1cdb4a1.chunk.js    6.75 kB                                  29  [emitted]         deckgl/layers/polygon
      deckgl/layers/path.47d1db5dd97d1e3f1535.chunk.js    7.42 kB                                  30  [emitted]         deckgl/layers/path
       deckgl/layers/hex.083fdc0e9eca06b50949.chunk.js    8.73 kB                                  31  [emitted]         deckgl/layers/hex
                448c34a56d699c29117adc64c43affeb.woff2      18 kB                                      [emitted]
   deckgl/layers/geojson.5e20b6a30b660329c019.chunk.js    12.1 kB                                  33  [emitted]         deckgl/layers/geojson
       deckgl/layers/arc.25cc2674046fd18c85a1.chunk.js    7.39 kB                                  34  [emitted]         deckgl/layers/arc
                 explore.69fb457561dcb2f21746.entry.js    25.6 MB                              35, 42  [emitted]  [big]  explore
                  sqllab.36c8988d9f36129a9183.entry.js    19.8 MB                              36, 42  [emitted]  [big]  sqllab
               dashboard.0a0c8aac20bdcac368aa.entry.js    15.4 MB                              37, 42  [emitted]  [big]  dashboard
                 profile.fa297a173d6a9ae45a79.entry.js    8.71 MB                              38, 42  [emitted]  [big]  profile
                addSlice.88e25db9764403cb2f42.entry.js    9.32 MB                              39, 42  [emitted]  [big]  addSlice
                 welcome.faa2156ccf68061b0f8a.entry.js    8.64 MB                              40, 42  [emitted]  [big]  welcome
                  deckgl.fb9e56a3bf69cd1ce139.chunk.js     8.7 MB                                  41  [emitted]  [big]  deckgl
                  common.32169c889bb0080def09.entry.js    3.99 MB                                  42  [emitted]  [big]  common
                   theme.489716a5e871d9900102.entry.js    6.15 kB                                  43  [emitted]         theme

The sad part is that this new deck.gl chunk doesn't load properly 😢 will keep digging a bit but may have to abandon it, or go talk to one of our web perf folks to see if they can help point me in the right direction. Sounds like there are many improvements for these exact thing in webpack v4, so we could consider upgrading to that (it will require new versions of node, so we'd need to specify engine: { node: '^8.9.4' } in the package.json, among other upgrades to webpack plugins, etc.)

@williaster
Copy link
Contributor Author

all right things are going to get crazier from here, I was advised to not waste time getting the CommonsChunksPlugin to work and instead move to the webpack 4 hotness 🔥. I have a working (locally) version of that change, so could do that in another PR or could add it to this mix. @mistercrunch do you have any preference on that? they're both non-trivial changes I think, webpack v4 will require "node": ">= 6.11.5 <7.0.0 || >= 8.9.0" which means chef/backend config changes (cc @john-bodley)

Just for fun-sies I tried the changes here on top of the webpack 4 change and we are going going to generate a crazy number of bundles (because it does basically all of the shared chunk-ing you described above). this is a good overview article.

@nathan-quinn
Copy link

nathan-quinn commented May 5, 2018

@williaster not sure if you are already familiar with this, but https://github.com/webpack-contrib/webpack-bundle-analyzer may be useful for deeper insights into the items impacting your bundle size here. Beyond the deck.gl stuff, seems like brace, mathjs, and moment (locale) are most impactful. There may be some opportunity to further optimize those, but would be interested in the webpack 4 upgrade stats before diving in on anything there. Happy to help on this effort once you decide on direction to take this with @mistercrunch.

This is the output I got from your branch with the above plugin:

superset_bundle_impact

@vibinsv09
Copy link

Hi,

Just wanted to check if we are planning to merge william's changes into superset?

Thanks

@williaster
Copy link
Contributor Author

williaster commented May 30, 2018

Sorry I've been slow getting back to this, was on vacation and now trying to wrap up dashboard v2 which is a monster. I hit an issue with the chunk urls that are generated when I use the webpack v4 splitChunks logic. I still think this is going to be a huge win for performance, I'll try to spend some time on it again next week unless anyone else wants to pull this branch and PR into it? (let me know and I can push my webpack v4 changes)

@williaster
Copy link
Contributor Author

back on it, I think I figured out the webpack 4 issue. will post back today or tomorrow with bundle analysis etc! 🚀

@williaster williaster force-pushed the chris--lazy-load-visualizations branch from b5d0216 to 5f92319 Compare June 8, 2018 00:26
@williaster
Copy link
Contributor Author

Bundles are looking good in terms of maximum splitting/re-use. These images don't fully capture the picture for entry points (e.g., explorer, dashboard, sqllab) because every entry point "runtime" now actually consists of multiple scripts (for maximum sharing) [templates were updated accordingly].

Rough empirical #s for DOM loaded, MB transferred, etc. match pretty close to what I posted above, but the number of requests is now higher. I'm not sure this really matters if empirical load time + total MB transferred are still good, though.

before
screen shot 2018-06-07 at 11 14 14 pm

screen shot 2018-06-07 at 11 14 05 pm

after webpack 4 + splitchunks
screen shot 2018-06-07 at 10 50 00 pm

screen shot 2018-06-07 at 11 14 50 pm

@mistercrunch
Copy link
Member

Curious as to what happens if you pick multiple visualizations to have same webpackChunkName (trying to reduce the numder of chunks). Say all of the deckgl related ones or all of the ones that are just a few kbs already.

"webpack-manifest-plugin": "1.3.2",
"webworkify-webpack": "2.1.0"
"url-loader": "^1.0.1",
"webpack": "^4.6.0",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh noice! I tried to do this in the past and failed :)

Copy link
Contributor Author

@williaster williaster Jun 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there were several loaders that had to be swapped out to support it 👍 took a while to figure it out!

@mistercrunch
Copy link
Member

Very excited to see this. Bundle sizes prior to this PR were starting to be quite embarrassing.

@vibinsv09
Copy link

Wow, this is super cool. It will improve user experience for lot of superset users. Thanks @williaster for all the hard work 👍

@williaster williaster force-pushed the chris--lazy-load-visualizations branch from daf5e5d to 7a49d26 Compare June 8, 2018 18:04
@williaster
Copy link
Contributor Author

williaster commented Jun 8, 2018

@mistercrunch re the same chunk for deckgl, I'm not sure that using the same chunk name is the best way to fix that given the options that the SplitChunks plugin supports. For example you can specify a minSize criteria to be spun into a new chunk (default = 30kb), maxAsyncRequests, or maxInitialRequests.

My inclination is that we should see what happens with this since it's already a big change, and then tweak the optimizations from there? wdyt?

Rebased on latest master just now and tried to test a lot myself locally. Will try to test on a staging box but if you could pull it and test more extensively with deck.gl that'd be super helpful! Unless we see any issues I think it's ready to merge!

@codecov-io
Copy link

codecov-io commented Jun 8, 2018

Codecov Report

Merging #4727 into master will increase coverage by <.01%.
The diff coverage is 84.61%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #4727      +/-   ##
==========================================
+ Coverage   77.46%   77.47%   +<.01%     
==========================================
  Files          44       44              
  Lines        8730     8737       +7     
==========================================
+ Hits         6763     6769       +6     
- Misses       1967     1968       +1
Impacted Files Coverage Δ
superset/viz.py 81.29% <100%> (ø) ⬆️
superset/__init__.py 73.1% <81.81%> (+0.78%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d6846d9...6a22d90. Read the comment docs.

@mistercrunch
Copy link
Member

Very nice. This seems to be a huge step forward, we can tweak things later as needed.

@williaster
Copy link
Contributor Author

williaster commented Jun 8, 2018

These are the final set of 3x empirical tests per example dashboard before and after, on non-minimized code with hard refresh/no caching. They look even better than above!

  • average total payload decreased by 10.1 MB (-71% change)
  • DOM content load time decreased 8.7s (-78% change)
  • Page total load time decreased 7.9s (-48% change)
  • the average # requests increased by 30

@mistercrunch shall we merge this? 🚀

  Total payload (MB)    
Dashboard Before After  Delta
Births example 12.5 2.2 -10.3 MB
World data example 12.5 2.6 -9.9 MB
Misc charts example 14.6 4.3 -10.3 MB
Deck gl 17.2 7.4 -9.8 MB
  DOM content loaded (seconds)    
Dashboard Before After Delta
Births example 11.52 2.28 -9.24 s
World data example 10.77 2.73 -8.04 s
Misc charts example 10.59 2.54 -8.05 s
Deck gl 11.69 2.17 -9.5 s
  Total time [all requests incl async] (sec)    
Dashboard Before After Delta
Births example 16.63 7.96 -8.67 s
World data example 13.17 6.76 -6.41 s
Misc charts example 17.58 10.78 -6.80 s
Misc charts example w Deck gl 18.43 8.85 -9.58 s
  Requests (count)    
Dashboard Before After Delta
Births example 32 63 +31
World data example 29 71 +42
Misc charts example 46 74 +28
Deck gl (high bc of map tiles) 196 217 +21

@williaster williaster force-pushed the chris--lazy-load-visualizations branch from ea5f147 to 6a22d90 Compare June 13, 2018 20:24
@williaster
Copy link
Contributor Author

all right tests look good, should we merge @mistercrunch @graceguo-supercat @john-bodley ?

@mistercrunch
Copy link
Member

Green light on my side

@williaster
Copy link
Contributor Author

all righty 🤞🤞🤞

@williaster williaster merged commit de0aaf4 into apache:master Jun 15, 2018
@williaster williaster deleted the chris--lazy-load-visualizations branch June 15, 2018 01:29
john-bodley pushed a commit to john-bodley/superset that referenced this pull request Jun 15, 2018
* [webpack] setup lazy loading for all visualizations

* [lazy-load] push renderVis function to <Chart /> state

* no mapbox token

* [lazy loading] use native webpack import func to fix chunk names, add babel-plugin-syntax-dynamic-import, fix rebase bug.

* fix geojson import, undefined t, and fix async css bug

* [lazy load] actually add babel-plugin-syntax-dynamic-import

* [webpack] working dev version of webpack v4

* [webpack 4] fix url issues, use mini-css-extract-plugin and webpack-assets-manifest plugins

* [webpack 4] use splitchunks for all files, update templates to multi-file entrypoints

* [webpack 4] multiple theme entry files for markup vis css, don't uglify mapbox

* [webpack 4] lint python manifest changes, update yarn lock.

* [webpack 4] fix tests with babel-plugin-dynamic-import-node

* [webpack 4] only use 'dynamic-import-node' plugin in tests, update <Chart /> vis promise when vis type changes

* [webpack 4] clean up package.json and yarn.lock after rebase

* [webpack 4] lint?

* [webpack 4] lint for real

(cherry picked from commit de0aaf4)
williaster added a commit that referenced this pull request Jun 16, 2018
john-bodley pushed a commit that referenced this pull request Jun 16, 2018
* Revert "[explore] fix autocomplete on verbose names (#5204)"

This reverts commit d5ebc43.

* Revert "[webpack] setup lazy loading for all visualizations (#4727)"

This reverts commit de0aaf4.
@williaster williaster restored the chris--lazy-load-visualizations branch June 18, 2018 21:33
timifasubaa pushed a commit to airbnb/superset-fork that referenced this pull request Jul 25, 2018
* [webpack] setup lazy loading for all visualizations

* [lazy-load] push renderVis function to <Chart /> state

* no mapbox token

* [lazy loading] use native webpack import func to fix chunk names, add babel-plugin-syntax-dynamic-import, fix rebase bug.

* fix geojson import, undefined t, and fix async css bug

* [lazy load] actually add babel-plugin-syntax-dynamic-import

* [webpack] working dev version of webpack v4

* [webpack 4] fix url issues, use mini-css-extract-plugin and webpack-assets-manifest plugins

* [webpack 4] use splitchunks for all files, update templates to multi-file entrypoints

* [webpack 4] multiple theme entry files for markup vis css, don't uglify mapbox

* [webpack 4] lint python manifest changes, update yarn lock.

* [webpack 4] fix tests with babel-plugin-dynamic-import-node

* [webpack 4] only use 'dynamic-import-node' plugin in tests, update <Chart /> vis promise when vis type changes

* [webpack 4] clean up package.json and yarn.lock after rebase

* [webpack 4] lint?

* [webpack 4] lint for real
timifasubaa pushed a commit to airbnb/superset-fork that referenced this pull request Jul 25, 2018
…5219)

* Revert "[explore] fix autocomplete on verbose names (apache#5204)"

This reverts commit d5ebc43.

* Revert "[webpack] setup lazy loading for all visualizations (apache#4727)"

This reverts commit de0aaf4.
wenchma pushed a commit to wenchma/incubator-superset that referenced this pull request Nov 16, 2018
* [webpack] setup lazy loading for all visualizations

* [lazy-load] push renderVis function to <Chart /> state

* no mapbox token

* [lazy loading] use native webpack import func to fix chunk names, add babel-plugin-syntax-dynamic-import, fix rebase bug.

* fix geojson import, undefined t, and fix async css bug

* [lazy load] actually add babel-plugin-syntax-dynamic-import

* [webpack] working dev version of webpack v4

* [webpack 4] fix url issues, use mini-css-extract-plugin and webpack-assets-manifest plugins

* [webpack 4] use splitchunks for all files, update templates to multi-file entrypoints

* [webpack 4] multiple theme entry files for markup vis css, don't uglify mapbox

* [webpack 4] lint python manifest changes, update yarn lock.

* [webpack 4] fix tests with babel-plugin-dynamic-import-node

* [webpack 4] only use 'dynamic-import-node' plugin in tests, update <Chart /> vis promise when vis type changes

* [webpack 4] clean up package.json and yarn.lock after rebase

* [webpack 4] lint?

* [webpack 4] lint for real
wenchma pushed a commit to wenchma/incubator-superset that referenced this pull request Nov 16, 2018
…5219)

* Revert "[explore] fix autocomplete on verbose names (apache#5204)"

This reverts commit d5ebc43.

* Revert "[webpack] setup lazy loading for all visualizations (apache#4727)"

This reverts commit de0aaf4.
@mistercrunch mistercrunch added 🏷️ bot A label used by `supersetbot` to keep track of which PR where auto-tagged with release labels 🚢 0.26.0 labels Feb 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🏷️ bot A label used by `supersetbot` to keep track of which PR where auto-tagged with release labels 🚢 0.26.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants