I've just done the same investigation and come to the same conclusion looking at DWC and how it grabs the info from the RRF printmonitor.
DWC uses the height of the object to calculate total layers at https://github.com/Duet3D/DuetWebControl/blob/1121469e780d213df0cda6e85fbf1bb2000a8c33/src/store/machine/modelItems.js#L435. After some scanning around, it doesn't look like RRF passes back numLayers hence always dropping into this approximation logic. Please correct me if I am wrong on this.
Given it is dropping into that approximation, the specific issue is that height is not calculated correctly where there is a none print move. This is especially prevalent when you have ending GCode to move the extruder out of the way of the printed part. The logic to calculate the height is done in the printmonitor code at https://github.com/Duet3D/RepRapFirmware/blob/123d4362a04a709103971dd10b94e916b8790ef8/src/PrintMonitor.cpp#L145.
Must admit that having the height parsing logic look forward for subsequent extrusions would likely cause parsing to slow down considerably. Given this, I wonder if implementing the parsing of numLayers to pull it out of the GCode header with a specific format is the best way to go.