RFC-0047: A blog for perfetto.dev #7221
Replies: 1 comment
|
📝 RFC Document Updated View changes: Commit History |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
📄 RFC Doc: 0047-perfetto-dev-blog.md
A blog for perfetto.dev
Authors: @primiano
Status: Draft
PR: N/A
This proposes adding
/blogto perfetto.dev: a chronological, staticallygenerated blog whose posts live on a dedicated
bloggit branch, rendered bythe existing
infra/perfetto.devpipeline.Live demo: https://perfetto-blog-demo.surge.sh/blog/ (I'm still working on some details)
Problem
Perfetto has no place to publish prose. We have reference documentation and we
have a
CHANGELOG, and neither is a thing anybody reads for pleasure orsubscribes to. Three concrete gaps:
v58.0shipped trace merging, Zstd compression, aunified stack-sample format and a client/server mode for
trace_processor.As a changelog that is a wall of bullet points. Nobody outside the project
learns that any of it happened.
docs/case-studies/memory.mdanddocs/case-studies/scheduling-blockages.mdare blog posts filed asdocumentation, because documentation was the only shelf available.
(Panfrost GPU counters), Ruby's ZJIT,
dotnet-traceand QEMU all publishPerfetto material on their own blogs. Nobody links them together.
Constraint
perfetto.dev is fully static, served by GCS as the rest of the perfetto.dev site.
No server-side rendering and no runtime dependency on a third party.
Decision
For now integrated as part of our perfetto.dev website (same hosting infra, same
build process). Use a different branch (blog) to host posts and images, similarly
to what we do for rfcs.
Design
Posts live on a dedicated
blogbranchAn orphan branch named
blog, exactly mirroring howrfcsworks today: flatdirectories at the root, no shared history with
main, and its own tooling if itever needs any.
The point is that writing a post never touches the code repository. A post is not
a code change, should not go through code review latency, and should not appear
in
git logformain. It also means post media does not accrete in the mainbranch's object store forever.
analyze.ymlonly runs the test matrix onmainanddev/**, so a PR againstblogfires no CI.blogis a real branch so that GitHub can open pullrequests against it — which is what makes guest posts and drive-by typo fixes
possible at all.
Source layout
At the root of the
blogbranch, one directory per post:post.mdcarries required front matter:authoruses the same@GithubHandlenotation asrfcs/template.md, whichmakes multiple authors free (
author: @stevegolton @LalitMaganti) and gives usthe avatar without a second field. The publish date is parsed from the directory
name; there is no
date:field to forget to update.Production layout
Two deliberate transformations happen at generation time:
byline, not to be part of a permalink. Correcting a wrong publish date should
not break inbound links.
/blog/media/<slug>/. This is not cosmetic. A POSIXfilesystem cannot hold both a file
blog/my-postand a directoryblog/my-post/, and the output tree is a real directory thatgsutil rsyncmirrors into the bucket. Hoisting media is what lets a post stay an
extensionless file like
docs/analysis/sql-tables, which in turn means theApp Engine proxy needs no changes — it only appends
index.htmltotrailing-slash paths and would otherwise 404 on a bare post URL.
Rendering
Posts are rendered by the existing
src/markdown_render.js, gaining a--mode=docs|blogflag.docskeeps every current value, so docs output staysbyte-identical; this is the first thing to verify.
Three behaviours are genuinely docs-specific and must be switched off:
/docs/are rewritten tosource.chromium.organdthen dead-link checked against the monorepo. A post linking to
/blog/other-postwould silently become a broken Chromium URL and fail thebuild.
/docs/. Posts need themedia/hoist described above instead.
docs/_nav.html. A post has no sidebar, andthe template references it unguarded, so rendering would throw.
Everything else is reused as-is: callouts, mermaid,
{#anchor}ids, code-copybuttons,
<?tabs>, and the../-forbidding link assertion.Front matter is parsed by ~20 lines of flat
key: valuehandling rather than anew npm dependency;
package.jsonhas no YAML parser today and this does notjustify adding one.
Index, feed and search
grid with the image on top. No pagination and no infinite-scroll JS: the markup
for a thousand posts is cheap, streams, and works with JavaScript disabled.
Images carry
loading="lazy"./blog/atom.xml, automatically geenrated, no dependency.Atom rather than RSS 2.0 because it is an actual specification: mandated
updatedtimestamps andxml:base, so dates and relative media URLs resolvethe same way in every reader.
gen_search_index.jsand the existing client-side ranking wholesale. Searchfrom a blog page returns only posts; from a docs page, only docs.
Card images
Every post gets an image, because a wall of undifferentiated text is a wall.
If
post.mdreferences an image, the first one becomes the card image.Otherwise the build generates one, in the flat, text-free, Google-palette
illustration language already used by
src/assets/ui.pngand friends.Generated covers are SVG, not PNG: vector, so they stay sharp on any
display; ~2 KB each; and emitted by ~200 lines of string concatenation, with no
rasteriser and so no new dependency. A PNG would mean adding an image library to
a
package.jsonthat today hasmarked,ejsandsassand little else, andwould bake in a fixed resolution.
The picture is a pure function of the hash of the title. From that hash we
pick, in order:
— nested slice tracks, a flame graph, scheduler lanes, async flows, sampled
columns;
The two-hue limit is the part that matters. Earlier drafts drew from the whole
palette at once and the results read as confetti at card size; constraining each
image to two hues at several brightnesses makes it read as a diagram instead.
Neutral greys are still used for baselines and lane rules, which are structure
rather than colour.
Text is never rendered into an image. Baking the title into artwork — as several
comparable blogs do — duplicates the headline sitting directly beneath it and
turns an index page into visual noise.
The generator runs once, at post-creation time, and its output is committed
into the post directory alongside
post.md. Regenerating on every build wouldmean retitling a post silently changed the cover of something already published;
committing it also makes the artwork reviewable in the same pull request as the
prose.
What we are deliberately not building
Tags, categories, reading-time estimates, a featured-post slot, a newsletter,
comments, and translations. Each can be added later if the volume ever justifies
it; none should be built before there is content to organise. Categories are the
most likely first addition.
Also, no dark mode. Not an oversight. Dark mode is a poor default for
long-form prose: a dark field dilates the pupil, which widens the eye's aperture,
degrades depth of field and amplifies optical aberration, so light glyphs bloom
into the background — worse at small sizes, and worst for the third to half of
adults with astigmatism. The positive-polarity advantage is well established:
Buchner & Baumgartner (2007, Ergonomics) found proofreading consistently better
with dark-on-light independent of ambient lighting; Piepenbrock et al. (2014)
measured pupil size directly and confirmed the causal chain; MIT AgeLab's Dobres
et al. (2017) found legibility worst of all for light-on-dark in dark rooms.
Readers cannot subjectively detect the deficit. Dark mode is fine for chrome,
UI, code and video — for a wall of prose it trades measurable legibility for an
aesthetic. The trace viewer can keep it; the blog will not have it.
Alternatives considered
Posts in the main repo under
docs/Pro:
Con:
main, with code-review latency.exactly the confusion that produced two case studies filed as docs.
refs/extra/bloginstead of a branchPro:
Con:
guest posts and external typo fixes.
dev/*branchesand 237 MB of objects, of which
docs/imagesalone is 52 MB.Keeping the date in the URL
Pro:
Con:
Media inside the post directory in production
Pro:
Con:
the App Engine proxy, which is deployed independently and rarely), or a
file/directory collision in the output tree.
A third-party static site generator (Jekyll, Hugo, Astro)
Pro:
Con:
code-copy buttons and dead-link checking that make Perfetto markdown what it is.
infra/perfetto.devis already a markdown-to-static-HTML generator. Themarginal cost of teaching it about a second content root is smaller than the
cost of running two generators.
Hotlinking GitHub avatars
Pro:
Con:
Fetching once at build time into
/blog/media/authors/keeps the published pagefree of third-party requests entirely.
💬 Discussion Guidelines:
All reactions