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

Async JavaScript Lazy Loading #899

Merged
merged 70 commits into from
Oct 21, 2019
Merged

Async JavaScript Lazy Loading #899

merged 70 commits into from
Oct 21, 2019

Conversation

Marc-Andre-Rivet
Copy link
Contributor

@Marc-Andre-Rivet Marc-Andre-Rivet commented Aug 30, 2019

Realted to component-specific implementations:
plotly/dash-core-components#616
plotly/dash-table#554

Component loading state is exposed on the component class / function.

The renderer evals the loading state of all component types on layout changes (possibility of new component types).

notifyObserver uses this state to decide whether to go forward with callbacks or wait.

Because of callback chains and multi-input & state parameters, it's not possible to only depend on the state of the current component. This may result in more overhead vs. checking out only the state of the (1) components in the dependency graph, (2) components impacted by the callback's dependency chain, but it feels like a good first implementation.


Dash now supports a new attribute on _js_dist assets: async.
async can't be used with dynamic and is instead used to determine at runtime if an asset should be eager or lazy. Takes three values: True, eager, lazy.

This is necessary to cover cases like the dcc.Graph plotly.js dependency -- we need window.Plotly to be set automatically if eagerly loaded, for the value to already be set after DOM render, for legacy purposes.


  • Special webpack plugin to redirect Dash dynamic imports correctly, byt taking into account the Dash path structure webpack-dash-dynamic-import

  • Common code for all async components to use to make the renderer aware of their 'aysnc' nature dash-component-plugins -- this was made more general with thoughts of adding other plugins here (e.g. the private layout could be abstracted here for components that need it)

  • Test Dash resolution of async with different values for eager_loading and force_eager_loading flags

  • Validate lazy requests are not loaded right away (e.g. DOM comparison)

  • Test setAppIsReady with shim -- make sure callbacks are blocked


Additional performance work that could be done here or spin off new PRs:

  • Investigate the possibility of dynamically deciding to be lazy/eager/prefetch/preload (determining the mechanism by which dash would provide the info is out of scope - pure FE sub-poc)
  • Chunk the renderer into two parts: (1) initiate layout request to server, (2) get the react/redux code -- one can be made as small as possible and put in the <head>, the other can stay were it is atm
  • Load the renderer with script tags in <head> instead of <body> -- wait for DOM from there
  • More aggressive chunking to parallelize js processing / download
  • Shared core-js in renderer, externalized for all other components (renderer to pull all instead of usage) -- need to coordinate targets
  • in prod, use attribute ?v=x.y.z with the version instead of the timestamp -- keep using the timestamp for debug
  • In dcc, make additional components lazy
  • apply a different priority to css and other resources (not sure there's something to be done here yet)

In order of priority / potential gains, stopping cache busting in production code is probably the biggest (and easiest) gain we can get.

@Marc-Andre-Rivet Marc-Andre-Rivet marked this pull request as ready for review September 24, 2019 19:13
@Marc-Andre-Rivet Marc-Andre-Rivet changed the title Experiment - Wait for lazy component before updating props Renderer - Support for lazy components Sep 24, 2019
@Marc-Andre-Rivet Marc-Andre-Rivet changed the title Renderer - Support for lazy components Renderer - Support for async components Sep 24, 2019
@Marc-Andre-Rivet
Copy link
Contributor Author

Marc-Andre-Rivet commented Oct 11, 2019

devtools were using dcc.Graph for prop type errors which caused problems - started using the DataTable instead as it (a) is not async, (b) has the same type of complex / deeply nested props as the graph

13e274e

@Marc-Andre-Rivet
Copy link
Contributor Author

added a shimmed test for notifyObservers- isAppReady 7c3edaa

Copy link
Collaborator

@alexcjohnson alexcjohnson left a comment

Choose a reason for hiding this comment

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

Looks great! I have no further comments, let's do it! 💃 🐎 🚀

@Marc-Andre-Rivet Marc-Andre-Rivet merged commit b31c447 into dev Oct 21, 2019
@Marc-Andre-Rivet Marc-Andre-Rivet deleted the exp-dynamic branch October 21, 2019 16:21
@chriddyp chriddyp changed the title Async support and general performance work Async JavaScript bundle loading Apr 6, 2020
@chriddyp chriddyp changed the title Async JavaScript bundle loading Async JavaScript Lazy Loading Apr 6, 2020
HammadTheOne pushed a commit to HammadTheOne/dash that referenced this pull request May 28, 2021
…ash-4.17.21

Bump lodash from 4.17.10 to 4.17.21
HammadTheOne pushed a commit that referenced this pull request Jul 23, 2021
…17.21

Bump lodash from 4.17.10 to 4.17.21
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

Successfully merging this pull request may close these issues.

2 participants