govuk-frontend icon indicating copy to clipboard operation
govuk-frontend copied to clipboard

Character Count calls the count function multiple times

Open 36degrees opened this issue 3 weeks ago • 0 comments

Description of the issue

On page load, before the character count is interacted with, we count the number of characters / words 6 times:

  1. The constructor calls updateCountMessage

  2. updateCountMessage calls updateVisibleCountMessage

    1. updateVisibleCountMessage calls count so that it can use the count to decide whether it has an error state or not
    2. updateVisibleCountMessage then calls getCountMessage
    3. getCountMessage then calls count again in order to craft the visible count message
  3. updateCountMessage calls updateScreenReaderCountMessage

    1. updateScreenReaderCountMessage calls getCountMessage again which calls count again.
  4. The pageshow event fires which triggers updateCountMessage again, so steps 1 to 3 are repeated.

If a threshold is set, this goes up to 10 times because updateVisibleCountMessage and updateScreenReaderCountMessage both call isOverThreshold which then calls count (unless no threshold is set, in which case it returns early).

Typing a single character into the box results in another 11 counts happening (when a threshold is set).

This isn’t too much of an issue when we’re just calling string.length which is relatively cheap, but I think we’ll want to fix this before we make the count function customisable, or explore using Intl.Segmenter to count.

Steps to reproduce the issue

One way to get visibility on the calls to count is to add a call to console.trace to the count function.

Actual vs expected behaviour

Expected behaviour: the count function is only called once (or as close to once as we can get it) Actual behaviour: the count function is called multiple times

Environment (where applicable)

  • Operating system: macOS
  • Browser: Chrome
  • Browser version: 125.0.6422.142
  • GOV.UK Frontend Version: (main)

36degrees avatar Jun 14 '24 15:06 36degrees