Improving Harper for Old Laptops

The most com­mon com­plaint I’ve been hear­ing as of late re­lates to Harper’s per­for­mance. I’ve been told that Harper has got­ten slow.

I was puz­zled. Nothing had sub­stan­tially changed in our core en­gine that could have made it slower. Our bench­marks had­n’t shown any slow-downs. What could be prompt­ing users to com­plain about per­for­mance?

The prob­lem was clearly in the Chrome ex­ten­sion. Those who com­plained were do­ing so with screen­shots from Notion or Ghost. Could re­cent de­vel­op­ments in the WebAssembly ecosys­tem be the cause? Nope. Could it have some­thing to do with the kinds of ap­pli­ca­tions users were try­ing to use with Harper? Nope. The com­plaints seemed un­teth­ered to a spe­cific do­main or pro­gram. What could be slow­ing our users’ down?

The Problem

As it turns out, the prob­lem was­n’t the ac­tual gram­mar check­ing, it was ren­der­ing the high­lights on the page.

The Chrome ex­ten­sion’s hot path looks some­thing like this:

  1. Extract the text from the page
  2. Run harper-core (the gram­mar en­gine) over it to find mis­takes
  3. Use DOM APIs to com­pute the bound­ing boxes of those mis­takes on the page. This is im­por­tant: This com­pu­ta­tion re­quires the browser to re­flow the lay­out of the page.
  4. Render ad­di­tional DOM el­e­ments to the screen over these bound­ing boxes. This also re­quires the browser to re­flow the lay­out of the page.

Requiring the browser to lay out the page more than once per frame is called layout thrash”, and it’s con­sid­ered bad prac­tice for per­for­mance rea­sons. It causes more CPU us­age than oth­er­wise, which can slow down com­plex web­sites and re­duce bat­tery life. It is­n’t no­tice­able for newer com­put­ers (4 years old), but it can be quite jar­ring for older lap­tops.

The Solution

Fortunately, there’s a so­lu­tion. Just re­cently, W3C stan­dard­ized The Custom Highlight API, which al­lows us to ren­der high­lights with­out in­ter­act­ing with the DOM at all. This saves us two full lay­out re­freshes and al­lows the browser to of­fload more work to the GPU, sav­ing CPU cy­cles and bat­tery life.

It’s not all roses and rain­bows. For one, we can only use this op­ti­miza­tion for text ed­i­tors that use contenteditable el­e­ments. It does­n’t help for <textarea /> or <input /> el­e­ments. Firefox also does­n’t sup­port this part of the API, which means we have to fall back to the old high­lighted ren­derer on Gecko-based browsers.

There are also some mi­nor dif­fer­ences be­tween how the new ren­derer and the old ren­derer style their high­lights. This is be­cause high­lights us­ing the Custom Highlight API can’t be styled us­ing any old CSS, but rather a sub­set.

Published September 19, 2025 at 6:00 AM

Proofread by Harper.

Comments

Gravatar for me@elijahpotter.dev
Elijah Potter

I'm not sure exactly when, but this should be released soon for those interested.