Optimal usage of server.R and global.R

Unlike UI.R, the core of the code in server.R and global.R does not normally differ significantly from normal R code. The mean calculations, statistical functions, and so on are obtained exactly in the same way within a Shiny application as in any other script.

However, in the context where code gets re-executed constantly, like in the Shiny applications, and where eventually a multi-concurrence of users can occur, performance becomes a key factor to avoid collapses.

For example, if the whole application is based on one data source, there is no point in loading it more than once. So, in this case, if the data load code is within a reactive expression in server.R, the data will be loaded unnecessarily again whenever an input value changes, whereas it could have been loaded just once when the application was loaded.

Here are some tips to optimize your code and considerably reduce your execution time:

  • Run once whatever is used by more than one process: In the reactive example shown in this chapter under the tabsetPanel section, for example, it was very clear that both renderPlot() and renderTable() used the same data source. However, this is not always so easy to identify. Before coding, it is always advisable to have an overview of the whole process, especially of what data is needed for each of the outputs. With this in mind, common processes can be identified and consequently run only once and stored in a reactive object.
  • Preload anything that can be preloaded: As it happens with all the examples shown that load the iris dataset, it is always advisable to preload and preprocess everything that can be preloaded and preprocessed in global.R. In order to do this successfully, the programmer needs to have a clear idea of which elements in the application change and which don't.

    Those that don't change must be handled either in global.R or in server.R before the shinyServer() call so that the application only re-executes what is definitely necessary to re-execute. From a more general perspective, this is related to a clear understanding of the main concept underlying the Shiny applications, that is, reactivity. A clear idea of what is reactive and what is not will lead to successful preprocessing and preloading of whatever can be preloaded.

  • Build useful functions: Building functions is a very good programming practice in general. Firstly, it reduces the amount of code written, and secondly, it spares massive eventual code modifications. For instance, if you need to do a change in a process that is not specified in a function, the change will have to be done in every place this process appears. Except for extremely exceptional cases, function declarations do not depend on reactive contexts, so it is also advisable when working with Shiny applications to declare all the functions either in global.R or in server.R before the shinyServer() call.

This list of good practices is valid for every code writing, not only in R but also in almost every programming language. But when it comes to web applications, where the response must be almost immediate, the execution times make the difference between a fair and an excellent job. Normally, web application users will be looking for fast answers to work in real time, so if the application cannot deliver the sought insights in time, it is simply not worth it.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset