5 ms·
Great technical details in this post. When speeding up page loads, I usually struggle with: > You should have only one remote JS file and one remote CSS file.
by ohitsdom 11y ago
Great technical details in this post. When speeding up page loads, I usually struggle with:
> You should have only one remote JS file and one remote CSS file.
I get this in theory, but it's difficult in practice. For example, this post has 7 CSS files and 13 JavaScript files. Also, combining all resources includes assets that aren't needed (CSS rules used on other pages), and also reduces the utility of public CDNs and browser caching.
- nateberkopec 11y agoHa, I should totally fix that. The site uses Jekyll, not Rails, which I'm used to getting the asset pipeline for free with! Combining all the resources will include assets that aren't needed. Part of the reason I made the post about profiling with Timeline was so that you could test tradeoffs like this for yourself. I don't know what you mean by reducing the utility of CDNs and caching though - surely having only one file actually increases the use of browser caching, since the browser will only make 1 request for CSS and serve the cached copy for every other page?
- nordsieck 11y agoHe's implying that other sites may use the same popular Javascript libraries, so they may already be in the browser cache, before the first page load.
- moron4hire 11y agoI've never understood why this was a good argument, because it just ignores that there are still going to be a lot of people who hit the worst-case scenario. When optimizing page-load time, you should always optimize for the worst-case scenario, not the best-case.
- adanto6840 11y agoIt really depends on your use-case & what you're doing. In many cases you will likely want to target ~ 95th percentile or similar.
- seanwilson 11y agoAlso, how likely is it that two websites use exactly the same CDN and version of e.g. jQuery or Angular?
- moron4hire 11y agoThis is probably a major contributing factor to the issue. Personally, I've seen the greatest improvement in performance by avoiding latency more often than total download size. That's why concatenation works so well. It's just much more expensive to initiate two HTTP requests (four, if it does a HEAD first to get the Last Modified date), than one. That said, I still limit total download size. JQuery is not a big enough contribution to my productivity to warrant an extra 86KB of data. React is like 132KB. Angular is 144KB. That's a lot of KB for anyone riding on the metro.
- sp332 11y agoBut if you're pulling in shared resources from a public CDN, like jquery, the browser probably already has it cached and won't need to download it at all.
- jon-wood 11y agoI'd love to see some concrete numbers on public CDN hit rates. It feels to me like of those ideas that sounds great in theory, but in the real world doesn't really work because of the multitude of versions, libraries, and options for public CENsus.
- gsnedders 11y agoI have some memory of someone doing this and finding the hit rates were abysmal—too many libraries and too many versions. And that was five years ago, and we just have more libraries and more versions today. I'd love to dig up the numbers… I hope they aren't somewhere internal to Opera (where I used to work)!
- strommen 11y agoCombining everything into one file reduces browser caching, since a change in any of the N files invalidates the cache. As a site grows, it's usually better to have 2-3 bundles grouped by frequency of change. E.g. I rarely upgrade 3rd-party files like jQuery, etc. but often make changes to the 1st-party app logic.
- ohitsdom 11y agoExcellent point about one file update invalidating the bundle, totally missed that in my argument. And I like your approach in bundling by update frequency!
- arohner 11y agoExcept for Chrome, and firefox users who have explicitly configured their cache size, most browsers have a very limited cache, with the average sizing being ~50MB. For everything. I don't know about you, but I've loaded 50MB already today. Because of that, I don't worry about cache hits, because the median visitor will have nothing cached. Instead, worry about total page size, and total number of http requests. Minifying dramatically helps the number of http requests.
- jwoah12 11y agoI just checked my preferences on Firefox 39 on OS X, and my cache is 350mb by default (I never changed it).
- strommen 11y agoGreat point, and caches are even smaller on mobile. I think it depends on your use case. If your page views are mostly new users (e.g. you're a content publisher), then cachability doesn't matter too much. But if you're writing a web app hoping to have high engagement with users that return to the site frequently, it's likely you can be pretty effective with caching. Also - I kinda doubt that browser caches use a simple LRU replacement policy. I suspect they have some heuristics built in to guess what is most likely to be re-used. I don't know for sure though...it would be interesting to know.
- 11y ago
- ohitsdom 11y agoAgreed, it's all about tradeoffs. On public CDNs- I mean public CDNs for common libraries (jQuery, Angular, Font Awesome) can improve page load time if a user already has the file. The more sites use the same public CDN, the more users benefit. But if a user doesn't have the file already, it's a loss. So, tradeoffs. On caching- if you make one JS file and one CSS file for each page, then there is no caching between pages but only necessary info is downloaded for each page. You could make one JS/CSS file for your whole site, but then there are unused assets on each page, and it becomes more difficult to simplify CSS and could increase layout thrashing. Again, tradeoffs. Really enjoying this discussion, thanks for taking the time to write this up. I have this debate in my head constantly.
- nateberkopec 11y ago> On public CDNs- I mean public CDNs for common libraries (jQuery, Angular, Font Awesome) can improve page load time if a user already has the file. The more sites use the same public CDN, the more users benefit. But if a user doesn't have the file already, it's a loss. So, tradeoffs. Even this has a tradeoff - if, for example, the other JS on your page require JQuery, you can't make the CDN copy of JQuery use an "async" tag, because you can't be certain of the order the JS will execute. And if you're not using the async tag, the first load will suffer.
- mutagen 11y agoUnfortunately the variety of library versions and public CDNs prevents users from realizing the benefits promised by caching most of the time.
- nthj 11y agoA bit off-topic, but I recommend Middleman as a nice, well, middle-ground: Middleman builds to static files like Jekyll, but pulls in Rails' asset pipeline features for a better experience.
- SonOfLilit 11y agoWhat he probably means is "I thought I should include a public CDN version of jQuery instead of combining it with my own scripts, so that it is served once across the internet and not just once across my website"
- jamiesonbecker 11y agoThird party CDN's are a security tradeoff. For Userify (an SSH key management company), we're working on eliminating our use of all third-party domains in both our app and main website. This is a process and we're giving up a lot of stuff like Google Analytics (however, it's debatable how useful that is with our target audience anyway). As we move forward, we're also combining (compiling) our resources into a single, cacheable SPA. Any time you incorporate code from another site, you're: a) leaking information about your visitors b) increasing the probability of malicious injection c) for required assets (JS/HTML, usually not CSS), lowering your overall site availability/reliability -- even if that third party site is often more reliable than your site d) for less frequently used CDN assets or less frequently used sources, possibly also decreasing the speed of site delivery, especially if resources are requested less often than cache expiration (depending on type of edge caching) e) similarly, possibly slowing down site by increased name resolution requests (this can be mitigated somewhat with pre-fetching) f) increasing variation in load times (weakest link) g) trading off latency for bandwidth The biggest reasons for us, however, are (a) and (b). This is also why TLS should forced enabled with HSTS for many sites. Security trumps efficiency, especially when the differences are measured in milliseconds.
- manigandham 11y agoYour site right now has some JS that's in a continuous loop adding the same assets to the page. http://i.imgur.com/MoRAVAH.png http://i.imgur.com/MoRAVAH.png EDIT: looks like it's live.js used to check for changes while in dev, probably shouldnt have that on the live site.
- jamiesonbecker 11y agoGood catch! Fixed.
- garrettr_ 11y ago> b) increasing the probability of malicious injection Subresource Integrity (SRI) [0] was designed to avoid this potential vulnerability. It's a brand-new browser feature (jus t landed in Chrome stable, is riding the trains to Mozilla stable now) but it's worth taking a look at. Github is already using it [1]. [0]: http://www.w3.org/TR/SRI/ http://www.w3.org/TR/SRI/ [1]: http://githubengineering.com/subresource-integrity/ http://githubengineering.com/subresource-integrity/
- acconrad 11y agoOne strategy for having 1 CSS and 1 JS file is to have a manifest file per model. So say for example you have User and a Widget model; the user dashboard lies within the User controller, and the product page is within the Widget controller. You can collect only the styles and javascripts needed for widgets into a concatenated file, and separately do the same thing for the user dashboard. The upside is you've combined only the resources you truly need, though the downside is you bust the cache more often because you have twice as many manifests to download the separated content. Could be useful if you have a massive project and breaking it out will make for a significantly smaller download size.
- Confusion 11y agoWith HTTP 2 this is actually no longer true. See [1], slide 29. Also e.g. sharding is no longer necessary or even a good idea. [1] https://docs.google.com/presentation/d/1r7QXGYOLCh4fcUq0jDdDwKJWNqWK1o4xMtYpKZCJYjM/present#slide=id.p19 https://docs.google.com/presentation/d/1r7QXGYOLCh4fcUq0jDdD...