Performance

posit::conf(2023)
Shiny in Production: Tools & Techniques

Performance Agenda

  • Profiling your Shiny app with {profvis}
  • Lightning-quick data loading/querying with {arrow} & .parquet files
  • Asynchronous processes with {crew}

{profvis}: an R package for profiling R code
(including Shiny apps)

What is {profvis}?

R package for visualizing how (and how fast/slow) your R code runs

{profvis} website

Working with {profvis} & {golem}

Our dev/run_dev.R script is where we can profile our app interactively.

options(golem.app.prod = FALSE)

golem::detach_all_attached()

golem::document_and_reload()

run_app()

Working with {profvis} & {golem}

Our dev/run_dev.R script is where we can profile our app interactively.

options(golem.app.prod = FALSE)

golem::detach_all_attached()

golem::document_and_reload()

profvis::profvis({
  print(run_app())
})

Demo!

Your Turn: Exercise 1

Profile the LEGO Bricks app!

  • Details
  • Posit Cloud project: Performance Exercise 1
05:00

{arrow} & the .parquet file format

What are .parquet files?

  • .parquet is a columnar storage format
  • .parquet files not only store data, but they also store metadata about your data (i.e., data types for each column, number of rows in the file, etc.)
  • Smaller files
  • Faster read speed

What is the {arrow} R package?

  • Part of the larger Apache Arrow project
  • Connect to your data with {arrow}…
  • … and query it with {dplyr}

Apache Arrow Homepage

Shiny + Arrow Article

Code-Along

Using .parquet in the LEGO Bricks Shiny app

  • Details
  • Posit Cloud project: Performance Exercise 1

Async Processing

Single (threaded) Line

  • A single R process managing the different tasks in a Shiny application
  • Executed one-by-one

Should I care? It Depends …

If you are the only user for a quick and efficient app: Likely not!

Crowd Pleaser

Multiple users accessing the app concurrently:

  • Single-threaded R process serving multiple users in typical deployments

Asynchronous Processing (circa 2018)

📦 {promises}

Handle objects representing the (eventual) result of an async operation

📦 {future}

Launch tasks without blocking current R session

Introducing {crew}

A distributed worker launcher for asynchronous tasks

  • Extends use of the mirai task scheduler to multiple computing backends
  • Central controller object manages tasks (scales on fly)
  • Supports multiple controller groups for specialized worker types
  • Fits nicely with {targets} and …

Watch-Along

Using {crew} inside a Shiny application:

Setting up for Success

  1. Create functions for long-running tasks
  2. Create multiple reactiveVal objects for bookkeeping
  3. Set up a {crew} controller
  4. Establish an event-driven push of task to the controller with monitoring of worker status

Code-Along

Asynchronous calls of a model prediction API.

  • Details
  • Posit Cloud project: Performance Code-along 2