←back to thread

182 points evilpie | 1 comments | | HN request time: 0s | source
Show context
theandrewbailey ◴[] No.43630873[source]
CSP is really great at plugging these kinds of security holes, but it flummoxes me that most developers and designers don't take them seriously enough to implement properly (styles must only be set though <link>, and JS likewise exists only in external files). Doing any styling or scripting inline should be frowned upon as hard as table-based layouts.
replies(6): >>43630934 #>>43631184 #>>43631253 #>>43632334 #>>43633733 #>>43635528 #
chrismorgan ◴[] No.43631184[source]
> Doing any styling or scripting inline should be frowned upon as hard as table-based layouts.

I strongly disagree: inlining your entire CSS and JS is absurdly good for performance, up to a surprisingly large size. If you have less than 100KB of JS and CSS (which almost every content site should be able to, most trivially, and almost all should aim to), there’s simply no question about it, I would recommend deploying with only inline styles and scripts. The threshold where it becomes more subjective is, for most target audiences, possibly over half a megabyte by now.

Seriously, it’s ridiculous just how good inlining everything is for performance, whether for first or subsequent page load; especially when you have hundreds of milliseconds of latency to the server, but even when you’re nearby. Local caches can be bafflingly slow, and letting the browser just execute it all in one go without even needing to look for a file has huge benefits.

It’s also a lot more robust. Fetching external resources is much more fragile than people tend to imagine.

replies(4): >>43631249 #>>43631792 #>>43632338 #>>43632478 #
theandrewbailey ◴[] No.43632338[source]
It's called Content Security Policy, not Content Performance Policy. My thoughts:

1. Inlining everything burns bandwidth, even if it's 100KB each. (I hope your cloud hosting bills are small.) External resources can be cached across multiple pageloads.

2. Best practice is to load CSS files as early as possible in the header, and load (and defer) all scripts at the end of the page. The browser can request the CSS before it finishes loading the page. If you're inlining scripts, you can't defer them.

3. If you're using HTTP/2+ (it's 2025, why aren't you?[0]), the connection stays open long enough for the browser to parse the DOM to request external resources, cutting down on RTT. If you have only one script and CSS, and they're both loaded from the same server as the HTML, the hit is small.

4. As allan_s mentioned, you can use nonce values, but those feel like a workaround to me, and the values should change on each page load.

> Local caches can be bafflingly slow, and letting the browser just execute it all in one go without even needing to look for a file has huge benefits.

Source? I'd really like to know how and when slow caches can happen, and possibly how to prevent them.

[0] Use something like nginx, HAProxy, or Cloudflare in front of your server if needed.

replies(2): >>43632605 #>>43639858 #
bgirard ◴[] No.43632605[source]
> Source? I'd really like to know how and when slow caches can happen.

I don't have a source I can link to or share. But cache outliers are a real thing. If you aggregate Resource Timing results, you'll find some surprising outliers in that dataset where transferSize=0 (aka cached load on Chrome). You'll have users with a slow/contended disk where as they might have a fast link, but you'll also have the reverse where you'll have users with a fast cache and a slow network link (high latency, low bandwidth or both).

There's no universal answer here and I feel like the above poster tries to oversimplify a complex problem into one-size-fits-all answers. You'll have different users making up your distribution and you'll have to decide how you weight optimizations. This could very much depend on your product, the expectations and if your user are power users running a complex SaaS frontend, or a news site supporting a range of mobile devices.

A few years ago I traced and notice that Chrome has a pseudo O(n^2) behavior when pulling a bunch of sequential resources from its cache. I reported it but I'm not sure if it got fixed.

replies(1): >>43632670 #
1. theandrewbailey ◴[] No.43632670{3}[source]
> If you aggregate Resource Timing results, you'll find some surprising outliers in that dataset where transferSize=0 (aka cached load on Chrome).

I've been digging into the JS resource timing API. You've suggested a fascinating avenue for me to explore!