Skip to content

Commit 1fe6f11

Browse files
committed
make embedded plotly.js as opt-in via feature flag
Signed-off-by: Andrei Gherghescu <[email protected]>
1 parent e3052a5 commit 1fe6f11

File tree

8 files changed

+47
-113
lines changed

8 files changed

+47
-113
lines changed

Diff for: CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
55

66
## [0.10.0] - 2024-xx-xx
77
### Added
8-
- [[#231](https://github.com/plotly/plotly.rs/pull/231)] Added new `plotly_noembed` feature to reduce binary sizes by not embedding `plotly.min.js`.
8+
- [[#231](https://github.com/plotly/plotly.rs/pull/231)] Added new `plotly_embed_js` feature to reduce binary sizes by not embedding `plotly.min.js` in the library unless explicitly enabled via the feature flag. Deprecates `use_local_plotly` in favor of explicit opt-in via the feature flag and introduce method `use_cdn_plotly` to allow users to use CDN version even behind the `plotly_embed_js` feature flag.
99

1010
## [0.9.1] - 2024-09-06
1111
### Added

Diff for: README.md

+10-5
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,12 @@ plot.add_trace(trace);
7878
plot.write_html("out.html");
7979
```
8080

81-
By default, the Plotly JavaScript library will be included via CDN, which results in a smaller filesize, but slightly slower first load as the JavaScript library has to be downloaded first. To instead embed the JavaScript library (several megabytes in size) directly into the HTML file, the following can be done:
81+
By default, the Plotly JavaScript library will be included via CDN, which results in a smaller filesize, but slightly slower first load as the JavaScript library has to be downloaded first. To instead embed the JavaScript library (several megabytes in size) directly into the HTML file, the library must be compiled with the feature flag `plotly_embed_js`. Once enabled, by default the JavaScript library is directly embedded in the generated HTML file. It is still possible to use the CDN version, by using the `use_cdn_plotly` method.
8282

8383
```rust
8484
// <-- Create a `Plot` -->
8585

86-
plot.use_local_plotly();
86+
plot.use_cdn_plotly();
8787
plot.write_html("out.html");
8888
```
8989

@@ -201,10 +201,15 @@ Adds trait implementations so that `image::RgbImage` and `image::RgbaImage` can
201201

202202
Adds support for creating plots directly using [ndarray](https://github.com/rust-ndarray/ndarray) types.
203203

204-
### `plotly_noembed`
204+
### `plotly_embed_js`
205205

206-
This feature can be used to reduce the binary size by not embedding `plotly.min.js`. This requires the use of the CDN version,
207-
and disables the `use_local_plotly` method.
206+
By default, the CDN version of `plotly.js` is used in the library and in the generated HTML files. This feature can be used to opt in for embedding `plotly.min.js` in the generated HTML files. The benefit is that the plot will load faster in the browser.
207+
208+
However, there are two downsides of using this feature flag, one is that the resulting html will be much larger, as a copy of the `plotly.min.js` library is embedded in each HTML file. The second, more relevant, is that a copy of the `plotly.min.js` library needs to be compiled in the `plotly-rs` library itself which increases the size by approx `3.5 Mb`.
209+
210+
When the feature is enabled, users can still opt in for the CDN version by using the method `use_cdn_plotly`.
211+
212+
Note that when using `Plot::to_inline_html()`, it is assumed that the `plotly.js` library is already in scope within the HTML file, so enabling this feature flag will have no effect.
208213

209214
### `wasm`
210215

Diff for: plotly/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ exclude = ["target/*"]
1717
kaleido = ["plotly_kaleido"]
1818
plotly_ndarray = ["ndarray"]
1919
plotly_image = ["image"]
20-
plotly_noembed = []
20+
plotly_embed_js = []
2121
wasm = ["getrandom", "js-sys", "wasm-bindgen", "wasm-bindgen-futures"]
2222
with-axum = ["rinja/with-axum", "rinja_axum"]
2323

Diff for: plotly/src/plot.rs

+30-41
Original file line numberDiff line numberDiff line change
@@ -11,40 +11,20 @@ use serde::Serialize;
1111

1212
use crate::{Configuration, Layout};
1313

14-
#[cfg(not(feature = "plotly_noembed"))]
1514
#[derive(Template)]
1615
#[template(path = "plot.html", escape = "none")]
1716
struct PlotTemplate<'a> {
1817
plot: &'a Plot,
19-
remote_plotly_js: bool,
18+
plotly_js_source: String,
2019
}
2120

22-
#[cfg(feature = "plotly_noembed")]
23-
#[derive(Template)]
24-
#[template(path = "plot_noembed.html", escape = "none")]
25-
struct PlotTemplate<'a> {
26-
plot: &'a Plot,
27-
}
28-
29-
#[cfg(not(feature = "plotly_noembed"))]
3021
#[derive(Template)]
3122
#[template(path = "static_plot.html", escape = "none")]
3223
#[cfg(not(target_family = "wasm"))]
3324
struct StaticPlotTemplate<'a> {
3425
plot: &'a Plot,
3526
format: ImageFormat,
36-
remote_plotly_js: bool,
37-
width: usize,
38-
height: usize,
39-
}
40-
41-
#[cfg(feature = "plotly_noembed")]
42-
#[derive(Template)]
43-
#[template(path = "static_plot_noembed.html", escape = "none")]
44-
#[cfg(not(target_family = "wasm"))]
45-
struct StaticPlotTemplate<'a> {
46-
plot: &'a Plot,
47-
format: ImageFormat,
27+
plotly_js_source: String,
4828
width: usize,
4929
height: usize,
5030
}
@@ -202,32 +182,26 @@ pub struct Plot {
202182
#[serde(rename = "config")]
203183
configuration: Configuration,
204184
#[serde(skip)]
205-
#[cfg(not(feature = "plotly_noembed"))]
206-
remote_plotly_js: bool,
185+
plotly_js_source: String,
207186
}
208187

209188
impl Plot {
210189
/// Create a new `Plot`.
211190
pub fn new() -> Plot {
212191
Plot {
213192
traces: Traces::new(),
214-
#[cfg(not(feature = "plotly_noembed"))]
215-
remote_plotly_js: true,
193+
plotly_js_source: Self::plotly_js_source(),
216194
..Default::default()
217195
}
218196
}
219197

220-
/// This option results in the plotly.js library being written directly in
221-
/// the html output. The benefit is that the plot will load faster in
222-
/// the browser and the downside is that the resulting html will be much
223-
/// larger.
224-
///
225-
/// Note that when using `Plot::to_inline_html()`, it is assumed that the
226-
/// `plotly.js` library is already in scope, so setting this attribute
227-
/// will have no effect.
228-
#[cfg(not(feature = "plotly_noembed"))]
229-
pub fn use_local_plotly(&mut self) {
230-
self.remote_plotly_js = false;
198+
/// Switch to CDN `plotly.js` in the generated HTML instead of the default
199+
/// local `plotly.js` version. Method is only available when the feature
200+
/// `plotly_embed_js` is enabled since without this feature the default
201+
/// version used is always the CDN version.
202+
#[cfg(feature = "plotly_embed_js")]
203+
pub fn use_cdn_plotly(&mut self) {
204+
self.plotly_js_source = Self::cdn_plotly_js();
231205
}
232206

233207
/// Add a `Trace` to the `Plot`.
@@ -445,8 +419,7 @@ impl Plot {
445419
fn render(&self) -> String {
446420
let tmpl = PlotTemplate {
447421
plot: self,
448-
#[cfg(not(feature = "plotly_noembed"))]
449-
remote_plotly_js: self.remote_plotly_js,
422+
plotly_js_source: self.plotly_js_source.clone(),
450423
};
451424
tmpl.render().unwrap()
452425
}
@@ -456,8 +429,7 @@ impl Plot {
456429
let tmpl = StaticPlotTemplate {
457430
plot: self,
458431
format,
459-
#[cfg(not(feature = "plotly_noembed"))]
460-
remote_plotly_js: self.remote_plotly_js,
432+
plotly_js_source: self.plotly_js_source.clone(),
461433
width,
462434
height,
463435
};
@@ -472,6 +444,23 @@ impl Plot {
472444
tmpl.render().unwrap()
473445
}
474446

447+
fn plotly_js_source() -> String {
448+
if cfg!(feature = "plotly_embed_js") {
449+
Self::local_plotly_js()
450+
} else {
451+
Self::cdn_plotly_js()
452+
}
453+
}
454+
455+
fn local_plotly_js() -> String {
456+
let local_plotly = include_str!("../templates/plotly.min.js");
457+
format!("<script type=\"text/javascript\">{}</script>", local_plotly).to_string()
458+
}
459+
460+
fn cdn_plotly_js() -> String {
461+
r##"<script src="https://cdn.plot.ly/plotly-2.12.1.min.js"></script>"##.to_string()
462+
}
463+
475464
pub fn to_json(&self) -> String {
476465
serde_json::to_string(self).unwrap()
477466
}

Diff for: plotly/templates/plot.html

+2-5
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,8 @@
88
<body>
99
<div>
1010
<script src="https://cdn.jsdelivr.net/npm/[email protected]/es5/tex-svg.js"></script>
11-
{% if remote_plotly_js -%}
12-
<script src="https://cdn.plot.ly/plotly-2.12.1.min.js"></script>
13-
{% else -%}
14-
<script type="text/javascript">{% include "plotly.min.js" %}</script>
15-
{% endif -%}
11+
12+
{{plotly_js_source}}
1613

1714
<div id="plotly-html-element" class="plotly-graph-div" style="height:100%; width:100%;"></div>
1815

Diff for: plotly/templates/plot_noembed.html

-22
This file was deleted.

Diff for: plotly/templates/static_plot.html

+3-6
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,8 @@
66
<body>
77
<div>
88
<script src="https://cdn.jsdelivr.net/npm/[email protected]/es5/tex-mml-chtml.js"></script>
9-
{% if remote_plotly_js -%}
10-
<script src="https://cdn.plot.ly/plotly-2.12.1.min.js"></script>
11-
{% else -%}
12-
<script type="text/javascript">{% include "plotly.min.js" %}</script>
13-
{% endif -%}
9+
10+
{{plotly_js_source}}
1411

1512
<div id="plotly-html-element" hidden></div>
1613
<img id="plotly-img-element"></img>
@@ -33,4 +30,4 @@
3330
</script>
3431
</div>
3532
</body>
36-
</html>
33+
</html>

Diff for: plotly/templates/static_plot_noembed.html

-32
This file was deleted.

0 commit comments

Comments
 (0)