Skip to content

Commit 0fa0157

Browse files
committed
More on caching
1 parent dfd4795 commit 0fa0157

File tree

1 file changed

+14
-19
lines changed

1 file changed

+14
-19
lines changed

action-graphics.Rmd

+14-19
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,9 @@ In real cases, you'd use more complicated expressions in the `width` and `height
249249

250250
## Cached plots
251251

252-
If you have an app with complicated plots that take a while to draw, and the same plots are seen by many people, you can get some major performance advantages by used plot caching. This is most a matter of changing `renderPlot()` to `renderCachedPlot()`, but there are a few other issues that you need to consider. Here we'll focus on the big picture; full the full details you can refer to the [Shiny website](https://shiny.rstudio.com/articles/plot-caching.html).
252+
If you have an app with complicated plots that take a while to draw, and the same plots are seen by many people, you can get some major performance advantages by used plot caching. This is most a matter of changing `renderPlot()` to `renderCachedPlot()`, but there are a few other issues that you need to consider.
253+
254+
The following app uses `renderCachedPlot()` to speed up the rendering of a large scatterplot of the diamonds dataset. If you run it yourself, you'll notice the first time you show each plot, it takes a noticeable fraction of a second to render (because it has to draw \~50,000 points). But if you re-show that same plot, it appears instantly (because it retrieves the plot from the cache).
253255

254256
```{r}
255257
ui <- fluidPage(
@@ -267,31 +269,26 @@ server <- function(input, output, session) {
267269
}
268270
```
269271

270-
You can use the plot cache with what you now know. But there are three topics that will Three important topics we need to cover:
272+
You'll notice one important difference between `renderPlot()` and `renderCachedPlot()`: a cached plot also needs a `cacheKeyExpr`, an expression that uniquely identifys each plot. This is the most important argument to `renderCachedPlot()` and we'll discuss it in more detail below. We'll also cover two other important arguments:
271273

272-
- The cache key, which determines when the plot needs to be recomputed.
273274
- The sizing policy, which ensures that plot is shared even when the sizes are a little different.
274275
- The scoping, which controls how frequently the cache is used.
275276

276-
### Cache key
277+
Here we'll focus on the big picture; full the full details you can refer to the [Shiny website](https://shiny.rstudio.com/articles/plot-caching.html).
277278

278-
But you also need to supply a `cacheKeyExpr`. This is some code that returns an object that basically represents the "state" of the plot; whenever that value changes, the plot will be recomputed.
279+
### Cache key
279280

280-
Best to keep it as simple as possible - should be a list of vectors.
281+
The `cacheKeyExpr` is the most important argument to `renderCachedPlot()` because it determines when the cache can be used. It should return an object (typically a list of simple vectors) that determins the "state" of the plot; whenever that value is the same as a previous value, a cached plot will be used.
281282

282-
- Input parameters.
283-
- Dataset reactive. Avoid using very large datasets as a cache key - it will take some time
284-
- Timestamp. `proc.time()[[3]] %/% 3600`
283+
Typically the cache key will be a list of input parameters or simple reactives. It is possible to use a dataset as a cache key, but you should avoid using very large datasets because it take some time to reduce and compare them across runs. If you want a plot to invalidate periodically, you can use something like`proc.time()[[3]] %/% 3600`. This is value will change once per hour (3600 s). You can adjust to any constant.
285284

286-
Also includes id, and plot size. Also implicitly depends on the current user.
285+
The cache is also affected by the plot size, and the cache scope, as described below.
287286

288287
### Sizing policy
289288

290-
Normally plots are rendered to the exact size needed. But that's not very useful for caching: if everyone has a slightly different sized plot, then the cache will never be used. `renderCachePlot()` resolves this problem by only caching plots with a fixed sizes and then resizing as needed.
289+
Normally plots are rendered to the exact size needed by the app. But doesn't work very well for caching, because even a pixel difference would require that the plot be re-rendering. Instead, `renderCachePlot()` caches plots with fixed sizes and then resizing as needed. Generally, you won't need to worry about this as the defaults use an exponential rounding strategy determined by the `sizingPolicy` argument. You can see more details in the `sizeGrowthRatio()` documentation.
291290

292-
It uses an exponential rounding strategy determined by the `sizingPolicy` argument. It's unlikely that you'll need to tweak this, but if you do, see the `sizeGrowthRatio()` for details.
293-
294-
Another option worth considering is setting the plots to a fixed size by setting the `width` argument to `plotOutput` to a fixed unit like `"400px"` (the default `height` is already fixed). That will give you the best cache performance because every plot will have the same size.
291+
You may also want to consider setting cached plots to a fixed size in `plotOutput()`. The default value for `height` is already fixed at `"400px"`, but `width` argument is `"100%"`. If you set `width = "400px"` every plot will be exactly the same size, and you'll get the best cache performance.
295292

296293
### Scoping
297294

@@ -302,16 +299,12 @@ By default, the plot cache is stored in memory, and shared across all users of t
302299
- `cache = diskCache(...)`: shares across multiple users, multiple\
303300
processes, and app-restarts. Beware that restarting the app will no longer clear the cache, so if you change the plotting code, you'll also need to manually reset the cache by deleting the directory.
304301

305-
It's also possible to store in a database, or right your own backend. See <https://shiny.rstudio.com/articles/plot-caching.html#can-i-write-my-own-caching-backend> for more details.
306-
307-
The default memory cache size of 10 MB can hold plenty of plots -- a cached plot object is typically between 50 and 250 kB. You can override with `shinyOptions(cache = memoryCache(size = 20e6))`.
302+
It's also possible to store in a database, or right your own backend. See <https://shiny.rstudio.com/https://shiny.rstudio.com/articles/plot-caching.html> for more details.
308303

309304
## Images
310305

311306
If you need to display images that you already have saved on disk. These might come from an external source (maybe a directory of photographs), or perhaps you've generated them with another package (e.g. a 3d scene with`rgl::rgl.snapshot()`).
312307

313-
<https://shiny.rstudio.com/articles/images.html>
314-
315308
Unlike `renderPlot()`, `renderImage()` must return a list:
316309

317310
- `src`: (local) path to the image file.
@@ -322,6 +315,8 @@ Unlike `renderPlot()`, `renderImage()` must return a list:
322315

323316
- `class`, `alt` will be added as attributes to the `<img>` tag.
324317

318+
<https://shiny.rstudio.com/articles/images.html>
319+
325320
### Static images
326321

327322
Sample app shows directory full of files.

0 commit comments

Comments
 (0)