docs(readme): record what a rendered post body costs to derive from - #160
Merged
Conversation
`$post->content()` reads like an accessor and is a render. It ends in `apply_filters( 'the_content' )`, and `do_blocks()` sits on that filter at priority 9, so deriving a word count, a reading time or a length from it renders the whole article once per row. Measured on a nine-teaser blog listing: 469-644 ms of an 897 ms page, 306 kB of HTML built and discarded to keep nine integers. Counting the same nine from the raw `post_content` cost 0.8 ms, and the page went 0.868 s to 0.354 s with byte-identical output. Documented rather than fixed in code, because the kit does not own the call site -- it is a pattern every consuming theme writes by hand in its teaser mappers. Two mechanisms hide the cost, and the section names both. Timber memoizes into `___content`, so the repeated call a reader goes looking for is free and the real cost is the first call; and a profile bills the time to `WP_Hook->apply_filters` rather than to the code that asked. It also records that rendering is not automatically the more correct input for a text measure. `the_content` rewrites `e-mail` to use a non-breaking hyphen (U+2011), so a word pattern admitting only an ASCII hyphen counts every hyphenated word twice. Across 1583 published articles 1579 agreed; two of the four that differed did so for that reason, two on a rounding boundary. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JMYy6JHLf4mU4H4Hd47spb (petr@pari.cz)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A new README section,
Deriving a value from a post body, plus its changelog entry. Documentation only — no code changes.Why
$post->content()reads like an accessor and is a render. It ends inapply_filters( 'the_content' ), anddo_blocks()sits on that filter at priority 9. Deriving a cheap value from it — a word count, a reading time, a length, a "has an image" flag — therefore renders the whole article, once per row.Found on
sloneek, whose blog listing calledReadingTime::minutes( $item->content() )for each of nine teasers:the_contentchain, nine articlespost_contentRendered HTML byte-identical once per-request
uniqueId()values are normalised.Why documentation and not code
The kit does not own the call site. Teaser mappers are written by hand in every consuming theme, so there is no function here to fix — only a trap to name.
What the section adds beyond "don't do that"
Two mechanisms hide the cost, and both are named:
$this->___content, so the repeated call a reader goes looking for is genuinely free. The cost is the first call, once per post object, and a listing has one object per row.WP_Hook->apply_filters, not to the code that asked for it.Rendering is not automatically the more correct input for a text measure.
the_contentrewritese-mailto use a non-breaking hyphen (U+2011). A word-boundary pattern admitting an ASCII hyphen inside a word but not that one then counts every hyphenated word twice. Across 1583 published articles, 1579 counted the same either way; of the four that differed, two held 52 hyphenated words and two sat exactly on a 200-word rounding boundary.Related
The profiler ranked PHP-Typography first on this page at 20 % of self time. Disabling it in a real request saved ~20 ms — it makes 483 000 tiny calls and Xdebug bills per call. That is the same inclusive-vs-real trap as #147, and it is why the numbers above are all bracketed
microtime()in real requests rather than profiler output.🤖 Generated with Claude Code
https://claude.ai/code/session_01JMYy6JHLf4mU4H4Hd47spb