Measure UTF-8 bytes instead of JavaScript string length

Analysis

By Juliet Ramos, Playable Production Editor3 min read

View author profile
Measure UTF-8 bytes instead of JavaScript string length

A teaching fixture that separates JavaScript string length from UTF-8 byteLength before any packaging limit is applied.

A source-size check can undercount non-ASCII text when it treats JavaScript string length as transmitted bytes. Playable engineers and QA owners who gate builds on that unit risk approving text that later fails a network package check, or rejecting ASCII that was never the real problem. This edition is a teaching laboratory: it makes the unit conversion explicit before any packaging limit is applied.

What the documentation establishes

MDN’s TextEncoder.encode() reference states that the method takes a string and returns a Uint8Array containing that string encoded as UTF-8. The return value’s .byteLength is therefore a byte count of UTF-8 text, which is a different measure from JavaScript’s .length on the same string. MDN documents the primitive; the fixture policy around it is ours. Body read on 19 September 2026; the page records a last modification of 28 June 2025.

The failure the fixture isolates

The fixed branch encodes the supplied string and counts bytes: (value) => new TextEncoder().encode(value).byteLength. The broken branch returns value.length. Three synthetic inputs expose the difference without a large bundle: plain ASCII, one accented character, and one emoji. The fixture measures uncompressed UTF-8 text only. It does not measure an archive, a transfer size, a decoded runtime payload or any ad-network package limit.

Reference table
CaseSynthetic inputExpected UTF-8 bytes (fixed)Broken output (`value.length`)
ASCII`"abc"`33
Accented character`"é"`21
Emoji`"🎮"`42

On 19 September 2026 the fixed branch matched all three expected values when executed in Node against these authored cases. ASCII happens to agree on both measures; the accented and emoji cases diverge. That pattern is the teaching point: a check that only samples ASCII will not catch the unit error.

Runtime matrix and untested cells

Reference table
CellStatus in this edition
Node fixture execution (synthetic cases)Executed 19 September 2026; fixed branch matched expectations
Browser device panelNot executed
Host SDK / WebView packagingNot executed
Ad-network package, compressed or decoded size gatesNot claimed
Store-opening callbacksNot tested
Campaign performance or analytics deliveryNot claimed

A browser or Node pass is not a device panel. Untested cells stay empty on purpose.

What a pass does not prove

A pass proves the unit conversion for the supplied ASCII, accented and emoji examples. It does not establish that a playable meets any ad-network size requirement. A platform may specify a package, compressed file, decoded payload or another unit; that exact current requirement must be checked before a submission claim is made. No network reviewed this build, and no campaign result is inferred from the fixture.

Next check on a real build

Label every build-size metric with its unit and stage: source text, encoded bytes, bundled output and final package. Measure the actual submission artifact, not a convenient precursor. Keep source-map and embedded-media decisions visible so a small code change cannot conceal a much larger asset contribution.

Download the case record. It keeps synthetic inputs, fixed and broken outputs, the runtime matrix and the explicit limits with a QA ticket.

Background in the archive: Playable ad device testing matrix and Playable spec sheet before you build. Those guides describe practice; they are not a substitute for this fixture, and this check does not recertify their every claim.

Featured

Related posts

Playable completers vs video viewers: downstream payer quality

measurement

playable ads

·

1 min read

Playable completers vs video viewers: downstream payer quality

measurement

playable ads

·

3 min read

Stop simulation time while the document is hidden

measurement

playable ads

·

3 min read

Fit the whole playable stage inside a narrow viewport

measurement

playable ads

·

2 min read

Require both intersection and document visibility before advancing

More from the Measurement desk

Airbridge adds Amazon Ads as an app measurement channel

measurement

·

2 min read

Airbridge adds Amazon Ads as an app measurement channel

measurement

·

2 min read

When to freeze a cohort for payback review (and when not to)

measurement

media buying

·

1 min read

Using predicted LTV in bids: disclosure checklist for the UA team

Blended ROAS targets that hide channel failure in F2P portfolios

measurement

media buying

·

1 min read

Blended ROAS targets that hide channel failure in F2P portfolios