Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Byte attribution of a served product snapshot: inlined CSS is 13%, attributes are 75%

Abierto
#147 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
5/5
Tiempo estimado
Más de una semana
Aptitud para principiantes
35/100
Tipo de issue
Nueva funcionalidad
Claridad
Necesita aclaración
Estado de actividad
Activo
Stack tecnológico
javascript
Área
performance

Línea de trabajo

Empieza leyendo la ruta de postProcess y el comportamiento existente de pruneUnmatchedCss y minifyInlineCss; después reproduce el desglose de bytes de /prerender_admin/page-content con las opciones indicadas de browser v1.21.0. Compara las palancas de SVG, tokens de clase y Style-URLs repetidas con las hojas de estilo externas y con la paridad de paint o geometría; no elimines el CSS del widget de revisión. El trabajo estará terminado cuando haya una optimización seleccionada y medida, con el contenido renderizado sin cambios y un camino claro hacia el límite de 1 MB.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Summary

A served product snapshot was reported as having a low text-to-HTML ratio, attributed to the CSS flattenShadowDom inlines for the review widget. Measured against a real served page, that attribution is wrong: inlined CSS is 13.4% of the document and attributes are 74.7%. Deleting every byte of injected styling moves the ratio 2.66% → 3.07%.

This issue records the byte attribution so the numbers aren't re-derived, and separates the levers that are provably safe from the one that isn't.

Method

One review-heavy product page (desktop), read from the serving cache via /prerender_admin/page-content, so these are the bytes a crawler receives. Rendered by browser v1.21.0 with flattenShadowDom, pruneUnmatchedCss and minifyInlineCss all on — i.e. the CSS below is already the residue after ~74% of style rules were pruned and the rest CSSOM-minified.

Class-token reference counts were computed against the inline <style> blocks and the four external stylesheets the snapshot still links. Measuring against inline CSS alone overstates the unreferenced total by ~6× (359 KB vs the true 61 KB) — the page keeps a 588 KB external utility stylesheet, so most tokens are referenced from a sheet that is not in the document.

Where 1,468,123 bytes go

bytes % of doc
class attributes 451,713 30.8%
inlined <style> CSS 197,160 13.4%
style= attributes 140,957 9.6%
href / src / srcset 214,751 14.6%
SVG d path data 81,344 5.5%
aria-label 52,604 3.6%
tag names + brackets 55,700 3.8%
ld+json 17,486 1.2%
visible text 39,078 2.66%

10,137 elements. 74.7% of the document is HTML attributes.

The review widget

The flattened review container is 385,482 B — 26.3% of the page — carrying 7,707 B of review text (2.0% of itself). Eight review cards; one card is 22,446 B / 235 elements for 956 B of text.

inside the review container bytes % of block
inlined <style> (host sheet + nested shadow hosts) 152,624 39.6%
SVG markup (d alone = 62,473) 108,954 28.3%
class 60,930 15.8%
review text 7,707 2.0%

Two candidates measured and rejected

  • Deduplicating identical shadow stylesheets across hosts. 9 distinct sheets across 10 hosts; total bytes sitting in duplicate copies: 196 B. Not a lever.
  • minifyInlineCss on the flattened blocks. Already CSSOM output, so re-emission is a no-op — consistent with the existing docstring.

Levers that remain, with sizes

  1. Repeated SVG path data — ~64,093 B (4.4% of the document), concentrated in the review block. 193 d occurrences, only 61 distinct; a single 1,033-byte path appears 45 times (46,485 B). Hoisting exact-duplicate path data into <defs><symbol> + <use> renders identically. No such pass exists in postProcess today.
  2. Class tokens no surviving rule references — 61,277 B page-wide, 34,467 B inside the review block. Same soundness argument that already licenses pruneUnmatchedCss: with stripScripts on, nothing can add a class after serialization, so a token no sheet mentions is inert. Must be evaluated against external sheets, not just inline ones.
  3. A repeated background-image URL in style= attributes — ~93,000 B. One sprite URL repeated 489 times across style= attributes. Origin-authored, not introduced by post-processing.

Cloaking: what actually carries risk here

Worth stating explicitly, because "fidelity" has been used to decline byte-cutting levers that do not actually implicate it.

Cloaking is presenting different content to users and crawlers in order to manipulate rankings. The unit is content — text, links, images, prices, availability, structured data — not markup. Removing an attribute no rule reads, deduplicating identical SVG path data, or pruning a rule that matches nothing changes zero content: a user and a crawler still perceive the same page. Levers 1–3 are outside the policy, and rendering-fidelity checks (paintParity, geometry) are the right bar for them for a different reason — Google indexes the rendered DOM and devalues content it determines is not visible, so a layout regression costs indexing quality on its own merits.

The risk is asymmetric, and it runs the other way: revealing content to a crawler that a user does not see is the cloaking-shaped move. That is exactly what dropping the review widget's CSS would do — the widget's own rules hold collapsed panels, modals and secondary UI at display:none, and stripping them injects text into the indexable page that no user is shown. It would also reintroduce the inbound-encapsulation defects fixed across v1.19–v1.21. Do not pursue "just drop the review CSS" for byte savings.

Note for answer/generative engines

Structured data carries aggregateRating (ratingValue, ratingCount) but no individual review objects. So the 385 KB review DOM is the only place individual review content exists in the snapshot — it is load-bearing for extraction, not redundant with the JSON-LD, and should not be treated as trimmable content. Emitting review items into the JSON-LD would serve extraction far better per byte than the DOM does, but that is an origin change, not a post-processing one.

Separately: text-to-HTML ratio is not a documented ranking signal — it is a third-party audit-tool metric. The documented hard constraint is the 1 MB soft cap a crawler applies to a document, and this page is at 1.47 MB. Sizing work against "get under 1 MB" is better defined than "raise a ratio", and levers 1–3 together are ~218 KB of the ~470 KB needed.

Lenguaje dominante
JavaScript
Estrellas
0
Forks
0
Merge medio
9 h 10 min
PR fusionados (30 d)
56

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de HarperFast/prerender-plugin

Todos los issues de HarperFast/prerender-plugin

Issues similares

Más issues de JavaScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.