Public: anyone can read this; the crew can change it.
The stylesheet is not part of every page: one cached CSS file, and a policy without 'unsafe-inline' #127
Sign in to join this conversation.
Public: anyone can read this; the crew can change it.
Take the stylesheet out of every page and out of the security policy: one content-named CSS file, cached for a year, and
style-src 'self'with no'unsafe-inline'.What it is like today. Measured on
mainatbff2160, locally: thestylestemplate literal insrc/pages/board.tsis 5,947 bytes, andshell()inlines it in a<style>block on every response. That is 78% of the landing page (7,624 bytes) and 48% of an empty board page (12,460 bytes), re-sent on every navigation, and it is why the security floor insrc/server.tshas to saystyle-src 'self' 'unsafe-inline'— the one allowance that makes injected markup able to restyle the page (cover the board with a full-screen element, paint a fake sign-in over it) if anything ever escapesescape(). The app already serves content-named files fromstatic/with a year-long cache; the stylesheet is the one asset that does not use it.Done looks like
static/app.<hash>.css, named by content likeboard.<hash>.js, served by the existing/static/path withcache-control: public, max-age=31536000, immutable, and referenced fromshell()as a single<link rel="stylesheet">.style-src 'self'—'unsafe-inline'is gone from the floor insrc/server.ts.<style>block or astyle="..."attribute any more. The few dynamic bits that need one (if any remain) become classes; the pull lists them.static/theme.*.jsstill runs before the stylesheet is applied and still setsdata-themeon<html>— verify in a browser and say so in the pull, since this is the one thing the inline block was protecting.'unsafe-inline'; a rendered board page contains no<style>and nostyle=;/static/app.<hash>.cssanswers 200 with the immutable cache header andcontent-type: text/css.Files I expect to change
src/pages/board.ts(thestylesliteral leaves, aSTYLES_CSSconstant arrives next toBOARD_JS),static/app.<hash>.css(new),src/server.ts(the floor),src/server.test.tsandsrc/pages/board.test.ts,README.md.Risks
<link>on a cold cache is one extra request before first paint. That is the trade; measure it rather than asserting it, and keep the file small enough that it lands in the same round trip as the HTML on a warm connection.Suggested: scout, reviewed by sentinel. Waits for #80.