I trust the people who work on Chrome to make extremely well-informed decisions about performance. I don't actually need my battery to last more than 20 minutes anyway.
Really enjoyed this 203! Ada and Jake have different opinions and its good to hear each other perspectives. Interesting I and didn’t know about the dependency tree of CSS
I like to inline CSS (and JS) needed for the initial page load and possibly the very first likely interactions to keep it snappy, and asynchronously fetch the rest through JS + preload. It's always a tradeoff though, inline too much and caching takes a hit, inline too little and the first page load takes a hit.
I'm an developer for email marketing HTMLs. Because there's no external stylesheets, all our CSS needs to be in the head or inline, which was definitely something I had to get used to coming from a webdev education background!
The issue isn't putting a link to a stylesheet at the top. The problem is bloatware of people using frameworks to display a simple page. The whole idea of having the stylesheet at the top is to make sure the page displays properly as it streams in, rather than a hot mess. Increase in internet speeds have made people lazy and they don't care how much unused code there is.
I think it's just changed priorities. Things are faster so you can focus on other things that matter more to users like having a working site in the first place
If you have 2Mb of CSS you are using it wrong, basically. Knowing the CSS selectors and how to use them will lead to a great reuse of code (and that also simplify the development process), but often I see, especially from people using framework like React and similar, that they use a CSS rule for each HTML element! That is not what CSS was designed to do! It will lead to a ton of repetition, and of course your page would be slower to load since not only all that code needs to be downloaded but it also needs to be parsed. Another cause that will lead to huge CSS files is using frameworks such as Bootstrap or similar, and then having to define a ton of rules just to override the framework behaviours. Writing CSS from scratch is really not that difficult, especially if you want to target modern browsers (you exclude Internet Explorer, that to these days it's something fine since it's mostly irrelevant) and thus you can use modern features of CSS such as grid or variables. In using CSS I tend to first style all the basic HTML elements, and then define rules to style particular cases (that should be particular). That way I maintain the semantics of HTML (that is important for a ton of reasons, for example accessibility) and the CSS file remains very compact and fast to load. Also it's easier to maintain consistency throughout the whole website.
The site in question probably included one or more complete css frameworks. Because, as you could see, 97% or whatever was completely unused. With a properly configured build system you would tree shake away unused CSS.
This is quite common with Angular apps where because of View Encapsulation there is a CSS file per component, and is specific to that component using attributes for tying the HTML and CSS together. It avoids CSS authored for one component having unintended consequences for the rest of the application which is also solvable using improved selector specificity of course with View Encapsulation turned off. I dont fault the feature, it does something sensible, but I find awareness is very poor and how to technically design web sites and applications to avoid this situation. I find the need for Angular web developers to understand web performance and how to use dev tools effectively is amongst the greatest amoung the web frameworks.
On a "modular webpage", like a page build within a CMS, how can you determine what css you need in you block? Or would you load multple tags throughout your page?
Probably the first time I'm gonna stay skeptical about Jake's arguments. I do use inline styles but only on very essential rules, rest of the styles will remain in .css and per page or component bases and load these on demand. And i do want to utilize cache, and i use file hash as a cache key. So if i modify a file and i rebuild the app, only built files with actual changes will have new hash for cache key. Rest of the app/page will still be loaded from cache.
The problem with the new hash thing… let's say you change an image. It changes hash. That image is referenced by a CSS resource, so it needs to change hash too. That CSS resource is imported by a JS module, so that needs to change hash too. As does the parent module etc etc. One small change can (in a correctly-build build system) knock out an entire tree. Things like import maps can help here, of course. What do you mean by "essential rules"? There's really no point in inlining some stuff if you have other CSS that's blocking render. If you're talking about inlining "above the fold" stuff and lazy loading the rest, then I don't agree - "above the fold" is very inaccurate, and often results in a flash of unstyled content. If by "essential rules" you mean the stuff that's needed for first paint, then that's what I'm proposing in this video.
I feel cache problems are severely escalated on mobile because there is no trivial way for users to selectively 'hard refresh' the Chrome cache for a particular website, they must wipe EVERYTHING - if a site is improperly configured for cache there is no work around.
@@yaboirairai Holding the refresh button seems to act differently than normal refresh (page loads seem to take longer compared to normal refreshing). So it seems to do what you're talking about. Just did a couple simple tests though, didn't look it up
I see the argument with caching not working on changes or after a longer time. But certainly when the user is surfing around on your page, the cached CSS is definitely used. If I include the stlye in html, it will have to be loaded every time I get the new page.
As an OG CSS head who cares about well invested time - @ Jake don’t bother with The Matrix 4. If you do happen to watch it, chances are this comment will stick like a splinter in the mind
I have multiple CSS files but the server-side code compiles them into 1 and then embeds them directly inside a tag. For JavaScript I actually like modules and asynchronous loading of multiple resources because 99% of my JS is not render-blocking but since CSS is necessary for the page I think inline CSS just makes the most sense. What I hate is bundling. I either don't bundle (let my code concatenate the CSS files each time) or I do something I guess you could call JIT bundling: The code checks the CSS files to see if any of their modification dates is newer than the created date of the bundled file, if so it re-compiles and saves the bundle file, if not it just serves up the bundled file contents. This might seem odd but it allows the website to be development-environment-agnostic. If someone needs to make a change but doesn't have our exact development environment, they can do so without having to download our IDE and a bunch of dependencies required to execute the bundling.
I like the idea of web bundles. I’ve spent loads of time tweaking my react apps with different code splitting, cache rules, preloading, etc. to get the performance just right, but that could all be taken care of with this idea, and drastically simplify the process.
The web is broken. Load page -> content appears -> cookie msg pops-up (you press accept anyway) -> start reading -> blank space while ads load -> everything jumps around -> *give up due to bad user experience.* Let's just go back to how it was 17 years ago.
Not to mention the ads, cant show any content the user actually want before the ads are shown you know, and what about the Adblocker blockers, and the adblocker, blocker blockers etc. Sorry if I went or here.
That 7mb .js file must be part of some sort of single page app. The css you serve needs to cover any sort of changes to the dom before the next reload. How would you stream in those styles as needed if you don't just provide them all up front?
What is the answer to Ada’s question at 11:51? To summarize, what allows just the necessary css to get bundled with the html? Is that right? Wouldn’t css-in-js do that by relying on js to scope the css? What specifically are the "build tools" you're using to create a better experience that are related to this question?
In stuff I've built recently, I use Rollup to import the CSS into my static build, and I only do that for components that are part of the static build. It doesn't do any stylesheet analysis - I haven't found those tools to be reliable.
I do both, some smaller css/js is inlined, also the early css sometimes or if cache is not needed, which I never rely on anyway before a website is live. The file size of fonts is usually the biggest problem I think. Laziness keeps me loading too much everywhere, someday I will be better at dividing code so that it's more "live dependant only". Also, I rarely "purify". and "minimize" is never needed I think.
I refuse to believe the 6MB of JavaScript was written by a human. It must be something generated by a script or some monstrosity transcribed into js from python, c or whatever the cool kidsuse these days. 2MB of css? Well, yeah, I can see how that could happen. It wasn't me, it was already like this when I started!
@@jevvir can you give an example? What's the alternative? If you want a svg on the page when it loads aren't you going to need to include it? Is that really bloat?
@@DrewIsFail Well, svg could be inlined in HTML, or it could be embeded via img tag. Of cource for some of the svg it makes sense to put these into css, it all depends what kinda of role svg plays. I'm not against svg in css, i'm just saying if you use lot's of svg in styling and these svg's may have variations depending on a state (not easy to change styling of svg if it's included in css). I'm just saying, that svg and raster images in css or javascript may contribute big time to final file size.
My phone has a billion hearts and several billion bits of memory, and hundreds of billions of bits of storage. 3 seconds load time for a website is unacceptable
Thank you for vocalizing what I was thinking. We have the capacity for sub-second page load times. But we seem to be trying as hard as we possibly can to create inefficient and difficult to use technologies (*cough*SPA*cough*) to make the web as slow as possible.
@@jakearchibald Unless you’ve got it down to 28.8K modem speeds, I can’t imagine how that could possibly be the case. I’ve deployed sub-second applications since around 2011, after chasing the IBM reps out of my business for having the exact same reaction. It’s really not that hard once you decouple content load and data load. We had a few places where the user would have to wait on a spinner up to 5 seconds for thousands of rows of data to download for the analytics components, but the user already had a fully loaded and usable page. If you set your constraints as “download a megabyte or more of CSS/JS”, then I see where you’re coming from. Though I would vehemently disagree with the premise. If you want a good user experience, your application should be designed from the ground up to be as tight and usable as possible. Which is something most developers don’t really do anymore, preferring to foist incredibly heavy frameworks on users because they’re “cool” or something. Which, BTW, I also fundamentally disagree that web frameworks have in any way made developer’s lives better. Just the shear complexity of what we’ve pushed on to developers has made for an all around, objectively worse experience for all. It’s really all the same mistakes we made with “MVC frameworks” on the server side, all over again.
@@jakearchibald Let me make sure I’m following, since it wasn’t clear to me in the video: You’re measuring specifically the time to user value on a 3G connection where you expect 2+ seconds of time to be initial setup time to communicate with the desired server? Given that we’re talking about a standard that is literally being shut down and phased out, that doesn’t seem terribly useful. I could see measuring low _speeds_ (e.g. 50KB/sec), but I’m struggling with the purpose of an end-to-end 3G test in 2022?
Funny, I was just thinking for hours about this topic for my webapp minicraft (sorry, yt keeps deleting the link) and my fazit is to try to keep the js/css as small as possible, reference them from html by hash (=commit id). I think waiting some milliseconds for the app to load is no problem and it is more important to save our ressources (less network traffic and computations). I am really thinking a damn lot about this topic and it is such a complex problem and I see so many different ups and downs on most approaches... But yes, for me my aim is to minimize the transferred data and the distance the data needs to be transported over.
HTTP/2 Push really needs to be Developer accessible. I have _NO_ idea how to make it work with nginx, or php, or rust's hyper server. There is a complete lack of documentation when it comes to the actual implementation at the developer level on how to actually implement this. I would choose it, if I knew how to use it.
@ Jake the issue that the image stole the bandwidth from the CSS file might be due to the on-the-fly gzipping of the css file from the server(ref: 8:56)? So, serving pre gzipped css should (theoretically) fix it, right? Then again a 20kb css will still arrive later than a .5kb png that was requested few hundred ns after the css, assuming the connection is h2/h3, so does it really matter that an image was fetched before the css?
As index.html is usually not cached maybe it is unwise to bloat it with CSS. Inlining CSS in JS for the final build is ok, but beware of doing it for some reusable components as frameworks like Next.js will have issues with SSR.
@@jakearchibald yes, and I think I understand the reasoning but maybe it's not applicable to apps where daily returned visit rate is high like news, productivity, etc. Than you'd be missing on cache hits.
@@jakearchibald that's a good question, maybe the first time visit performance outweighs additional payload on repeated visits. I really liked "fastest http connection is one that isn't made at all".
you should only render css that the page needs. lots of sites are bloated with libraries. you should also talk about compiling and bundling css and what the differences are.
One thing I never notice is the load speed of like 95% of websites when browsing. This is one of those problem developers care about but hardly anyone else.
I have been thinking about this. I’m a CSR nerd and I recently started taking advantage of suspense in React and now I split my bundle on a page by page basis. So when a user navigates to a new page the css and js necessary for that new page is downloaded while a fallback component is shown to the user and the fallback component is animated in just as if the page were already loaded. FCP and TTI saw huge improvements but I wondered if this was what SSR was trying to fix and now I can do it in CSR, does the user care?
@@nxte8506 I don't think they do, I mean the amount of time a user spends closing pop-ups for ads or cookies to get to some website content, then you're worrying about things that you need DEV tools open to measure, you're probably just making jobs for yourself for your own pleasure of shaving milliseconds off paint times.
There cannot be a way to determine what CSS is needed for a specific site, because Javascript is turing complete and solving this would probably solve the halting problem. How would you know what elements the javascript inserts into the DOM? What if it requests an XML from an external server and then inserts that into the HTML? You cannot know in advance what elements will be inserted.
I think advanced tooling needs to be made where like the suggest at the end. For any page (or maybe critical pages). This would require page virtualisation and would only really be done on like production builds.
I use Webpack to bundle everything that is repetitive (reset, global styling, components) but have individual css file per page (and JS) and I'm only loading vendor (libraries) on page that need it.
I feel like this should've been solved by the build tools we have already. But inlining vs external file is something I still can't decide on. I like how in a SPA you have the css needed for the components that are currently rendered in a bundle and the rest is loaded as the user navigates around.
What I always prefer is to have inline css on demand, like what needs to be seen on the page by the user first. Then have the general utilities in an external bundle. Depending on its size I can opt to preload or/and cache it. Caching has its problems specially on mobile since user cannot do hard reset on their browser app, and that's where the css hashing comes in.
Depends on the framework and tooling you use. In recent sites I've built, I use Preact on the server/static build. I use Rollup to catch an import to some CSS, which processes it using postcss then gives me the source as a string, which I can add to a style element.
A big CSS file for me is maybe... 20 KB? That's for the entire site. With modern HTTP, the differences between inlining or not are in milliseconds. I just serve it as an external file which can then be reused from cache when the user visits other pages in the site. There are much bigger fish to fry when aiming at performance. Like they mentioned at the end, those multi-megabyte pages with bloated JS, text displayed as images, and stuff like that.
A basic, nonetheless very interesting topic. Great discussion, great video! I have to agree with Jake in regards to Web Components and H2Push. H2Push is cursed; one of many reasons is, that web authors (and their tools) and Admins managing web server configuration are too often too far apart. With Web Components there is a JS dependency, just put the CSS in the JS, there is no usage for it without the JS anyway. But inlining CSS only makes sense to me, if changes to CSS happen quite frequently or it is very different between the individual pages. Otherwise, I'd argue, put all CSS in one file with a hash in the filename, then let service workers, browsers, CDNs cache it. Tradeoff: first visit takes a little bit longer, all further requested HTML is shorter without CSS in there, including revisits. What about people who clear their cache very often? People who clear their caches don't get peak performance. What about external CSS that is not yet cached, that can be slowed down by loading of other resources? Lazy load all JS and all images. What about images above the fold? Lazy load ALL the images! Hot take: if quickly showing an image is essential to your above-the-fold-content, you're probably doing it wrong. ("essential" as in: not worth showing without) Again great video. Triggering, I mean - uh - thought provoking. Edit: Since CSS can override the display value even for (attribute) hidden elements, a defer attribute to load external stylesheets asynchronously might be an improvement in terms of not blocking content. But, afaik, for this there are only JS-dependent workarounds as of today.
What would help is having tool recommendations to make it easier. There's no reference to how you are pulling the CSS and inlining it, or how you'd load only CSS specific per-page.
I feel like the concerns about caching were too easily discarded based on only the "user comes back later, but things may have changed" scenario. Return visits aren't the only reason things are cached. Sure, if you're writing a news/article site where you know most users read one page then leave, it's fine. However not all sites are like that, other sites have users navigating between pages or opening multiple tabs. If the user ever navigating back to a page they visited in the same session, or to another page with the same layout, is expected. Then the cache isn't going to have been cleared, it's still going to be useful.
I'd argue that it is not optimal for repeat loads of that page or other pages using the same styled components. For general e-commerce sites a user visits 4 pages on average. This video grossly understates the benefits of caching.
Good presentation, but, I'm irked by the inaccuracy of saying this is "inline" CSS. You are talking about embedded CSS. Inline CSS would be where you add styles to the style attribute of an individual HTML element. Embedded CSS is CSS in a style block. (And external CSS is CSS linked via an external file.)
I don't think your definition of "inline" is particularly universal. For instance, the CSP spec w3c.github.io/webappsec-csp/#style-src-inline (a W3C web standard) uses 'inline' to mean roughly "not external", which is how I was using the term in the video. So, if I'm using the term in a way defined by a W3C-sanctioned standard, it seems unfair to say I'm using the term inaccurately. Maybe you know a spec that defines it differently?
Jake, I would really like you to make another good flame war about utility-first CSS (you know the one with die-hard 1D fans). It's gonna be lit. I know you're gonna wind up with some interesting arguments.
Front end is the front line. Designers need to get over their hang ups about coding and get in there to save CSS before full-stacks squash it into oblivion.
I feel like the way Jake is presenting the 'simplicity' of inlining the CSS is overlooking where the actual complexity lies. He talks about no longer having to figure out what things to put in which CSS file, but you (or a bundler) still has to figure out which CSS goes with which page. The difficult bit is figuring out what CSS is essential for a particular page. Once you've figured that out, I'm not very convinced inlining that CSS is actually that much simpler than putting it in a CSS file. I think Ada makes a great point about having a bit of an audience mismatch here. Sure, if you have the team and time to hyper-optimize a page, inlining CSS might be worth looking into. Especially if you limit that CSS to only the first-render (or maybe even only above the fold) content. But if you're shipping multiple MBs of CSS, inlining is probably not the best place to start. PS: I'm really enjoying the episodes with Ada so far!
I think, once you've identified exactly what CSS the page needs for a first render, dumping that out to a different file seems like an extra unnecessary step, and comes with a performance penalty.
@@jakearchibald I get where you're coming from. If think that given those 2 assumptions (you've identified the CSS and there is a performance penalty) I would probably agree with you. I would be interested to see a more thorough review of how negligible the caching of CSS files really is. I get that you can only get into so much detail in a youtube video, but I wasn't entirely convinced that it's really a factor we should disregard. The benefit caching gives you also really depends on how well you split up the CSS files, separating the bits that change often from the more long-term styling. I'm also wondering if the 2 examples you mentioned, the BBC and The Guardian, may be a bit of an outlier in terms of CSS because of their nature as a newsroom. They often develop interactive experiences for just a single story/page that a user is likely to only visit once. It would be interesting to hear how much that was part of why they chose this inlining pattern.
If you in-lined the styles wouldn't only those needed be loaded? I don't understand why we're thinking in terms of "page" that's not the smallest unit of composition we work at... Is it?
@@DrewIsFail I'm not sure I 100% understand your question. I'll elaborate a bit what I mean by the difficulty in 'figuring out what CSS is essential for a page'. This is just my personal experience on the type of projects I've worked on, not necessarily saying this applies generally. The frontend source of projects I've worked on were often split up per section or component. An example with sections: I worked for a news outlet where journalists could write stories in a CMS out of 'blocks'. Each of these blocks consisted of some HTML and CSS, and sometimes some JS. The backend would then concatenate those blocks into a story and serve that as a page. The tricky part there was that there was sometimes a lot of repetition between those blocks because of common UI elements. So you would either ship duplicate code with your page or there needed to be more complex tooling that did something more clever than simple concatenation. The other type I've worked on a lot are JS component frameworks with server-side rendering, where the styling was either CSS-in-JS like styled-components or there was a small .css file imported by every component. In particular I did a lot of React but lately I'm very excited about what Svelte is doing with SvelteKit. For the first page load, a node.js server would either render the page on the fly or when possible there was some tooling that pre-compiled components into static HTML pages. There was a considerable amount of complexity on the server side keeping track of what components were being used while rendering, and then determining what CSS needs to go with that. A lot of the newer isomorphic JS frameworks take care of that quite well nowadays, but I feel it often still takes a lot of configuring to get everything right.
@@flutflo My question wasn't specific enough for an answer, so I appreciate the general feedback. Let me try and elborate, i'm not directly replying to your ideas at this point, just trying to set some foundation for myself. the fundamental smallest unit of CSS is the property key and the property value. e.g "font-size" "12px". Ideally, according to some business goal, we load those properties as needed. As we have discussed there are trade offs between package size, original load time, and successive loads. No performance plan really makes sense without context. I think were all plans suffer though is that 1. style sheets (.css) files, operate a higher level then key and value. Then munge the key into the value. And then give us tools that aren't very explicit about changing the value. That's the cascade order and inheritance system. it's like updating a variable in your programming language by constantly re-declaring it. 2. styling an application is as dynamic, and complicated a task as other functions of an application. Yet CSS as a PL is lacking. The reason css-in-js is attractive is because it means we can use a more expressive language (js) and less tools (.css/sass/etc...). If there is no downside to inline styles, if in fact, on average they are faster because they lead to leaner packages sizes because they are easier to compse using JS, then i feel like this is a potential huge win for the community and something we need to embrace. some css-in-js solutions will let you express styles in line then create a stylesheet, i'm not even sure this is a win?
@Jake Archibald By inline styles, do you mean each HTML attribute gets a style attribute? Or are you just including one style tag that contains all the style properties.
@@jevvir you would have to do that for certain functionality. Keyframes and such. But then you can't keep css more local to where it's used and have to use css classes. Also, calling that inline styles is really really confusing.
@@hrgwea if your storing the css directly on the tags that would be true any place it repeated. Of course, i think it might not matter that much, especially for the first page load, and it would mean you didn't risk un used styles. If your building a spa, with js, then the shared css might be stored in the js, so there wouldn't be more bloat right?
It would be nice if pages could be crawled/analysed and a subset of the css styles served per page. Server side prepares a cache of these cut down, static clones of the css, maybe the first time that page is served, and from then on sends a few k instead of several mb. Obviously dynamic content has a big impact here; I wonder if in an awful lot of the most common cases would be covered.
The thing is very simple. If a product is good the users will return and no one will recall how many seconds took the first render on the first visit. But if a product is a pure crap, no one will appreciate the short first time render time.
I don't think this is fully true. There are websites you have the option of going to and some you MUST go to. On those you really notice how good our bad they are.
Performance isn't the only element of UX, true, but you should look up some case studies on this stuff. They consistently show that faster performance leads to more engagement. Also, it's worth thinking of folks who don't have as powerful a device as you, or as fast of an internet connection as you.
My first office job was creating templates for an intranet. Not only did they have to work in IE6, but they also had to render nicely in Frontpage, which used a different rendering engine at the time. Frontpage didn't support 'strict' mode, so yeah, quirks mode was the best option to make IE6 and Frontpage render similar 😀
@jake I wonder what do you recommend in large websites where the page is dynamically rendered, and has a lot of is/jQuery modifying the page layout (adding CSS classes, creating menus, etc). the page would seemingly be missing a lot of CSS that could not have been discovered? also when the HTML is gigantic (like a product listing page) and streaming chunks already exceed the maximum chunk size? this pattern only seem feasible in small static sites?
If the styles are only used after JS modifies the page, the styles should be bundled with the JS. I think this pattern is great for big sites - that's why it's being used in the wild by sites like The Guardian and SmashingMag
I don't usually go that far, unless a particular client required a ton of CSS that most clients didn't need. The point is to avoid serving CSS for a component that doesn't exist on the page. Unfortunately the majority of the web does this.
@@jakearchibald ahhh! But what difference does it make if it's inline css or external? Wouldn't it even be easier to have component css in separate files and then the server decides which files to link according to which components are being used?
That "server knows what the client probably has cached" sounds like a horrible tracking method but users should be able to allow this feature. (opt-in)
@@jakearchibald yes you pointed that out. But a cache miss would be less personal than some kind of unique identifier. Yes, there could be a simple "last visited" timestamp sent by the client or at least a "first-time visit" flag, no unique identifier needed...
@@l3p3 a cached resource can contain a unique identifier. I don't see why you're wanting this to have a stricter model than the rest of the HTTP cache. All of the existing privacy mitigations would work exactly the same here.
With newer HTTP versions, it gets less important, as one request can ask for several files at once and the server can send dependencies together without the client even asking for them yet!
Jake there's probably an easy way out of the big several megs CSS file: install a tool that parses and inlines the CSS per request, exactly as you said (or caches it) It exists already, too ;) And if memory serves, it was published by Google folks, if not the official entity
Looking at the coverage tab of this very page it's pretty much the same scenario, JS of 8MB almost all unused, CSS of 2MB almost all unused. Sure, things can be improved but if the big companies aren't optimising their own sites, is this really an issue?
@@jakearchibald Not entirely sure I'd agree. But I haven't tested it fully myself. My test only went as far as to break up one large json file containing blog post data into smaller json files, then use h2, brotli, etc (all the good stuff), and size and speed were markedly improved. But I also inline my CSS as part of components, and don't load any images at all (except for the logo of course) unless the visitor clicks to see them. In one example I went from a 25.9kb file down to 418b. And that was typical across all the json files; nothing with less than a 90% reduction.
@@brymstoner one combined compressed file will always be smaller than split files individually compressed. If you're seeing something different, something is going wrong somewhere.
@5:50 the problem wity css is that it is difficult to refactor design updates. Changes end up being added and old cruft left to rot. There’s too much voodoo involved.
This episode is going to end friendships
And create new ones
I love how they don’t always agree. It makes it more interesting.
I trust the people who work on Chrome to make extremely well-informed decisions about performance. I don't actually need my battery to last more than 20 minutes anyway.
Really enjoyed this 203! Ada and Jake have different opinions and its good to hear each other perspectives. Interesting I and didn’t know about the dependency tree of CSS
Hiya Hussein! Really enjoyed your recent deep-dive into DNS. Cheers!
I like to inline CSS (and JS) needed for the initial page load and possibly the very first likely interactions to keep it snappy, and asynchronously fetch the rest through JS + preload. It's always a tradeoff though, inline too much and caching takes a hit, inline too little and the first page load takes a hit.
The fewer the files you have to open, the faster loading goes.
Also people with slow internet can visit the site without having to wait for the css etc. download
@@lawrencedoliveiro9104 then bundle but inline JS is just the worst
I never use onclick ever because it's unpredictable from thehe rest of the JS code
Yup it is good until it grows big.
Good luck maintaining that.
@@anonymunsichtbar3715 老婆视频😂呵🌞
I'm an developer for email marketing HTMLs. Because there's no external stylesheets, all our CSS needs to be in the head or inline, which was definitely something I had to get used to coming from a webdev education background!
Learned that email pages do not support css files the hard way just a few weeks back. I have been doing UI for over 5 years now 😂
And I learned the hard way that the Outlook Desktop App accepts almost no CSS instructions at all xD
The issue isn't putting a link to a stylesheet at the top. The problem is bloatware of people using frameworks to display a simple page. The whole idea of having the stylesheet at the top is to make sure the page displays properly as it streams in, rather than a hot mess. Increase in internet speeds have made people lazy and they don't care how much unused code there is.
I think it's just changed priorities. Things are faster so you can focus on other things that matter more to users like having a working site in the first place
I love this kind of video, this format and the conversation, great job!
5:27 For those interested: It is Ferrari and I am glad that their car is more performant than their website this year. :D
My question is what the other team Jake used as an example.
Great talk Ada from Samsung Internet and Jake NOT from Samsung Internet
If you have 2Mb of CSS you are using it wrong, basically. Knowing the CSS selectors and how to use them will lead to a great reuse of code (and that also simplify the development process), but often I see, especially from people using framework like React and similar, that they use a CSS rule for each HTML element! That is not what CSS was designed to do! It will lead to a ton of repetition, and of course your page would be slower to load since not only all that code needs to be downloaded but it also needs to be parsed.
Another cause that will lead to huge CSS files is using frameworks such as Bootstrap or similar, and then having to define a ton of rules just to override the framework behaviours. Writing CSS from scratch is really not that difficult, especially if you want to target modern browsers (you exclude Internet Explorer, that to these days it's something fine since it's mostly irrelevant) and thus you can use modern features of CSS such as grid or variables.
In using CSS I tend to first style all the basic HTML elements, and then define rules to style particular cases (that should be particular). That way I maintain the semantics of HTML (that is important for a ton of reasons, for example accessibility) and the CSS file remains very compact and fast to load. Also it's easier to maintain consistency throughout the whole website.
good point
For React, I think it includes just the Css for that page, not for all pages.
The site in question probably included one or more complete css frameworks. Because, as you could see, 97% or whatever was completely unused.
With a properly configured build system you would tree shake away unused CSS.
This is quite common with Angular apps where because of View Encapsulation there is a CSS file per component, and is specific to that component using attributes for tying the HTML and CSS together.
It avoids CSS authored for one component having unintended consequences for the rest of the application which is also solvable using improved selector specificity of course with View Encapsulation turned off.
I dont fault the feature, it does something sensible, but I find awareness is very poor and how to technically design web sites and applications to avoid this situation. I find the need for Angular web developers to understand web performance and how to use dev tools effectively is amongst the greatest amoung the web frameworks.
On a "modular webpage", like a page build within a CMS, how can you determine what css you need in you block? Or would you load multple tags throughout your page?
Probably the first time I'm gonna stay skeptical about Jake's arguments. I do use inline styles but only on very essential rules, rest of the styles will remain in .css and per page or component bases and load these on demand. And i do want to utilize cache, and i use file hash as a cache key. So if i modify a file and i rebuild the app, only built files with actual changes will have new hash for cache key. Rest of the app/page will still be loaded from cache.
All the same here 🙏 it's good to see their view nonetheless but yeah I don't agree with him at all.
The problem with the new hash thing… let's say you change an image. It changes hash. That image is referenced by a CSS resource, so it needs to change hash too. That CSS resource is imported by a JS module, so that needs to change hash too. As does the parent module etc etc. One small change can (in a correctly-build build system) knock out an entire tree. Things like import maps can help here, of course.
What do you mean by "essential rules"? There's really no point in inlining some stuff if you have other CSS that's blocking render. If you're talking about inlining "above the fold" stuff and lazy loading the rest, then I don't agree - "above the fold" is very inaccurate, and often results in a flash of unstyled content. If by "essential rules" you mean the stuff that's needed for first paint, then that's what I'm proposing in this video.
@@jakearchibald don't keep images that change often in that file then. Problem solved.
I feel cache problems are severely escalated on mobile because there is no trivial way for users to selectively 'hard refresh' the Chrome cache for a particular website, they must wipe EVERYTHING - if a site is improperly configured for cache there is no work around.
Firefox has shift-refresh, I think.
@@lawrencedoliveiro9104 on mobile???
@@yaboirairai Holding the refresh button seems to act differently than normal refresh (page loads seem to take longer compared to normal refreshing). So it seems to do what you're talking about. Just did a couple simple tests though, didn't look it up
I see the argument with caching not working on changes or after a longer time. But certainly when the user is surfing around on your page, the cached CSS is definitely used. If I include the stlye in html, it will have to be loaded every time I get the new page.
As an OG CSS head who cares about well invested time - @ Jake don’t bother with The Matrix 4.
If you do happen to watch it, chances are this comment will stick like a splinter in the mind
I have multiple CSS files but the server-side code compiles them into 1 and then embeds them directly inside a tag. For JavaScript I actually like modules and asynchronous loading of multiple resources because 99% of my JS is not render-blocking but since CSS is necessary for the page I think inline CSS just makes the most sense. What I hate is bundling. I either don't bundle (let my code concatenate the CSS files each time) or I do something I guess you could call JIT bundling: The code checks the CSS files to see if any of their modification dates is newer than the created date of the bundled file, if so it re-compiles and saves the bundle file, if not it just serves up the bundled file contents. This might seem odd but it allows the website to be development-environment-agnostic. If someone needs to make a change but doesn't have our exact development environment, they can do so without having to download our IDE and a bunch of dependencies required to execute the bundling.
Long live the tag. I solute you comrad!
I like the idea of web bundles. I’ve spent loads of time tweaking my react apps with different code splitting, cache rules, preloading, etc. to get the performance just right, but that could all be taken care of with this idea, and drastically simplify the process.
The web is broken. Load page -> content appears -> cookie msg pops-up (you press accept anyway) -> start reading -> blank space while ads load -> everything jumps around -> *give up due to bad user experience.* Let's just go back to how it was 17 years ago.
Good thing about css: it make things organised. Bad thing about css: you need extra people in your development team.
I think in order to keep things simple, having a tool that minifies, concats everything and inlines everything is absolutely the best.
Why not have a parser that parses .css into inline?
Not to mention the ads, cant show any content the user actually want before the ads are shown you know, and what about the Adblocker blockers, and the adblocker, blocker blockers etc. Sorry if I went or here.
That 7mb .js file must be part of some sort of single page app. The css you serve needs to cover any sort of changes to the dom before the next reload. How would you stream in those styles as needed if you don't just provide them all up front?
The changes to the DOM will be done by JS, so the styles of things that can only be revealed by JS should be bundled in the JS
@@jakearchibald Thanks. It helps to see that the JS provides the styles for changes that could have only happened from that JS.
What is the answer to Ada’s question at 11:51? To summarize, what allows just the necessary css to get bundled with the html? Is that right? Wouldn’t css-in-js do that by relying on js to scope the css?
What specifically are the "build tools" you're using to create a better experience that are related to this question?
In stuff I've built recently, I use Rollup to import the CSS into my static build, and I only do that for components that are part of the static build. It doesn't do any stylesheet analysis - I haven't found those tools to be reliable.
One of the best shows yet.
I do both, some smaller css/js is inlined, also the early css sometimes or if cache is not needed, which I never rely on anyway before a website is live. The file size of fonts is usually the biggest problem I think. Laziness keeps me loading too much everywhere, someday I will be better at dividing code so that it's more "live dependant only". Also, I rarely "purify". and "minimize" is never needed I think.
I refuse to believe the 6MB of JavaScript was written by a human. It must be something generated by a script or some monstrosity transcribed into js from python, c or whatever the cool kidsuse these days. 2MB of css? Well, yeah, I can see how that could happen. It wasn't me, it was already like this when I started!
One way to bloat your css/js is to include images in them, both svg and raster (using base64), i've seen it :)
@@jevvir can you give an example? What's the alternative? If you want a svg on the page when it loads aren't you going to need to include it? Is that really bloat?
@@DrewIsFail Well, svg could be inlined in HTML, or it could be embeded via img tag. Of cource for some of the svg it makes sense to put these into css, it all depends what kinda of role svg plays. I'm not against svg in css, i'm just saying if you use lot's of svg in styling and these svg's may have variations depending on a state (not easy to change styling of svg if it's included in css). I'm just saying, that svg and raster images in css or javascript may contribute big time to final file size.
@@jevvir thanks for the follow up
It's really simple....if you're using php or c#, just write the css from a file into the html page before serving it to the Dom
But if your css is really big, your caching ratio will get horrible and you are resending a lot of code all the time...
@@l3p3 idk. Why would your css data be needlessly big? Drop the premade frameworks and learn how to use vanilla css
@@l3p3 did you watch the bit in the episode about caching?
My phone has a billion hearts and several billion bits of memory, and hundreds of billions of bits of storage.
3 seconds load time for a website is unacceptable
Thank you for vocalizing what I was thinking. We have the capacity for sub-second page load times. But we seem to be trying as hard as we possibly can to create inefficient and difficult to use technologies (*cough*SPA*cough*) to make the web as slow as possible.
@@thewiirocks at the connection speeds used in these tests, sub-second is impossible unless you're using a service worker to make it offline-first.
@@jakearchibald Unless you’ve got it down to 28.8K modem speeds, I can’t imagine how that could possibly be the case. I’ve deployed sub-second applications since around 2011, after chasing the IBM reps out of my business for having the exact same reaction. It’s really not that hard once you decouple content load and data load. We had a few places where the user would have to wait on a spinner up to 5 seconds for thousands of rows of data to download for the analytics components, but the user already had a fully loaded and usable page.
If you set your constraints as “download a megabyte or more of CSS/JS”, then I see where you’re coming from. Though I would vehemently disagree with the premise. If you want a good user experience, your application should be designed from the ground up to be as tight and usable as possible. Which is something most developers don’t really do anymore, preferring to foist incredibly heavy frameworks on users because they’re “cool” or something.
Which, BTW, I also fundamentally disagree that web frameworks have in any way made developer’s lives better. Just the shear complexity of what we’ve pushed on to developers has made for an all around, objectively worse experience for all. It’s really all the same mistakes we made with “MVC frameworks” on the server side, all over again.
@@thewiirocks connection setup time on things like 3g is long. Look it up 😀
@@jakearchibald Let me make sure I’m following, since it wasn’t clear to me in the video: You’re measuring specifically the time to user value on a 3G connection where you expect 2+ seconds of time to be initial setup time to communicate with the desired server? Given that we’re talking about a standard that is literally being shut down and phased out, that doesn’t seem terribly useful. I could see measuring low _speeds_ (e.g. 50KB/sec), but I’m struggling with the purpose of an end-to-end 3G test in 2022?
Good DX leads to fast live deploys and quick fixes in live env. IMO. I dont think DX and UX are directly related.
I like these conversations. I learnt how to be a web dev "with the time"
skip the 404 episode, so it would make 404 not found plz plz plz
Funny, I was just thinking for hours about this topic for my webapp minicraft (sorry, yt keeps deleting the link) and my fazit is to try to keep the js/css as small as possible, reference them from html by hash (=commit id). I think waiting some milliseconds for the app to load is no problem and it is more important to save our ressources (less network traffic and computations). I am really thinking a damn lot about this topic and it is such a complex problem and I see so many different ups and downs on most approaches... But yes, for me my aim is to minimize the transferred data and the distance the data needs to be transported over.
at this point, maybe we should be developing our sites in a different language than we're serving to people, even for the basic markup.
You could say this happens already. JSX isn't JavaScript. SCSS isn't CSS. CSS modules aren't CSS etc etc
HTTP/2 Push really needs to be Developer accessible. I have _NO_ idea how to make it work with nginx, or php, or rust's hyper server. There is a complete lack of documentation when it comes to the actual implementation at the developer level on how to actually implement this. I would choose it, if I knew how to use it.
I think it's dead at this stage. We didn't even enable it for HTTP/3 in Chrome, it was slowing sites down too much.
@@jakearchibald *sigh* what a waste. Thank you for that information. It’s really a shame. But I guess understandable.
8:43 There used to be a principle that a well written page would render layout first, then text, then images. *Does user experience matter no more?*
Love this! Ada and Jake are awesome!
css modules are shipping the bundle as a tag. is this means its inline and is the best for performance?
@ Jake the issue that the image stole the bandwidth from the CSS file might be due to the on-the-fly gzipping of the css file from the server(ref: 8:56)? So, serving pre gzipped css should (theoretically) fix it, right? Then again a 20kb css will still arrive later than a .5kb png that was requested few hundred ns after the css, assuming the connection is h2/h3, so does it really matter that an image was fetched before the css?
Good question! The host was Netlify and I'm pretty sure they don't do on-the-fly gzipping. In this case the image was wayyyyyy bigger than .5kb
As index.html is usually not cached maybe it is unwise to bloat it with CSS. Inlining CSS in JS for the final build is ok, but beware of doing it for some reusable components as frameworks like Next.js will have issues with SSR.
Did you watch the bit about caching? 😀
@@jakearchibald yes, and I think I understand the reasoning but maybe it's not applicable to apps where daily returned visit rate is high like news, productivity, etc. Than you'd be missing on cache hits.
@@radulaski then why is this pattern common among news sites that put a lot of effort & research into performance? (Guardian, BBC)
@@jakearchibald that's a good question, maybe the first time visit performance outweighs additional payload on repeated visits. I really liked "fastest http connection is one that isn't made at all".
@@jakearchibald considering the caching bit from the video I was wondering what is the current stance on ServiceWorkers?
you should only render css that the page needs. lots of sites are bloated with libraries. you should also talk about compiling and bundling css and what the differences are.
One thing I never notice is the load speed of like 95% of websites when browsing.
This is one of those problem developers care about but hardly anyone else.
I have been thinking about this. I’m a CSR nerd and I recently started taking advantage of suspense in React and now I split my bundle on a page by page basis. So when a user navigates to a new page the css and js necessary for that new page is downloaded while a fallback component is shown to the user and the fallback component is animated in just as if the page were already loaded. FCP and TTI saw huge improvements but I wondered if this was what SSR was trying to fix and now I can do it in CSR, does the user care?
@@nxte8506 I don't think they do, I mean the amount of time a user spends closing pop-ups for ads or cookies to get to some website content, then you're worrying about things that you need DEV tools open to measure, you're probably just making jobs for yourself for your own pleasure of shaving milliseconds off paint times.
There cannot be a way to determine what CSS is needed for a specific site, because Javascript is turing complete and solving this would probably solve the halting problem. How would you know what elements the javascript inserts into the DOM? What if it requests an XML from an external server and then inserts that into the HTML? You cannot know in advance what elements will be inserted.
I think advanced tooling needs to be made where like the suggest at the end. For any page (or maybe critical pages). This would require page virtualisation and would only really be done on like production builds.
I really enjoyed listening to this!
You didn't mention the media property, in the link tag, which helps to load only the resources needed. 😢💔😭😭
The whole thing was about first render CSS. If the media doesn't match, it isn't needed for first render.
I use Webpack to bundle everything that is repetitive (reset, global styling, components) but have individual css file per page (and JS) and I'm only loading vendor (libraries) on page that need it.
Now I have an urge to watch might max. The cartoon from the 90s
I feel like this should've been solved by the build tools we have already. But inlining vs external file is something I still can't decide on. I like how in a SPA you have the css needed for the components that are currently rendered in a bundle and the rest is loaded as the user navigates around.
What I always prefer is to have inline css on demand, like what needs to be seen on the page by the user first. Then have the general utilities in an external bundle. Depending on its size I can opt to preload or/and cache it. Caching has its problems specially on mobile since user cannot do hard reset on their browser app, and that's where the css hashing comes in.
What would the build process for inlining css like this look like?
Depends on the framework and tooling you use. In recent sites I've built, I use Preact on the server/static build. I use Rollup to catch an import to some CSS, which processes it using postcss then gives me the source as a string, which I can add to a style element.
@@jakearchibald Cheers!
Inline styling is a crime against humanity.
Except in my React components. Then it is fine for some reason.
I do both, my main bundle done via src and page specific styles are done inline
A big CSS file for me is maybe... 20 KB? That's for the entire site. With modern HTTP, the differences between inlining or not are in milliseconds. I just serve it as an external file which can then be reused from cache when the user visits other pages in the site. There are much bigger fish to fry when aiming at performance. Like they mentioned at the end, those multi-megabyte pages with bloated JS, text displayed as images, and stuff like that.
No. CSS files save a lot of space especially with browser caching
also, react sucks
DId you watch the bit in the episode about caching? 😀
A basic, nonetheless very interesting topic. Great discussion, great video!
I have to agree with Jake in regards to Web Components and H2Push.
H2Push is cursed; one of many reasons is, that web authors (and their tools) and Admins managing web server configuration are too often too far apart. With Web Components there is a JS dependency, just put the CSS in the JS, there is no usage for it without the JS anyway.
But inlining CSS only makes sense to me, if changes to CSS happen quite frequently or it is very different between the individual pages.
Otherwise, I'd argue, put all CSS in one file with a hash in the filename, then let service workers, browsers, CDNs cache it. Tradeoff: first visit takes a little bit longer, all further requested HTML is shorter without CSS in there, including revisits.
What about people who clear their cache very often? People who clear their caches don't get peak performance.
What about external CSS that is not yet cached, that can be slowed down by loading of other resources? Lazy load all JS and all images.
What about images above the fold? Lazy load ALL the images! Hot take: if quickly showing an image is essential to your above-the-fold-content, you're probably doing it wrong. ("essential" as in: not worth showing without)
Again great video. Triggering, I mean - uh - thought provoking.
Edit: Since CSS can override the display value even for (attribute) hidden elements, a defer attribute to load external stylesheets asynchronously might be an improvement in terms of not blocking content. But, afaik, for this there are only JS-dependent workarounds as of today.
What would help is having tool recommendations to make it easier. There's no reference to how you are pulling the CSS and inlining it, or how you'd load only CSS specific per-page.
I feel like the concerns about caching were too easily discarded based on only the "user comes back later, but things may have changed" scenario. Return visits aren't the only reason things are cached. Sure, if you're writing a news/article site where you know most users read one page then leave, it's fine. However not all sites are like that, other sites have users navigating between pages or opening multiple tabs. If the user ever navigating back to a page they visited in the same session, or to another page with the same layout, is expected. Then the cache isn't going to have been cleared, it's still going to be useful.
Hey, I could see a person analyze a page and inline all the css in that page only. that would be most optimal!
I'd argue that it is not optimal for repeat loads of that page or other pages using the same styled components. For general e-commerce sites a user visits 4 pages on average. This video grossly understates the benefits of caching.
Good presentation, but, I'm irked by the inaccuracy of saying this is "inline" CSS. You are talking about embedded CSS. Inline CSS would be where you add styles to the style attribute of an individual HTML element. Embedded CSS is CSS in a style block. (And external CSS is CSS linked via an external file.)
I don't think your definition of "inline" is particularly universal. For instance, the CSP spec w3c.github.io/webappsec-csp/#style-src-inline (a W3C web standard) uses 'inline' to mean roughly "not external", which is how I was using the term in the video. So, if I'm using the term in a way defined by a W3C-sanctioned standard, it seems unfair to say I'm using the term inaccurately. Maybe you know a spec that defines it differently?
Jake, I would really like you to make another good flame war about utility-first CSS (you know the one with die-hard 1D fans). It's gonna be lit. I know you're gonna wind up with some interesting arguments.
Front end is the front line. Designers need to get over their hang ups about coding and get in there to save CSS before full-stacks squash it into oblivion.
I feel like the way Jake is presenting the 'simplicity' of inlining the CSS is overlooking where the actual complexity lies. He talks about no longer having to figure out what things to put in which CSS file, but you (or a bundler) still has to figure out which CSS goes with which page. The difficult bit is figuring out what CSS is essential for a particular page. Once you've figured that out, I'm not very convinced inlining that CSS is actually that much simpler than putting it in a CSS file.
I think Ada makes a great point about having a bit of an audience mismatch here. Sure, if you have the team and time to hyper-optimize a page, inlining CSS might be worth looking into. Especially if you limit that CSS to only the first-render (or maybe even only above the fold) content. But if you're shipping multiple MBs of CSS, inlining is probably not the best place to start.
PS: I'm really enjoying the episodes with Ada so far!
I think, once you've identified exactly what CSS the page needs for a first render, dumping that out to a different file seems like an extra unnecessary step, and comes with a performance penalty.
@@jakearchibald I get where you're coming from. If think that given those 2 assumptions (you've identified the CSS and there is a performance penalty) I would probably agree with you.
I would be interested to see a more thorough review of how negligible the caching of CSS files really is. I get that you can only get into so much detail in a youtube video, but I wasn't entirely convinced that it's really a factor we should disregard. The benefit caching gives you also really depends on how well you split up the CSS files, separating the bits that change often from the more long-term styling.
I'm also wondering if the 2 examples you mentioned, the BBC and The Guardian, may be a bit of an outlier in terms of CSS because of their nature as a newsroom. They often develop interactive experiences for just a single story/page that a user is likely to only visit once. It would be interesting to hear how much that was part of why they chose this inlining pattern.
If you in-lined the styles wouldn't only those needed be loaded?
I don't understand why we're thinking in terms of "page" that's not the smallest unit of composition we work at... Is it?
@@DrewIsFail I'm not sure I 100% understand your question. I'll elaborate a bit what I mean by the difficulty in 'figuring out what CSS is essential for a page'. This is just my personal experience on the type of projects I've worked on, not necessarily saying this applies generally.
The frontend source of projects I've worked on were often split up per section or component. An example with sections: I worked for a news outlet where journalists could write stories in a CMS out of 'blocks'. Each of these blocks consisted of some HTML and CSS, and sometimes some JS. The backend would then concatenate those blocks into a story and serve that as a page. The tricky part there was that there was sometimes a lot of repetition between those blocks because of common UI elements. So you would either ship duplicate code with your page or there needed to be more complex tooling that did something more clever than simple concatenation.
The other type I've worked on a lot are JS component frameworks with server-side rendering, where the styling was either CSS-in-JS like styled-components or there was a small .css file imported by every component. In particular I did a lot of React but lately I'm very excited about what Svelte is doing with SvelteKit. For the first page load, a node.js server would either render the page on the fly or when possible there was some tooling that pre-compiled components into static HTML pages. There was a considerable amount of complexity on the server side keeping track of what components were being used while rendering, and then determining what CSS needs to go with that. A lot of the newer isomorphic JS frameworks take care of that quite well nowadays, but I feel it often still takes a lot of configuring to get everything right.
@@flutflo
My question wasn't specific enough for an answer, so I appreciate the general feedback. Let me try and elborate, i'm not directly replying to your ideas at this point, just trying to set some foundation for myself.
the fundamental smallest unit of CSS is the property key and the property value. e.g "font-size" "12px". Ideally, according to some business goal, we load those properties as needed. As we have discussed there are trade offs between package size, original load time, and successive loads. No performance plan really makes sense without context.
I think were all plans suffer though is that
1. style sheets (.css) files, operate a higher level then key and value. Then munge the key into the value. And then give us tools that aren't very explicit about changing the value. That's the cascade order and inheritance system. it's like updating a variable in your programming language by constantly re-declaring it.
2. styling an application is as dynamic, and complicated a task as other functions of an application. Yet CSS as a PL is lacking.
The reason css-in-js is attractive is because it means we can use a more expressive language (js) and less tools (.css/sass/etc...).
If there is no downside to inline styles, if in fact, on average they are faster because they lead to leaner packages sizes because they are easier to compse using JS, then i feel like this is a potential huge win for the community and something we need to embrace.
some css-in-js solutions will let you express styles in line then create a stylesheet, i'm not even sure this is a win?
I read as "Is css a bad idea to begin with ?" and said Yeah !!! 🤣
great presentation
@Jake Archibald
By inline styles, do you mean each HTML attribute gets a style attribute? Or are you just including one style tag that contains all the style properties.
I'm pretty sure he's talking about putting your css into style tag :)
@@jevvir you would have to do that for certain functionality. Keyframes and such. But then you can't keep css more local to where it's used and have to use css classes.
Also, calling that inline styles is really really confusing.
@@DrewIsFail i know right :) maybe we should call using style tag as inline css and using style attributes as inline style.
tags of course. Using the style attribute would be a gigantic waste of bandwidth.
@@hrgwea if your storing the css directly on the tags that would be true any place it repeated. Of course, i think it might not matter that much, especially for the first page load, and it would mean you didn't risk un used styles.
If your building a spa, with js, then the shared css might be stored in the js, so there wouldn't be more bloat right?
What's wrong with the sound? Hard to understand.
I usually include the “above the fold” css on-page then external link the rest
I found that too fragile due to in-page links and scroll restoration
Sometimes you inline sometimes you dont, sometimes you sheet yourself sometimes you dont
I just use Tailwind CSS at this point, because DX is great and UX feels great.
It would be nice if pages could be crawled/analysed and a subset of the css styles served per page. Server side prepares a cache of these cut down, static clones of the css, maybe the first time that page is served, and from then on sends a few k instead of several mb. Obviously dynamic content has a big impact here; I wonder if in an awful lot of the most common cases would be covered.
wouldn’t inline styles do the equivalent of this?
The thing is very simple. If a product is good the users will return and no one will recall how many seconds took the first render on the first visit. But if a product is a pure crap, no one will appreciate the short first time render time.
I don't think this is fully true. There are websites you have the option of going to and some you MUST go to. On those you really notice how good our bad they are.
Performance isn't the only element of UX, true, but you should look up some case studies on this stuff. They consistently show that faster performance leads to more engagement. Also, it's worth thinking of folks who don't have as powerful a device as you, or as fast of an internet connection as you.
just to have a comment. we can split hashed styles to chanks, so it can fix the issue of caching invalidation by a single tiny change in css file
But that messes with the compression, so I don't think it's really worth it, unless you really are updating your styles all the time.
Pity the series Best web features of 20XX is gone
Spotted: the framed portrait of Surma in the background
Svelte Kit does hit that middle ground you describe
All comes back to just inlining critical css.
CSS should be split into two different entities. One strictly for describing appearance and the other for describing positioning and spacing.
The latter should be inline to avoid first paint shifts, good idea
After this episode I feel like a noob frontend dev again. … thanks? Haha
Never be scared to be the dumbest person in the room, and you'll never stop learning.
So the key to Ferrari's great performance this season in F1 is gigantic CSS files?
if ur not designing for quirks mode, you are part of the problem.
My first office job was creating templates for an intranet. Not only did they have to work in IE6, but they also had to render nicely in Frontpage, which used a different rendering engine at the time. Frontpage didn't support 'strict' mode, so yeah, quirks mode was the best option to make IE6 and Frontpage render similar 😀
@jake I wonder what do you recommend in large websites where the page is dynamically rendered, and has a lot of is/jQuery modifying the page layout (adding CSS classes, creating menus, etc). the page would seemingly be missing a lot of CSS that could not have been discovered?
also when the HTML is gigantic (like a product listing page) and streaming chunks already exceed the maximum chunk size?
this pattern only seem feasible in small static sites?
If the styles are only used after JS modifies the page, the styles should be bundled with the JS. I think this pattern is great for big sites - that's why it's being used in the wild by sites like The Guardian and SmashingMag
Loved the discussion BUT my attention was stolen by the Joy-con doubling as a presentation remote 😂
We even did an episode about it! ua-cam.com/video/pIIHJ-NIyes/v-deo.html
@@jakearchibald Awesome!
I don't get it. Is the server supposed to serve only the css that fits that particular client? How will it do that?
I don't usually go that far, unless a particular client required a ton of CSS that most clients didn't need. The point is to avoid serving CSS for a component that doesn't exist on the page. Unfortunately the majority of the web does this.
@@jakearchibald ahhh!
But what difference does it make if it's inline css or external? Wouldn't it even be easier to have component css in separate files and then the server decides which files to link according to which components are being used?
@@AntonAdelson I think this is covered in the episode. The time it takes to request all the little CSS files can be significant.
@@jakearchibald Ahhh, I see! Thank you!
So it's a http protocol issue!
I don't think my CSS file causes problems mostly because I use CSS purge and so they are extremely small
In that case your bottleneck becomes the request and response, and as you can see from 14:37, that's significant.
@@jakearchibald haha yes I should have watched it til the end 😅
Agree that is bad idea. In 2022 mobile-first indexing gonna start new trend sim-card-mobile-first-indexing
That "server knows what the client probably has cached" sounds like a horrible tracking method but users should be able to allow this feature. (opt-in)
Pretty sure we addressed this in the episode. It wouldn't give you anything you don't get with the HTTP cache as it already exists in the browser.
@@jakearchibald yes you pointed that out. But a cache miss would be less personal than some kind of unique identifier. Yes, there could be a simple "last visited" timestamp sent by the client or at least a "first-time visit" flag, no unique identifier needed...
@@l3p3 a cached resource can contain a unique identifier. I don't see why you're wanting this to have a stricter model than the rest of the HTTP cache. All of the existing privacy mitigations would work exactly the same here.
Maybe it'd be useful if you could describe a privacy invasive vector here that offers more identification bits than the HTTP cache does today.
yes! web bundles are great! lets reduce the number of HTTP requests!
With newer HTTP versions, it gets less important, as one request can ask for several files at once and the server can send dependencies together without the client even asking for them yet!
Jake there's probably an easy way out of the big several megs CSS file: install a tool that parses and inlines the CSS per request, exactly as you said (or caches it)
It exists already, too ;)
And if memory serves, it was published by Google folks, if not the official entity
Looking at the coverage tab of this very page it's pretty much the same scenario, JS of 8MB almost all unused, CSS of 2MB almost all unused. Sure, things can be improved but if the big companies aren't optimising their own sites, is this really an issue?
Yes. If you decide that performance doesn't matter because you can point to a worse site, then it's a race to the bottom for the whole web.
WYSDNHTBWYA is a Frankensteinian acronym.
Astro splits the css files for good caching I think
how is brotli the same as gzip? the compression rates are considerably better in brotli.
By "the same" I mean 32 individually gzipped/brotli'd files will be bigger than 1 combined gzipped/brotli'd file
@@jakearchibald Not entirely sure I'd agree. But I haven't tested it fully myself. My test only went as far as to break up one large json file containing blog post data into smaller json files, then use h2, brotli, etc (all the good stuff), and size and speed were markedly improved. But I also inline my CSS as part of components, and don't load any images at all (except for the logo of course) unless the visitor clicks to see them. In one example I went from a 25.9kb file down to 418b. And that was typical across all the json files; nothing with less than a 90% reduction.
@@brymstoner one combined compressed file will always be smaller than split files individually compressed. If you're seeing something different, something is going wrong somewhere.
Your presentation background gradient feels kind of horrible.
nah, it's great
Vite is pronounced Veet - it’s French, for “quick”
Spicy.
Is he using a switch to present?
ua-cam.com/video/pIIHJ-NIyes/v-deo.html
@5:50 the problem wity css is that it is difficult to refactor design updates. Changes end up being added and old cruft left to rot. There’s too much voodoo involved.
I've never heard someone criticize vite before- 18:07