Skip to content
Home » Blog » Lazy code

Lazy code

You may be familiar with “lazy loading” on webpages. That’s where the browser doesn’t request images from the server until the page is scrolled to the point where they would be visible.

The general principle is to not do work until you have to, both to speed up initial loading and because who knows, you might not have to do it at all.

The same principle can be applied to writing code. For best performance of your code, try to avoid time-consuming operations altogether. In the LotusScript context, an example would be that you sometimes need to look things up in a view, but sometimes not. You don’t open the view and create a NotesView object until it’s first needed, and then once you have opened it, you don’t discard the object until you know you’re done with it. You can create your own cache.

This sort of thing is most easily handled in the context of a class. That gives you a place to store the saved object for reuse, and not worry about duplicate names. There may also be other code in the class that needs access to the cached object, e.g. to delete it from cache if that code is doing something that invalidates it.

I use this technique routinely, not only for views but also profile documents, hard-to calculate values (e.g. a hash code for some file contents), …

Example: a view

This class has a lazy-loading property, IDView, which only fetches the view sorted by ID field if it’s needed. The view is loaded with Autoupdate = False for best performance, and a method IDViewUpdate is provided to refresh it on demand if it’s already cached. The Save method does that explicit update because it knows the document it’s saving is in that view and wants it to be up to date. The isIDUnique method casually makes use of IDView to search for existing documents with the key value we propose to use. If in whatever sequence of events occurs using the form, isIDUnique is never called, we never have to do the work of loading the view. If the user tries several different IDs, we only have to load the view once.

I’m assuming here a context where the ProjectDocument object is remaining in memory while all this is going on, e.g. it’s declared as a Global on the Document form.

Class ProjectDocument
	Private z_db As NotesDatabase
	Private z_docProject As NotesDocument
	'...
	
	Private z_IDView As NotesView
	%REM
		Property IDView (read)
		Description: Get the view of Project documents sorted by ID field.
			This view is set to not autoupdate, so if you change documents and
			need to refresh it, do this explicitly via IDViewUpdate method
	%END REM
	Public Property Get IDView As NotesView
		If z_IDView Is Nothing Then
			Set z_IDView = z_db.Getview("ProjectsByID")
			z_IDView.Autoupdate = False
		End If
		Set IDView = z_IDView
	End Property
	%REM
		Sub IDViewUpdate
		Description: Make sure any cached view index of the ID view is up to date.
	%END REM
	Sub IDViewUpdate
		If Not z_IDView Is Nothing Then
			z_IDView.Refresh
		End If
	End Sub

	%REM
		Function isIDUnique
		Description: Find out whether the ID the user proposes already is in use.
		Arguments:
			ID: the ID to check.
		Returns: TRUE if the ID is unique.
	%END REM
	Function isIDUnique(ByVal ID$) As Boolean
		Dim docsWithID As NotesViewEntryCollection
		Set docsWithID = IDView.Getallentriesbykey(ID, True)
		If docsWithID.Count > 1 Then Exit Function ' returning False
		If docsWithID.Count = 1 Then
			Dim ent As NotesViewEntry
			Set ent = docsWithID.Getfirstentry
			If ent.Noteid <> z_docProject.noteid Then Exit Function ' another doc already using this ID
		End If
		isIDUnique = True
	End Function
	
	%REM
		Sub Save
		Description: Save the Project document associated with this object.
		Arguments:
	%END REM
	Sub Save
		Call z_docProject.Save(True, False, True)
		IDViewUpdate ' the saved document appears in this view so make sure it's up to date
	End Sub
End Class

Leave a Reply

Your email address will not be published. Required fields are marked *