Plotting (to save) XSLT
Using XSLT to transform XML data into SVG plots, Wok style
GAFAM's latest attack on the open web comes in the form of a proposal to deprecate XSLT. I've talked about XSLT in the past here, discussing options for the sparklines and (in Italian) to show a simple website entirely designed around its power.
I profoundly dislike the idea of such a powerful feature being removed from browsers, and I will write elsehwere about why this is a threat to the open web, an attack against the indieWeb and an attempt to undermine the more recent efforts to push against the centralization of the web.
What I want to talk about here is about some recent efforts of mine to introduce XSLT in the Wok as an example of how websites can benefit from its adoption. This will be a long process, and my hope is that in the process I'll even manage to get rid of some (optional) JavaScript usage, particularly in the generation of the “index pages tables of contents”. For the time being, what I've done has been to introduce a “plotting stylesheet” to reproduce the plots from my recent article (in Italian) about the language to write in, processing directly some XML data client-side to produce the relevant SVG images.
The original images were produced via some server-side awk scripts
(linked from the above mentioned page, for the curious)
that need to be run after updating the stats whenever I want to regenerate the plots,
and the idea was to try and get the same results (or possibly improve on them)
by only needing to update the statistics (written this time in XML form).
By the way: even though it may seem that I'm only doing this to spite the GAFAM engineers working on the browser engines, or to skew the stats about XSLT adoption, that's not really the reason why I'm doing this: as I've mentioned already, I've been pondering about doing this for a long time, and the only thing that the umpteenth attempt at sabotaging well-established standards (see their attempt in 2013, and the related attempt to deprecate SMIL in 2015; notice how they always go for it in the summer, too) has done is to push me to finally act on my intentions.
The results are in. The “articles per language per year” plots are:
and the “language percentages per year” plots are
There are some minor aesthetic differences because I've taken the opportunity to fix some visualization artefacts (such as the grid-under/over-bars inconsistency in the first plot), and also to update the statistics for 2025, but other than that the plot match up.
The biggest difference, however, is technical: since the XSLT plots make use of external resources (the XSL stylesheet and the data XML) they must be included not as images, but as objects.
Is it worth it?
Now there's an interesting question.
In terms of raw size, the original SVGs add up to just shy of 9KiB, but the scripts (two separate scripts) to generate them take around 6.3KiB. The data is a few hundred bytes and doesn't get committed to the repository.
The new SVGs weight less than 300 bytes combined, but the XSLT stylesheet to produce the same result (more on this later) is 12KiB. The data itself is around 2.8KiB, and this needs to be committed to the repository (and sent to the user), although it could be reduced to less than 1.3KiB choosing more compact node and attribute names (they're completely arbitrary).
Adding things up, it's a bit of a mixed bag. On the one hand, the original SVGs and necessary scripts take up more space in the repository: barely so on first commit, but the benefits would improve when stats get updated and/or the scripts get revised. On the other hand, the original SVGs send fewer bytes to the reader on first load, although the benefit would even out in case of updates, that would require only the next XML data to be re-fetched (unless the XSLT stylesheet changes too, of course, but that would be expected to change less often).
But there's more to it.
First of all, since we're producing the SVG via transformation, we can actually do something that would have be rather more expensive with the previous approach: we can include both plots in the same SVG:
This is just a trivial exercise in this case, but there's room for some fancy combinations in more sophisticated setups (left as an exercise to the reader).
Even better: the attentive reader will have noticed that the linked XSLT stylesheet is not, in fact, 12KiB in size, but slightly larger. This is because, given that we have to include those plots as objects anyway, we can take advantage of this to make them interactive.
Fun fact: having interactive plots was actually my original intent, but I stopped short of doing it because the resulting files would have been too large (around 50% larger, with the current interactivity features). Now I don't have to worry about that, because the size increase to make the SVGs interactive goes into the stylesheet, and not only by increasing the size of a single file the benefits get shared between all plots, but even for a single plot the total increase (XML + XSLT) is considerably less because I only need to update the common template of all the bars, and not each bar. So for less than a 1KiB I manage to gain something that would have required more than 2KiB per file to achieve. A net win.
Conclusions
The migration from SVGs statically generated as part of the build process to SVGs generated via XSLT from data stored in XML format has been a resounding success. The next step will be to work on something similar for the sparklines of the index pages.
EDIT (2025-08-08): while working on sparkline support, I've taken the opportunity to organize things better and redesign the data file. The net result is that both the data file and XSLT stylesheet are slightly smaller, making this approach even more convenient.