Skip to main content

Reflex Unexpected Duplicate (Part 2)

The Reflex FRP calculator tutorial provides a working project, with explanations for incremental implementations of a calculator and some exercises at the end. This is a nice first tutorial that demonstrates some important concepts through a simple example. I would like to learn how to start a project from scratch, however, so I looked for other tutorials that do that. One has to be careful of old tutorials that differ from current best practices, however, and I realized that I need to understand more about the Reflex ecosystem now.

I initially did not understand the relationship between Reflex Platform and Obelisk. I do not think it is explained clearly, for people who are new to Reflex, anywhere. After searching and reading in lots of places, I have arrived at the following understanding.

  • Reflex Platform provides the packages and tools to build Reflex projects targeting multiple platforms using Nix. From my experience with Nix, I have found that it works great when using packages that already work, but it can be very difficult to make stuff work in the first place. The Reflex developers maintain the Reflex Platform to provide a set of package versions that are tested and known to work together.
  • Obelisk is essentially a framework that uses Reflex Platform. By structuring your application in the prescribed way, Obelisk provides many useful features and development tools.

While reading documentation, I saw the following in the Obelisk README.

Now, with an appropriate browser, go to http://localhost:8000 (or the address/port specified in config/common/route) to access your app. Firefox will not be able to properly run the development website due to issue 460. Fortunately, this problem does not occur on a fully built website.

I find it promising that the issue is only with the development website! I would like to try building the “fully built website” for the calculator tutorial and check out the results. To do this, I followed the directions to deploy the application locally.

That build took a long time. I was expecting the long build yesterday, but I must admit that I am a bit disappointed that this build took so long, as I had hoped that much of the work was already done during the development build. For example, I noticed that it was downloading GHC, which I assume was already downloaded. I configured the cache, but perhaps it is not working? Perhaps different builds of GHC are used for development and production?

Speaking of GHC, I notice that GHC 8.6.4 is being used. This is amusing because of the recent discussion about supporting three major versions. GHC 8.6 is already two major versions behind the oldest supported version with this policy. I suspect that such short support makes maintenance quite challenging for projects like Reflex! I am curious why GHC 8.6.5 is not used, but I will not look into that.

While waiting for this build, there were times that my processor maxed out, making the whole system become unresponsive. A friend who develops using Nix recommends doing development on a separate computer/server.

The build completed successfully, and it works in Firefox!

I am curious to see the size of the build, but it is a mess of symbolic links because it uses Nix. I wonder if there are any utilities that can provide a good overview of such a build… For now, I investigated using find -L.

One interesting thing that I learned is how assets are stored. A type file specifies the type of asset, including the following:

  • immutable
  • redirect

The immutable assets have an encodings directory that contains files corresponding to different content encodings for HTTP compression. This allows the server to send pre-compressed assets, so that there is no need to compress the same file multiple times. The build includes the following encodings:

  • compress
  • deflate
  • gzip
  • identity (no compression)

There are many files linked, and I bet that many of them are not actually used by the tutorial… Perhaps builds include all built-in (runtime) dependencies of Obelisk web applications, with no tree shaking? My impression is that Reflex is only appropriate for applications where bandwidth is not an issue, so I guess this does not matter. Curious, however, I checked what is transferred for step 11 of the tutorial.

Firefox indicates that about 2MB of JavaScript is transferred. Looking into it, I found that an asset named all.js has type redirect and target 1fj1x2ib6f5rlvsplcgrszsxcqr5z0rmh52f2f8ispxjpy7h2grc-all.js. That file has type immutable, and the gzip encoding is 1,064,632 bytes. The Firefox development tools indicate that this file is transferred twice, which is strange! I captured the packets and confirmed that the file is not being sent twice. Research indicates that it is an issue with Firefox that is quite old. There have been many “duplicate” bugs reported, but 1617852 seems to be the primary one.

The following are the correct stats. Note that there are no images on the page, but the browser checks for a favicon automatically.

Content Type Transferred (KB) Decompressed (KB)
JavaScript 1,055.92 11,311.83
CSS 24.97 188.91
HTML 0.93 2.35
Image 0.10 0.00

This blog entry covered more topics than planned, as there is plenty of time for the mind to wander during long builds. (I am only half joking.) I am happy that the tutorial works with Firefox when using production builds.

Author

Travis Cardwell

Published

Tags
Related Blog Entries