[HN Gopher] Show HN: Jampack - Optimizes static websites as a po...
       ___________________________________________________________________
        
       Show HN: Jampack - Optimizes static websites as a post-processing
       step
        
       Hi!  Jampack is a post-processing tool that takes the output of
       your Static Site Generator (aka SSG) and optimizes it for best user
       experience and best Core Web Vitals scores.  As of today it can:  -
       Optimize local images, CDN images or external images  - Optimize
       above-the-fold vs below-the-fold  - Limit images max width  -
       Inline critical CSS  - Prefetch links on scroll  - Improve browser
       compatibility  - Auto-fixes HTML issues  - Warn for HTML
       accessibility issues  - Compress all assets in the end  It
       processes directly the static output so it's compatible with any
       SSG or framework. We are intensively using it as a post-processing
       step to our Astro websites for example.  With Jampack, we end-up
       focusing more on how simple, readable and maintainable our code is,
       throw images of any size, and let it optimize for maximum
       performance.  We hope this can be helpful to lot of people! Cheers,
       Georges and the <div>RIOTS team!
        
       Author : georges_gomes
       Score  : 238 points
       Date   : 2024-03-25 14:32 UTC (8 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | microflash wrote:
       | Would love to see a way to subset fonts based on unicode range of
       | SSG output and freeze opentype axes based on font-feature-
       | settings defined in the CSS.
        
         | georges_gomes wrote:
         | Yes, lots of cool things to do around fonts! I have in TODO to
         | add automatic system font fallback with the right metrics in
         | order to improve CLS automatically. Is it what you call "freeze
         | opentype axes based on font-feature-settings" or is it
         | something else?
         | 
         | I would like to do the subset font optimization. I'm just not
         | sure how much of an improvement it's going to be. Have you done
         | it manually before?
        
           | microflash wrote:
           | > Is it what you call "freeze opentype axes based on font-
           | feature-settings" or is it something else?
           | 
           | I was talking in context of variable fonts which come with
           | lots of features mapped to opentype tags and axes. font-
           | feature-settings property selects (or activates) those
           | features. Usually this is done at few CSS selector levels.
           | The variable fonts can be trimmed by freezing those features.
           | I did something like this with Fira Code a few years ago. [1]
           | 
           | > I would like to do the subset font optimization. I'm just
           | not sure how much of an improvement it's going to be. Have
           | you done it manually before?
           | 
           | It can be quite an improvement for fonts like Inter which
           | ship with massive number of glyphs to support different
           | languages.[2] Doing this manually is a huge pain. Zach
           | Leatherman created a tool called Glyphhanger to automate some
           | of the usecases [3]
           | 
           | [1]: https://github.com/naiyerasif/FiraSourceMono
           | 
           | [2]: https://paulcalvano.com/2024-02-16-identifying-font-
           | subsetti...
           | 
           | [3]: https://github.com/zachleat/glyphhanger
        
             | georges_gomes wrote:
             | Thanks for all the links! It's definitely bumping my
             | excitement towards subset fonts!
        
       | Alifatisk wrote:
       | This is very cool
        
       | xnx wrote:
       | This reminds me of the PageSpeed modules for Apache and Nginx
       | https://developers.google.com/speed/pagespeed/module
        
         | me_bx wrote:
         | I believe the project is not maintained anymore.
         | 
         | Github repository is archived:
         | https://github.com/apache/incubator-pagespeed-ngx.
         | 
         | Or has it perhaps moved to some other location?
        
           | aendruk wrote:
           | I haven't seen a clear answer.
           | https://news.ycombinator.com/item?id=37578513
        
           | codetrotter wrote:
           | That repository links to a site https://www.modpagespeed.com/
           | which in turn links to a different repository
           | https://github.com/we-amp/ngx_pagespeed
           | 
           | It only has one extra commit, which deletes RETIRED.txt which
           | was added in the repo you linked.
           | 
           | So at the moment it seems someone is intending to continue
           | development. And might even be working on it, but haven't
           | pushed any work to the main branch.
        
       | dan_can_code wrote:
       | This is great! Having to handle these tasks manually can be very
       | tedious, so this tool is a breath of fresh air.
        
       | pdimitar wrote:
       | Ohhh, I like this is a lot! Will use it!
       | 
       | Any unimpressed commenters willing to point any defects? To me
       | this looks like the equivalent of compiling C to super-optimized
       | assembly and is definitely doing things that I wouldn't want to
       | do myself.
        
         | rthnbgrredf wrote:
         | I don't know if we are on the right track if we have to ship
         | "super optimized assembly" for HTML and CSS. I think we should
         | be able to write the most simple and straightforward HTML and
         | CSS and the Browser on all devices should just render it fine.
         | 
         | If we really have to ship super optimized assembly, then I
         | would completely skip HTML and CSS altogether and just ship
         | highly optimized web assembly and let developers use whatever
         | language they want.
        
       | kibwen wrote:
       | I'm interested in the notion of identifying "critical" CSS that
       | should be inlined rather than live in its own stylesheet.
       | 
       | I was hoping there was some principled way of identifying
       | critical and non-critical CSS (e.g. user interaction effects like
       | :hover would always be considered non-critical), but it looks
       | like the library it's using just tries to render your page and do
       | a best-effort detection on which rules are considered critical,
       | which IMO is a little unsatisfying:
       | https://github.com/GoogleChromeLabs/critters
        
         | chrismorgan wrote:
         | If you have less than 50KB of CSS, inline it. (And if you have
         | more than 50KB of CSS, you're probably doing it wrong. Well,
         | OK, maybe you're inlining fonts too, that's understandable. But
         | if you have more than 50KB of _other_ styles, you're probably
         | doing it wrong.)
         | 
         | Seriously, inlining is _absurdly_ good for performance, even
         | compared with a warm cache, and the threshold where external
         | stylesheets or scripts perform better is surprisingly high,
         | into the hundreds of kilobytes for some common markets.
         | 
         | The notion of critical CSS... it's a defeatist attitude, trying
         | to grasp back _some_ squandered performance, rather than fixing
         | the underlying problem.
         | 
         | I regret to say this is just based on casual experience and
         | observation, not any methodical technique. I would really like
         | someone to run with this concept and measure it more fully. I
         | just doubt it's going to be me.
        
           | georges_gomes wrote:
           | To back this up I would point to
           | https://news.ycombinator.com/item?id=32587740
        
       | KingOfCoders wrote:
       | After trying this (JS always amazing, 47 vulnerabilities (19
       | moderate, 24 high, 4 critical)), my web vitals went down from 84
       | to 77.
       | 
       | So not sure about that one.
       | 
       | Also some svg images went missing.
        
         | georges_gomes wrote:
         | Needs a little bit of updates :) will do. If you can share your
         | static website on GitHub repo or something I would love to have
         | a look. georges [at] divriots [dot] com
        
           | KingOfCoders wrote:
           | Rolled back, https://www.amazingcto.com/
           | 
           | There where many errors, I'll try again later and send you
           | the vitals + errors.
           | 
           | [Edit] Generally I would love this.
        
             | mousetree wrote:
             | Heads up, you've got an h3 tag now on your website that
             | says "Articlesnpm install -D @divriots/jampack from
             | Stephan".
        
               | KingOfCoders wrote:
               | Lol, thank you. Fixed.
        
       | sodality2 wrote:
       | Hm, this didn't change anything hugely on one of my projects -
       | for example, it reduced the total bundle size, but it increased
       | the gzip'd size, so it's actually a net negative for me. But it
       | looks like the CSS improvements actually did help.
       | 
       | It looks like a great idea and would probably help if I had any
       | images in my project.
        
         | georges_gomes wrote:
         | Hi! It's true that it you don't have images, the benefits are
         | limited. Also, your CSS may become bigger at the end because we
         | automatically improve compatibility with browser. You can
         | disable this by setting browserlist to empty string.
         | https://jampack.divriots.com/features/browser-compatibility/
        
       | celicoo wrote:
       | Thanks for the project!
       | 
       | Can I expect it to run out of the box for Next.js static-
       | generated files? If so, any recommendations on how to set it up
       | in a Next.js project?
        
         | georges_gomes wrote:
         | Hi! If the static output of your Next.js project is `./build`
         | then add `&& jampack ./build` to your build command.
         | 
         | If the site is 100% static then it should play nice. If it's
         | hydrated with JS: results may vary. Let me know!
        
       | chambored wrote:
       | This is exactly what I've been looking for. I had been using my
       | own scripts with Sharp for image optimizations like this, but
       | this eliminates the need for the that entirely and works much
       | better!
       | 
       | I ran Jampack after building my Quarto static site and got a 32%
       | smaller folder with no noticeable drawbacks yet. Here are my
       | metrics before Jampack and after using PageSpeed Insights:
       | 
       | before Jampack:
       | 
       | - mobile: - 52 Performance - 73 Accessibility - 100 Best
       | Practices - 85 SEO
       | 
       | - desktop: - 90 Performance - 75 Accessibility - 100 Best
       | Practices - 82 SEO
       | 
       | after Jampack:
       | 
       | - mobile: - 49 Performance - 80 Accessibility - 100 Best
       | Practices - 92 SEO
       | 
       | - desktop: - 85 Performance - 82 Accessibility - 100 Best
       | Practices - 91 SEO
        
         | georges_gomes wrote:
         | Hi! Happy you enjoyed it! I would have expected better results
         | for Performance metrics! If you don't mind sharing your static
         | site output pre-jampack I would enjoy checking out. georges
         | [at] divriots [dot] com
        
           | samstave wrote:
           | Just want to say this two comment interaction is a perfect
           | distilled example of value of posting to HN for such things.
        
             | nolok wrote:
             | I would say it's exactly why I miss the network of forums
             | of old internet, where this interaction was common on
             | pretty much any subject matter from video game saves to
             | tooling to whatever.
             | 
             | Facebook groups, discord rooms, reddit subs and the likes
             | just aren't the same, they all feel so impersonal and
             | detached, in some people compete for internet points, in
             | others everything is ephemeral and closed off ... Maybe
             | it's just nostalgia / me being old.
        
               | samstave wrote:
               | Sam's Law:
               | 
               |  _" As an idea or subject gains wider popularity and
               | interest, the level of passion and laser focus on the
               | _outcomes_ of the idea or subject gets diluted to the
               | average level of understanding of the interested audience
               | for the core subject"_
               | 
               | (my weak attempt at describing this issue)
        
               | rrr_oh_man wrote:
               | The Peter Principle of communities: They grow until they
               | become useless.
        
               | samstave wrote:
               | Petering out, as it were :-)
        
               | joemi wrote:
               | > Facebook groups, discord rooms, reddit subs and the
               | likes just aren't the same
               | 
               | I think it depends on which ones you're using. There are
               | some facebook groups and subreddits I use that still feel
               | very much like a small-forum, where people are generally
               | good and helpful and many of the users are regulars. I
               | haven't seen any discord rooms like that except for some
               | ones that are direct spinoffs of the facebook groups and
               | subreddits I mentioned, so that seems more like a credit
               | to the users than the medium.
               | 
               | I think they have to be pretty niche, though. But to be
               | fair, forums of the old internet also had similar issues
               | where once they reached a certain size the experience was
               | different/worse than when they were smaller.
        
           | chambored wrote:
           | I've zipped it up and sent a link.
        
         | lelandfe wrote:
         | Remember that Lighthouse (and therefore PageSpeed Insights)
         | scores fluctuate. Consider running multiple times and taking
         | median scores when doing comparisons of performance like this.
         | "The median Lighthouse score of 5 runs is twice as stable as 1
         | run"
         | https://developers.google.com/web/tools/lighthouse/variabili...
        
           | chambored wrote:
           | That's a fair point. There were certainly small discrepancies
           | when I ran it multiple times, but I'll use the median metric
           | moving forward.
        
       | notahacker wrote:
       | This looks like it covers several use cases people are picking
       | the SSG and its plugins to handle in the first place, especially
       | if they're picking Astro or Eleventy.
       | 
       | Is there a reason for preferring them as a separate post-build
       | step? I guess the tradeoff is faster rebuilds when you're
       | developing vs the possibility that you miss subtle bugs resulting
       | from introducing stuff like width declarations for images?
        
       | rkagerer wrote:
       | This looks great! Although personally I hate it when I scroll a
       | page beyond the 'fold' and have to wait for images to load. By
       | default, does this load the remaining below-the-fold content in
       | the background once the above-the-fold stuff is complete?
        
         | lelandfe wrote:
         | It does not. It leverages native lazy loading. All major
         | browsers treat a `loading="lazy"` attribute as meaning "do not
         | load this image/iframe until it is nearly in view."
         | https://developer.mozilla.org/en-US/docs/Web/HTML/Element/im...
         | 
         | However, this does inline aspect ratios, so the layout won't
         | change after they're done loading - the cardinal sin of lazy
         | loading.
        
           | rkagerer wrote:
           | Thanks.
           | 
           | 10+ years ago I wrote a GreaseMonkey userscript for a dating
           | site that collected all your results into one scrollable
           | table. It exercised very explicit control over the image
           | loading sequence. If I recall (and my memory might be
           | spotty), it grabbed 1 thumbnail image per match initially, in
           | the order they were displayed, to populate the table. Once
           | all the thumbnails were pulled (which didn't take very long),
           | it would start downloading full sized images, in the
           | background. Hovering a match to view more details would
           | immediately prioritize that matches photos, and if you
           | hovered over one of said match's photo thumbnails (as if to
           | click) that specific image would be placed at the top of the
           | queue.
           | 
           | It was all done using Javascript (no frameworks) and
           | XmlHttpRequest, and worked pretty well. This was back when
           | servers only allowed you a couple (or handful) of connections
           | at a time. I wrote a "TaskQueue" class in Javascript
           | implementing a very simple form of cooperative multitasking
           | (jobs designed to do their work in chunks). Tasks could
           | "preempt" others, and you could define simple relationships
           | so a group of tasks could block on one they were dependent
           | on.
           | 
           | Funny story, I actually sent a link to the tool to a girl on
           | the site who I eventually wound up in a long-term
           | relationship with ("here, let me help you make it more
           | efficient to browse for other guys...").
           | 
           | Anyway, at the time I felt like it was table stakes that a
           | page like this should be able to exert some sensible control
           | over the sequencing and prioritization of its image assets,
           | in a fashion that has the user's best interests at heart. I'm
           | glad browsers have finally evolved out-of-the-box attributes
           | like "loading=lazy", but I kind of wish there were an option
           | between "eager" and "lazy" that simply deferred the lazy
           | content until all the other content is done. So I can still
           | walk away to get a coffee (or switch to another tab) and come
           | back to a fully, instantly-responsive page.
        
             | lelandfe wrote:
             | Great story.
             | 
             | > Once all the thumbnails were pulled... it would start
             | downloading full sized images
             | 
             | LQIP, Low-Quality Image Placeholder - that was pretty new
             | stuff circa 2014. Facebook also popularized fetching a tiny
             | version, and blurring it:
             | https://engineering.fb.com/2015/08/06/android/the-
             | technology...
        
         | georges_gomes wrote:
         | As user @lelandfe pointed out here, Jampack is using browser
         | native loading="lazy".
         | 
         | There is currently no way to change this behavior but I could
         | add an option that would preload the below-the-fold images in
         | the background when all the page is loaded. It's actually a
         | pretty nice idea.
         | 
         | I'm just afraid it will load unnecessary images at the bottom
         | of the page but if it's an option, anybody can choose to have
         | it or not!
        
       | lispisok wrote:
       | As somebody who loathes doing webpage layout, refuses to learn
       | it, but has to still do it sometimes this looks great
        
       | spxneo wrote:
       | what are some static site generators people are using in
       | production? I think this could be used to further optimize the
       | output.
       | 
       | ( Case in point, yesterday I spent all day trying to follow
       | examples to turn Divjoy react website into a simple html to serve
       | from S3 bucket. I can't believe how hard that was and I am still
       | struggling. Ideally something that can just auto-deploy to S3
       | bucket and point domains to it. It hurts that I paid money for it
       | and the developer is gone, discord is abandoned. This is why I
       | always prefer FOSS )
        
         | nine_k wrote:
         | Well, Hugo, Zola, Jekyll. They sort if have parts of this.
        
       | Solvency wrote:
       | If my website is an image-heavy portfolio that I wrote myself in
       | pure HTML/CSS/JS with zero dependencies whatsoever... does a tool
       | like this offer me any value? What could it do here?
       | 
       | My site consists of a project grid (large thumbnails) and project
       | page with hi-rez (3200x2000) images in a JS slideshow I wrote.
        
         | georges_gomes wrote:
         | Do you have a link you can share? I think the project grid with
         | thumbnails could benefit greatly from Jampack but I would need
         | to see the page to confirm.
        
           | Solvency wrote:
           | https://tinonyman.com/archive
           | 
           | Not my site, but mine (in progress) is almost exactly the
           | same UX/UI but with zero dependencies or
           | libraries/frameworks.
        
       | georges_gomes wrote:
       | I'm receiving lots of static websites by email from people who
       | want to help me with real world examples :heart: you guys are
       | awesome! Thank you so much!
        
       | jdthedisciple wrote:
       | Highly needed - thanks!
        
       ___________________________________________________________________
       (page generated 2024-03-25 23:00 UTC)