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

Support replacing resources #655

Open
mjclawar opened this issue Mar 19, 2019 · 4 comments
Open

Support replacing resources #655

mjclawar opened this issue Mar 19, 2019 · 4 comments

Comments

@mjclawar
Copy link
Contributor

Background

As raised in plotly/dash-core-components#462, some of the default included JS libraries are not the latest/much larger than needed by some users. For example, there is no need to include the full plotly.js library for an application only using a scatter plot.

Potential implementation

@alexcjohnson laid out a potential function that would allow a user to swap out a resource on a per-namespace basis, dash.replace_resource: plotly/dash-core-components#462 (comment)

dash.replace_resource(dcc, 'plotly.js', {'external_url': 'https://cdn.plot.ly/plotly-basic-1.44.4.js'})
# or even just put the new file in your assets/ so it's loaded automatically,
# and tell us to ignore the default one:
dash.replace_resource(dcc, 'plotly.js', None)

This issue would need to cover implementing this function, which might look something like below:

def replace_resource(namespace, resource_name, replacement_resource):
    """Replace the metadata for resource_name in namespace with replacement_resource"""
    def _process_resource(resource):
        if 'resource_name' in resource and resource['resource_name'] == resource_name:
            return replacement_resource
        else:
            return resource

    namespace._js_dist = [
        _process_resource(r) for r in namespace._js_dist
    ]

replace_resource(
    namespace=dcc,
    resource_name='plotly.js',
    replacement_resource={
        'external_url': 'https://cdn.plot.ly/plotly-cartesian-1.45.2.min.js',
        'asset_path': 'plotly-cartesian-1.45.2.min.js',
        'filepath': 'assets/plotly-cartesian-1.45.2.min.js',
    }
)

In order to support this generically, future Dash component packages would need to include a resource_name field when specifying, e.g., _js_dist. Alternatively, it could also be set up using a lambda that returns True/False (i.e., a function passed to a filter) given a generic resource specification.

There's likely a better way to handle this using the Resources objects for both css and for js

@Jeffrey9130
Copy link

Thanks for this post. However, I think the point is how to make such a minimum javascript.

@alexcjohnson
Copy link
Collaborator

If you're talking about specifically how to make a smaller plotly.js bundle, first take a look at the ones already provided: https://github.com/plotly/plotly.js/tree/master/dist#partial-bundles

If there isn't already one that meets your needs, there are ways to make your own - see eg https://community.plot.ly/t/modularizing-plotly/6029

The subject of this issue is, once you have the new bundle, how to cleanly plumb it into dash. But if you're looking for a quick-and-dirty way to do it, you can just put the new bundle somewhere convenient, and after importing dash_core_components modify its _js_dist[0] to point to the new bundle.

@Jeffrey9130
Copy link

Greate, thanks for your reply! And looking forward to the dynamic loading of dcc in future.

@alexcjohnson
Copy link
Collaborator

For plotly.js, this issue was resolved a different way when we introduced async resources - we don't load plotly.js for dcc.Graph until we're actually trying to render a graph, and at that point we first check to see if one is present on window.Plotly. What that means is you can simply add your own version of plotly.js to your assets folder. That bundle will load synchronously and we'll automatically use it and skip even trying to load the built-in version.

We're planning to do the same for markdown code highlighting plotly/dash-core-components#643. Something like dash.replace_resource may still be useful for cases that haven't migrated to async, though I'm a bit wary of confusing people by making two different methods that need to be used depending on the particular resource you're replacing. So for the time being I'd like to keep handling this case-by-case following the plotly.js pattern.

I will leave this issue open though even after we do this for highlight.js. If other cases come up where resource replacement would be useful - particularly if it's in 3rd-party dash components - please comment here.

also: https://github.com/plotly/dash-docs/issues/723

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