Performance Calendar

calendar.perfplanet.com · Group blog · on HN since 2010

An annual advent-style series of articles by various authors on web performance, covering images, rendering, and JavaScript.

What HN saysHN commenters cite it in debates about progressive JPEGs and critical rendering path, while disagreeing on how well browsers handle progressive loading.
123HN people shared it
41linked it in comments
166stories submitted
3.1Kstory points
4 months agolast shared
2010people per year2026

Most-shared posts

  1. 1
    MozJPEG 3.0
    5 people · 290 points · first shared 2014 · 64 comments on HN
  2. 2
    React's Diff Algorithm
    5 people · 212 points · first shared 2013 · 33 comments on HN
  3. 3
    Progressive JPEGs: a new best practice
    4 people · 133 points · first shared 2012 · 63 comments on HN
  4. 4
    Mobile Performance of Next.js Sites
    4 people · 5 points · first shared 2022 · 1 comments on HN
  5. 5
    HTTP/3 Prioritization Demystified
    4 people · 2 points · first shared 2023 · discussion on HN
  6. 6
    HTML and CSS techniques to reduce your JavaScript
    3 people · 592 points · first shared 2020 · 133 comments on HN
  7. 7
    Evolution of <img>: Gif without the GIF
    3 people · 259 points · first shared 2017 · 138 comments on HN
  8. 8
    PNG that works
    3 people · 135 points · first shared 2011 · 39 comments on HN
  9. 9
    QUIC and HTTP/3: Too big to fail?
    3 people · 68 points · first shared 2018 · 5 comments on HN
  10. 10
    Mobile ISP image recompression
    3 people · 21 points · first shared 2013 · 1 comments on HN
  11. 11
    The unseen performance costs of CSS-in-JS in React apps
    3 people · 7 points · first shared 2019 · discussion on HN
  12. 12
    Non Blocking JS Loader Pattern
    3 people · 6 points · first shared 2012 · discussion on HN
  13. 13
    Cache digests http2 server push
    3 people · first shared 2017
  14. 14
    The mythical “fast” web page
    2 people · 114 points · first shared 2020 · 162 comments on HN
  15. 15
    Testing with realistic network conditions
    2 people · 95 points · first shared 2016 · 7 comments on HN

What HN people wrote when they linked it

acdha · 2023-12-15
Criticism of cherry-picking cuts against WebP because the marketing campaign for that codec relied on cherry-picking both the least optimized JPEG codec and the most favorable metrics for comparison. If you had humans comparing images or enabled JPEG optimization you saw far less exciting numbers for WebP - usually under 10% savings, not uncommonly negative – and there were other formats which consistently outperformed it. You can see the mood around that time here: https://calendar.perfplanet.com/2014/mozjpeg-3-0/ Even a decade later, however, Google repeats the 25-34% claim and their performance tools tell developers they should use a modern format, which by sheer coincidence means the one they invented rather than the best ones on the market.
memco · 2021-03-14
Yes, it is a thing: https://calendar.perfplanet.com/2012/progressive-jpegs-a-new-best-prac… Some people do use it intentionally.
sp332 · 2017-06-05
I don't think this is right. IE9 renders progressive JPEGs progressively. https://calendar.perfplanet.com/2012/progressive-jpegs-a-new-best-prac…
dgreensp · 2016-12-28
Progressive JPEGs are actually a worse experience on browsers that don't render them progressively, like Safari (including iOS). This is why many major sites, such as Flickr, don't use progressive JPEGs (last time I checked, which was a few years ago). See: http://calendar.perfplanet.com/2012/progressive-jpegs-a-new-best-pract…
FigmentEngine · 2013-01-10
worth reading in relation to this, including the impact of the CSSOM http://calendar.perfplanet.com/2012/deciphering-the-critical-rendering… and using the DOMContentLoaded event
ksec · 2019-01-01
> For instance, one I read a comment on the article here https://calendar.perfplanet.com/2018/is-avif-the-future-of-i... Jpeg was released the MPEG-1 ( H.261 ) era. Since then we have had H.262 / MPEG2, H.263 / Divx, H.264 /AVC, H.265 / HEVC, and the coming H.266 / VVC. If we consider the amount of improvement we got from Video Encoding, images hasn't changed much at all, we happen to fine tune the heck out of Jpeg. And I hardly call a new image format with 50% reduction bitrate compared to a nearly 30 years old tech a major breakthrough, and that is without mentioning the huge decoding resources requirement. There are many project that just improves on JPEG, Dropbox had a lossless compressor for JPEG, and Cant remember if Pik was originally based on jpeg as well. Unless there is a real major breakthrough that gives the current best JPG encoder quality at 25% or less its size, focusing on 200KB, 100KB, 50KB images size, ( i.e the new image will have to be 50KB, 25KB, 12.5KB ) while using within 2x decoding power. I am convinced our roadmap for Network bandwidth improvement in the next 3 - 5 years are going to make JPEG to last forever.
PaulHoule · 2018-12-31
From time to time I've run an analysis on the use of alternative image formats on the web and it never comes out to be worth it. New formats are not supported on all browsers so you wind up having to support the mainstream formats as well as one or more new formats. Rather than benefiting from reduced storage costs, your storage costs get multiplied. Performance is also a problem, particularly when people add "yet another polyfill" to get an image to work without native support. Once I get into eyeballing images closely I also end up questioning if the compression gains are real. For instance, one I read a comment on the article here https://calendar.perfplanet.com/2018/is-avif-the-future-of-images-on-t… and looked closely I couldn't unsee that the AV1 had very different artifacts than the other compressed images. Not necessarily worse, but definitely different. Unlike the poster I liked the way the suit rendered but definitely there was a lot of blocking around edges that the poster interprets as "pixelation on the flag". Like many things, the costs of switching image formats are definite, but the benefits are questionable.
brycewray · 2026-07-12
> Is it really better than just having a placeholder square with maybe the most prominent color? Or just a good old progressive image? The Hugo static site generator provides a `.Colors` method[0] for doing this. It produces what one 2018 article[1] referred to as a GIP (Gradient Image Placeholder). [0]: https://gohugo.io/methods/resource/colors/#article [1]: https://calendar.perfplanet.com/2018/gradient-image-placeholders/
dieulot · 2026-04-10
That’s an unreliable way of simulating an unreliable network, as overviewed in https://calendar.perfplanet.com/2016/testing-with-realistic-networking…
alwillis · 2026-01-11
Attempting to lazy load an LCP could delay the loading the image as much as 15% [1]. Lazy-loading is an effective technique we can use to delay non-critical resources at the beginning of the page load. However, a considerable problem occurs when we apply this technique to an LCP image. Lazy-loading prevents the browser from loading the image immediately because it takes time for it to realize that the image is in the viewport and needs to be loaded. According to some lab tests, this could cause a 15% regression in LCP performance. This might sound obvious for someone working on web performance, but the fact that nearly one in five web pages are doing it is a sign that it’s not very well understood by most other web developers. [1]: https://calendar.perfplanet.com/2022/lazy-loading-lcp-images-why-does-…
crowcroft · 2025-01-09
Yea, iPhones are FAST. My point is that in the graph showing Geekbench score and INP [1] you can draw a straight line, but what I see in the graph are three clusters – phones with a Geekbench score: - above 1,500 (look very good) - between 500 and 1,500 (look decent still) - below 500 (really terrible) Both an iPhone and a flagship Android will have a much better INP than a phone with a Geekbench score of 500. I'm not so sure if an iPhone has a much better INP score than a flagship Android though (maybe it does, I'm not seeing that in the data though). [1] https://calendar.perfplanet.com/images/2024/alex/1_9TNKz0qd5pdSMXNc6Qt…
andrewf · 2024-09-17
Adding to this: I like looking at graphs like https://calendar.perfplanet.com/images/2021/leon/image1.png . In this particular example, the "lzma" (ie xz) line crosses the zstd line, meaning that xz will be compress faster for some target ratios, zstd for others. Meanwhile zlib is completely dominated by zstd. Different machines and different content will change the results, as will the optimization work that's gone into these libraries since someone made that chart in 2021.
mhoad · 2023-08-13
For all of its marketing hype, Next is actually kind of dogshit when it comes to performance especially compared to something like Astro https://calendar.perfplanet.com/2022/mobile-performance-of-next-js-sit…
crubier · 2020-12-03
Slow at bundle time like tailwind, AND slow at runtime like css in js. I don’t get these tools, the whole point of tailwind for me is the runtime performance combined with high flexibility! Twin is the worst of both worlds. The runtime cost of css in js is real, and becoming a real problem for my app. Seeing like 2x slowdown as compared to classnames like in https://calendar.perfplanet.com/2019/the-unseen-performance-costs-of-c…
depressedpanda · 2020-01-16
Why force all your users to download transpiled ES5, just to accommodate IE11 dinosaurs? Not to mention all the issues you'll have if you try to use CSS Flex or Grid. Support IE11 only if you absolutely must, is my advice, and do that with differential serving: https://philipwalton.com/articles/deploying-es2015-code-in-production-… https://calendar.perfplanet.com/2018/doing-differential-serving-in-201…
tedmiston · 2019-05-12
It's not quite what you described but static asset fingerprinting or asset digest fingerprinting is a good place to start. In theory, if you're using this behind a cache or CDN, then you've already heavily optimized your server load for serving static assets. I haven't seen any sort of a diff-based approach to caching in the browser. I don't think there is a notion of cache "layers" for an arbitrary binary file in a browser to easily support this, but that doesn't mean you couldn't build it. Maybe you could use localStorage / sessionStorage here? Another research term that might be useful is incremental caching. This seems relatively new but cache digests could also be useful here. https://calendar.perfplanet.com/2016/cache-digests-http2-server-push/
gardaani · 2019-05-10
Safari 11.1 supports any video in <img> tag and it does all the things you want: https://calendar.perfplanet.com/2017/animated-gif-without-the-gif/ There is a feature request for Chrome: https://bugs.chromium.org/p/chromium/issues/detail?id=791658
cflat · 2019-05-09
Agree. Safari has already made moves for this[1], but Chrome seems to be resistant[2]. [1] https://calendar.perfplanet.com/2017/animated-gif-without-the-gif/ [2] https://bugs.chromium.org/p/chromium/issues/detail?id=791658
SippinLean · 2018-04-13
>WebKit in Safari now supports loading H.264 encoded MP4 video with an HTML tag. I was confused by this sentence, but it actually says "HTML <IMG> tag" (the "<IMG>" part of the text is unescaped, and does not render). Meaning you can use <img src="video.mp4"> "But we already have <video> and animated webP and..." is addresed in depth in the linked article: https://calendar.perfplanet.com/2017/animated-gif-without-the-gif/
floatboth · 2017-06-06
They should try just compressing them with mozjpeg anyway, since mozjpeg has deringing https://calendar.perfplanet.com/2014/mozjpeg-3-0/ it's actually not bad for text/cartoons/other things with high-contrast edges
bfred_it · 2017-05-20
If your intent is to load scripts asynchronously and keep their order, just use `<script defer>`. From what I see, you only ever need something like `fetch-inject` if you also want to load stylesheets OR if you want a load callback. I've been using `defer` exclusively ever since I read this: https://calendar.perfplanet.com/2016/prefer-defer-over-async/
bluthru · 2016-09-28
MozJPEG is especially impressive at reducing artifacts around text: http://calendar.perfplanet.com/2014/mozjpeg-3-0/
jakub_g · 2016-05-12
It's far from being immediately actionable and focused on JS libs, but this book [1] from Ilya Grigorik, who is a perf engineer at Google, is a good start. It's not about JS, but a wide view, starting from TCP / HTTP(S) level, through how mobile devices work, to JavaScript. You may want to read also some articles on perfplanet [2] Blog of Grigorik is also intersting [3] But as I said all those resources are about "web performance" rather than "JS performance" and are more high level overview about latencies, UX and not exactly on minimizing CPU cycles. [1] http://chimera.labs.oreilly.com/books/1230000000545 [2] http://calendar.perfplanet.com/2015/ [3] https://www.igvita.com/
fsiefken · 2015-09-29
Yes, this was wishful thinking on my part. sp332 is right, there was no decision to implement this. They choose to put their efforts towards mozjpeg instead: http://calendar.perfplanet.com/2014/mozjpeg-3-0/
kluck · 2015-06-28
That guy [1] used search engine autocomplete to find out that many people search for phrases like "why is facebook so slow". This is really just another indication of something beeing terribly wrong here... [1] http://calendar.perfplanet.com/2013/why-is-the-web-so-slow/
DougBTX · 2015-03-21
Hi! That might be my comment down below. There's a nice article about how the diffing works here: http://calendar.perfplanet.com/2013/diff/ The important bit is that the diff is applied to the old and new virtual doms, and it is the render method that gets called to compute the new virtual dom. Only after the diff does the real dom get updated.
vjeux · 2014-07-21
1. The boundaries are currently at event loop. Whenever an event comes in, we dispatch it to React and every time the user calls setState on the component, we mark it as dirty. At the end of that dispatch, we go from top to bottom and re-render elements. It's possible to change the batching boundaries via "Batching Strategies" but we haven't exposed/documented it properly yet. If you are interested, you can look at requestAnimationFrame batching strategy. https://github.com/petehunt/react-raf-batching 2. We cannot really use normal diff algorithms for list because elements are stateful and there is no good way for React to properly guess identity between old and new. We're pushing this to the developer via the `key` attribute. See this article I wrote for a high level overview of how the diff algorithm is working: http://calendar.perfplanet.com/2013/diff/

Keyboard shortcuts

/Search
j kNext / previous blog
EnterOpen selected blog
vVisit the blog site
fFollow / unfollow
lSwitch grid / list view
dSwitch dark mode
g hHome
g pTop posts
g tTopics
g fFollowing
g lLiked
g yHistory
g qFAQ
EscBack / close