27/07/2021

Speeding up a Domino website by eliminating the Dojo framework (DRAFT)

BasicWeb is used by a client to manage his Domino-based website. They have many internal databases for their business processes (CRM, products), all on Domino, and it was only logical to create a dedicated database for their website. Technically it was not a real problem: several Forms and Views to manage the pages in Notes, and one XPage plus a lot of custom controls for the presentation. There are some interesting features, like embedding documents in others, also from other databases, but that's not the topic of this article.

This website went online serveral years ago and it easily survived many modifications, both in the page contents and in the design of the website and related databases. Technically it was a great success at a time when speed wasn't considered to be very important. But now it is, Google's ranking algorithm seems to value speed as a very important aspect of a website. Since content optimisation isn't really on my plate, I only had to look at potential ways to optimise BasicWeb and Domino itself, especially the perceived speed of the website.

We analysed the website using PageSpeed Insights. The home page scored a depressing 16/100 (mobile), we didn't check the desktop page speed. When we looked at the detailed output, it suggested that there was already a lot to be gained by eliminating Dojo: it consists of several big files, even in compressed form, that are loaded on every page, and they are considered to be blocking resources. Only a small percentage of the contents of these files are really used in BasicWeb, so it should be possible to gain a lot by removing them altogether. How to accomplish this, what does Dojo do, where does it come in, can it be avoided, and what are the pitfalls?

For us, there were four areas of interest, where Dojo is used, that needed attention: standard page resources and those included by XPages, the XSP JavaScript client-side object, CSS classes and styles (those with a prefix .xsp), and additional nice Dojo elements used in the website like a Menu and a Tree.

I learned that resources can be eliminated completely by putting the following line in the XSP.properties:

xsp.client.script.libraries=none
but that's not what we need. I wanted to get rid of Dojo only, and keep the possibility to include my own resources.

The first thing I did was to create a simple, empty theme:

<theme extends="nothing" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:noNamespaceSchemaLocation=
"platform:/plugin/com.ibm.designer.domino.stylekits/schema/stylekit.xsd" >
</theme>		
That effectively got rid of the theme-related settings and files. Then, I searched the Internet again, to find out if there is some setting that eliminates only Dojo from the output. I couldn't find one, so I developed a small renderer class in Java that just doesn't render Dojo-related resources. It is based on one of the ViewRootRenderers that I found while searching (link).
package fr.bosman;

import java.io.IOException;
import java.util.List;

import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;

import com.ibm.xsp.FacesExceptionEx;
import com.ibm.xsp.component.UIViewRootEx;
import com.ibm.xsp.renderkit.html_basic.ViewRootRendererEx2;
import com.ibm.xsp.resource.GenericHeadResource;
import com.ibm.xsp.resource.MetaDataResource;
import com.ibm.xsp.resource.Resource;
import com.ibm.xsp.resource.ScriptResource;
import com.ibm.xsp.resource.StyleSheetResource;

public class ViewRootRenderer extends ViewRootRendererEx2 {

	@Override
	protected void encodeResourcesList(FacesContext context, UIViewRootEx viewRoot, 
	  ResponseWriter writer, List resources) throws IOException {
		for (Resource resource : resources) {
			try {
				if (resource instanceof StyleSheetResource)
					encodeStyleSheetResource(context, viewRoot, writer, 
					  (StyleSheetResource) resource);
				else if (resource instanceof ScriptResource)
					encodeScriptResource(context, viewRoot, writer,
					  (ScriptResource) resource);
				else if (resource instanceof MetaDataResource)
					encodeMetaDataResource(context, viewRoot, writer, 
					  (MetaDataResource) resource);	
			} catch (FacesExceptionEx fff) {
				writer.writeComment("Problem encoding Resource " + resource);
				writer.write("\n");
			}
		}
	}
	
	private void encodeStyleSheetResource(FacesContext context, 
	  UIViewRootEx viewRoot, ResponseWriter writer, StyleSheetResource resource) 
	  throws IOException {
		if(!resource.isDojoTheme())
			encodeResource(context, viewRoot, writer, resource);
	}
	
	private void encodeScriptResource(FacesContext context, UIViewRootEx viewRoot, 
	  ResponseWriter writer, ScriptResource resource) throws IOException {
		if(resource.getSrc() == null || !resource.getSrc().contains("dojo"))
			encodeResource(context, viewRoot, writer, resource);
	}
	
	private void encodeMetaDataResource(FacesContext context, UIViewRootEx viewRoot, 
	  ResponseWriter writer, MetaDataResource resource) throws IOException {
			encodeResource(context, viewRoot, writer, resource);
	}
}
		
And the generated output is a lot smaller, many linked files are no longer there, allowing to render the page a lot faster. But as we expected, there are many errors, because the XSP and Dojo objects are missing (see the Developer's console in the browser) and styles no longer match.

So I set out to find or develop replacement code for the XSP object, a daunting task so it seemed, until Shillem Volpato told me on Slack that he already developed a Dojo-free XSP object! link Brilliant stuff, a great step forward! I added PubSub to this XSP object and enhanced the code so that events are published before, during and after a partial refresh. link

All I had to do next is eliminate the Dojo code I introduced myself to the website, i.e. for the Menu and the Tree. I replaced Dojo's menu by (a modified version of) ClickyMenus.js and the Tree could simply be rebuilt using a custom control. Now why didn't I think of that before...

In the end, when we opened the website, it was indeed a lot faster. We checked with PageSpeed Insights: 46/100 (mobile) and 75/100 on a desktop!!

© 2020 Sjef Bosman · Consultant HCL Domino/Notes
SIRET 442 133 252 00019 · tél. +33 475 252 805
sjef@bosman.fr · sjef.bosman