ResponsiveFlow is a minimalist WPF application that measures the time of HTTP requests.
The application takes the JSON project file as input. It specifies the list of URLs to request, and the root directory for the output. For an example of such a project file, see project-example.json.
{
"Urls": [
"https://jsonplaceholder.typicode.com/users/",
"https://picsum.photos/seed/1729/350/200",
"https://placeholder.pics/svg/350x200"
],
"OutputDir": "C:/Temp/"
}You can select the project file from an Open… menu, or pass it to the application as a --Project command line argument.
ResponsiveFlow.Application.exe --Project="c:/Temp/Projects/responsive-flow-project.json"You can also manually add URLs to the grid by clicking on the bottom row.
The output report is saved in the subfolder of the directory specified by the OutputDir setting.
If it's omitted, the default is the subfolder in the user's home directory.
For example c:/Users/{Username}/Documents/ResponsiveFlow/281_01-49-19/.
The application also accepts the appsettings.json as a configuration file. Depending on the build configuration, appsettings.Development.json or appsettings.Production.json is also an option, which is convenient to override the default configuration when running from the IDE. See appsettings-example.json for a reference.
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"MaxConcurrentRequests": 23
}You can also set the maximum number of concurrent requests using the --MaxConcurrentRequests command line argument.
ResponsiveFlow.Application.exe --MaxConcurrentRequests=24The continuous progress bar at the bottom of the window shows overall responsiveness; the actual progress is shown by the progress bar at the top.
The application collects a five-number summary of the distribution (minimum, maximum, median and other quartiles) along with the mean, standard deviation and standard error.
The output JSON report contains the collected metrics for each input URL.
[
{
"UriIndex": 3,
"Uri": "https://jsonplaceholder.typicode.com/users/",
"Metrics": {
"Count": 100,
"Mean": 37.46743300000001,
"Variance": 374.3024034905159,
"StandardDeviation": 19.346896482136763,
"StandardError": 1.9346896482136764,
"Quartiles": [18.0431, 25.2191, 28.915, 39.346225000000004, 95.3742],
"InterquartileRange": 14.127125000000003
}
},
...
]The application saves the response time histogram in SVG format.
Instead of box plots1, it draws a quartile-respectful histogram with four equiprobable variable width bins using the Perfolizer library.
(These images have been carefully cherry-picked. The usual plots are often uglier, with multiple modes and outliers.)
The application sorts and ranks the URLs in the report according to their response times. It assigns equal ranks to URLs with the same responsiveness, using the Mann-Whitney U-test (from the Perfolizer library) for the equivalence analysis.
The solution consists of three projects — Application, Presentation, and Models.
The Application entry point App.Main() serves as the composition root for setting up dependencies in the DI container.
The Presentation project provides the viewmodels and defines the UI logic. The UI states and transitions between them are as follows:
All the asynchronous machinery for making requests and collecting the measurements is placed in the Models project.
Footnotes
-
I’ve Stopped Using Box Plots. Should You?
https://nightingaledvs.com/ive-stopped-using-box-plots-should-you/ ↩
