avatarJason Knight

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

4709

Abstract

de> command with parallelism.</p><h2 id="9570">Benchmarks</h2><p id="dc98">Benchmarks conducted on four different repositories revealed that a hot mvnd execution, where the daemon is already running, can accelerate builds by up to 50% of builds that do not run tests or static analysis as this is the most common use-case among developers in our organization.</p><figure id="442c"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/0*xot8KoV94usih-4e"><figcaption></figcaption></figure><h2 id="77be">Local vs CI server</h2><p id="ac6e">Using Maven Daemon significantly sped up our local builds, making our engineers’ daily iterations faster and more efficient. However, this solution wasn’t suitable for our CI environment with TeamCity. Since we don’t reuse TeamCity, there was no benefit to starting a daemon process in this context.</p><p id="3916">In response to this limitation, we will be exploring the possibility of reusing agents and investigating potential improvements in a different initiative to better optimize our CI environment.</p><h2 id="c57d">Adoption</h2><p id="8fb7">To ensure every Java team at Picnic could benefit from the increased speed of local builds using Maven Daemon, we created a comprehensive knowledge article outlining the steps and best practices. By sharing this detailed knowledge article, we ensured that all developers in our organization could easily adopt and benefit from using Maven Daemon, leading to faster build times and improved productivity.</p><p id="436d">Currently, we don’t have visibility in the adoption rate here, but we are looking into using OpenTelemetry Maven extensions to get more insights into this to better track and advocate</p><h1 id="aceb">Maven Build Cache</h1><p id="6a2a">One of the best ways to speed up builds is to do less. And the best way to do less is to eliminate duplicate or unnecessary work. Why should we want to rebuild and retest all modules in our project if I change a single test, or a small if-statement in a module no other module depends on? We can use a build cache to only execute Maven goals for modules that changed and modules that depend on these changes.</p><h2 id="f90a">How does it work</h2><p id="5cdc">The Maven Build Cache extension enhances the efficiency of large Maven projects by implementing the following set of features:</p><ol><li><b>Incremental Builds</b>: Only the modified parts of the project graph are rebuilt.</li><li><b>Subtree Support</b>: Allows isolated builds of specific parts in multi-module projects.</li><li><b>Version Normalization</b>: Facilitates version-agnostic caching.</li><li><b>Project State Restoration</b>: Avoids repeating expensive tasks like code generation by restoring previous states from the cache.</li></ol><figure id="5b07"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/0*ehx_WSQV_zw9e68p"><figcaption>The diagram shows that changes in a module (Module 2) lead to it and its dependents (Module 3) being rebuilt, while unchanged modules (Module 1 and Module 4) are retrieved from the cache.</figcaption></figure><h2 id="28f6">Local Build Cache</h2><p id="2678">When working locally, the Maven Build Cache stores the build output artifacts in a designated local cache directory. Here’s a step-by-step breakdown of how it operates:</p><ol><li><b>Initial Build:

  • </b>During the first build, Maven compiles the entire project as usual.
  • For each module, the build cache extension computes a unique hash based on the module’s inputs (source files, Maven configuration, dependencies, etc.).
  • The build outputs (e.g., compiled classes, packaged artifacts) are stored in the local cache directory with the computed key.</li><li><b>Subsequent Builds:
  • </b>Before building a module, Maven checks the local cache directory to see if there is a cached result for the module’s hash.
  • If a match is found, the cached outputs are restored, and Maven goals executed when the cache was constructed are now skipped.
  • If no match is found, Maven rebuilds the module, and the new outputs are cached for future use.</li><li><b>Cache Management:
  • </b>The local cache can be configured to limit its size and manage the retention of cached artifacts.
  • Policies can be defined to periodically clean up old or infrequently used cache entries, ensuring the cache directory remains manageable.</li><li><b>Key Generation:
  • </b>The unique key for each module is generated by hashing the module’s inputs. This includes source code files, project model (POM file), plugin configurations and parameters, and dependency versions and configurations.
  • By including all relevant inputs in the key, the build cache ensures that any change in the inputs results i

Options

n a new key, prompting a rebuild.</li></ol><p id="4903">The build cache uses hashing to generate unique keys for storing and restoring build results. Correctness is maximized by including all relevant files and functional plugin parameters, while reuse is enhanced by filtering non-essential files and minimizing controlled plugin parameters. Configuration involves balancing correctness and performance through an XML file, <code>buildinfo.xml</code>.</p><h2 id="88d2">Usage in CI</h2><p id="6966">In our CI process, we also leverage the Maven Build Cache solution to accelerate our CI builds. However, for CI, we employ <a href="https://maven.apache.org/extensions/maven-build-cache-extension/remote-cache.html">a remote cache</a> stored in an artifactory instead of using a local directory. In our case, cached artifacts are stored in Nexus. This approach has markedly increased the speed of our Java builds. Consequently, our builds finish sooner and build queues are shorter.</p><p id="d0a3">However, in certain situations, users need to perform a full build of their changes. To accommodate this, we introduced a TeamCity parameter called “Use Maven build cache” with the following options:</p><ul><li><code>true</code>: the cache is used</li><li><code>false</code>: the cache is not used</li><li><code>default</code>: the repository-level setting is applied</li></ul><figure id="51f5"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*cjBQGpXtPyo_8MeafHw1TA.png"><figcaption></figcaption></figure><p id="76d0">It is good to note that we currently employ the cache only for builds that do not create production artifacts, as we wish to have these as ‘pure’ as possible. As such, we disable the cache for builds on default branches supporting continuous deployments, and in release builds.</p><h2 id="1253">Benchmarks</h2><p id="12d5">In the best-case scenario, the execution time of CI builds dropped by ~ 90% when execution of every module was skipped, this is how it was shown in the build logs:</p><div id="bdae"><pre>[INFO] Skipping plugin execution (cached): <span class="hljs-keyword">install</span>:<span class="hljs-keyword">install</span></pre></div><p id="72cd">Instead of 10 minutes 4 seconds, the build that was fully cached took only 1 minute 22 seconds. 😲</p><p id="fb1e">Of course, this is quite a rare case to run a build that has every module skipped. The average build time improvement across all Java repositories in Picnic is shown in the picture below. It is noticeable that build time dropped by 62% in general.</p><figure id="3fd7"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*m9KcQpIhbc66wTHDIvttPQ.jpeg"><figcaption></figcaption></figure><p id="97f1">For some repositories, the build time improvement was more noticeable than for others. Projects with many modules benefit more than projects with only a few modules. This can be seen in the chart below showing P75 build times. Highly modular projects see their build times drop from 10 to 5 minutes. Projects with a few modules only benefit little from this improvement.</p><figure id="8e53"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/0*Qp8AmIXK7M0xzbuc"><figcaption></figcaption></figure><h1 id="d1eb">Conclusion</h1><ol><li><b>Dramatic Build Time Reduction:

  • </b>Build times dropped from 12 minutes to 8 minutes in general. This significant improvement eliminates long waits, allowing developers to maintain focus and productivity.</li><li><b>Enhanced Developer Experience:
  • </b>Faster build times, especially for local builds, lead to fewer interruptions, enabling developers to stay in the zone and work more efficiently. This improvement has contributed to higher job satisfaction and overall happiness among our teams.</li><li><b>Increased Efficiency in CI Pipelines:
  • </b>Using the Maven Build Cache in our CI environment has sped up CI builds, reduced queue times, and made TeamCity agents available more quickly.</li></ol><p id="46a2">These improvements have significantly boosted developer morale and productivity. Reduced build times mean less context switching, quicker feedback, and a more enjoyable workflow.</p><p id="316d">Developers feel more empowered and efficient, resulting in higher-quality code and faster feature implementation.</p><p id="90d2">In summary, the integration of the Maven Build Cache extension and Maven Daemon has transformed our build process, making it faster and more efficient. We are excited to continue leveraging these tools to maintain and further improve our build processes, ensuring our developers have the best possible experience.</p><p id="0bd6">In collaboration with <b>Pieter Dirk Soels</b></p></article></body>

Utility Classes And Atomic CSS. Predatory Propaganda Deflection!

As sometimes happens this started life as a response to someone else’s post. It grew in size, scope, and took enough of a different tack on the topic to warrant its own article.

In his article here:

Hajime Yamasaki Vukelic brushes aside the leaves used to camouflage what these two terms are basically used to hide. The construction of monuments to the worst of mid ‘90’s web development practices. Dialing the clock back 25 years with code bloat, hard to maintain complex convoluted WET code, and reeking of a general ignorance of the most basic of HTML and CSS concepts. All concepts I am more than familiar with, and any of you who read my articles will recognize is the exact same thing I’ve been saying for decades.

But there is something more insidious to it. I’ve said it, but never really gone into depth about it. And that’s how these hoi-polloi terms exist not because they are something new, or worthy of their own name… no, they were created as a deflection, a way to avoid saying what is really being done.

They are NOT “atomic CSS” since they have jack freaking shit to do with CSS since you’re talking about shitting classes into the markup to avoid using CSS. They are NOT “utility classes” since the only utility they provide is … well… shitting classes into the markup to avoid using CSS.

THEY ARE PRESENTATIONAL MARKUP, THE BLEEDING EDGE OF 1997 WEB DEVELOPMENT!!!

And why don’t they call it “presentational markup / classes” and created these deflections? SIMPLE! To avoid reality so they can continue to peddle their broken, bass-wackard approach to coding the front end.

As I keep saying, if you don’t understand that:

<div class="text-center font-bold font-lg color-400-red">

Is the exact same broken bloated outmoded mentally enfeebled brain damage as:

<center><b><font color="#EF5350" size="+1">

Please, just admit defeat and go back to writing that HTML 3.2 with all the deprecated presentational tags and attributes, abusing table elements for layout, and all the other hacky nonsense y’all so clearly and dearly miss!

Seriously I know I keep saying it, but that’s ALL this idiocy is. It is literally mollycoddling the people who can’t extract their cranium from the browser wars’ rectum, allowing people to make their HTML “do too much”

And that’s another place where it’s comic tragedy.

If A Function Can “Do Too Much” Why Can’t You Admit That About Your Markup?

Seriously, the sheer hypocrisy of this. So many people working in JavaScript, TypeScript, React, and so forth will parrot the gibberish “that function does too much” claim, break things up into dozens of separate functions and even separate files / modules… But at the same time have no problem telling the separation of concerns in HTML/CSS to sod off? Which is it?!?That so many flat out are blind to the fact that they are the same failing? Classic.

You can see it in React, where instead of keeping things separate so they’re efficient, speedy, easy to maintain, etc, etm? They slop together client-side scripting only markup in the server-side code; “onevent” attributes in that markup; Presentational classes and CSS in JavaScript. Until you end up with these massive complex hard to understand functions being written by the very same people who lose their freaking minds over a switch/case or excessive if/else! Or even sillier balk at do/while.

But this is to be expected in a way, whilst opposing sides of the same argument they are both cases of trying to justify bad practices. Writing more code than needed, in as painfully complex a manner as possible, all because of a refusal to learn enough of the vanilla / underlying languages to even know what “easy” is.

Why The Deceptive Misleading Names?

And that’s easy. It’s plain as day and something I’ve written about before: Propaganda. Specifically “glittering generalities”, “card stacking”, and “transfer.” The overlap of these techniques is a bit fascinating here.

Words like “utility” or “atomic” really don’t have much to do with what these actually do. They sound good so they’re the glittering generality. People understand and like concepts where those words actually mean something, so that’s transfer. They are an evasion oft tied to bad examples of what these clowns THINK vanilla code is / should look like, so there’s your card stacking.

And evasion is indeed the correct word, because even when they write diatribes dissecting the separation of concerns, they are trying to avoid admitting that ALL this amounts to is presentational classes. Using classes to say what things look like.

But What’s So Wrong With That?

Presentation has no business in the markup for a number of really good reasons. I’ve said it before and I’ll keep on saying it.

  1. HTML is for more than what things look like on screen devices. The ability to have different media targets for your CSS — print, speech, aural — means you don’t have to waste time sending style to users where it doesn’t matter and/or is irrelevant. Your HTML should be written for everyone, not just the perfectly sighted on screens. That’s why semantic markup exists. Why would you send screen appearance to search or braille?
  2. The more you can move out of the markup, the sooner parallel page-loads can kick in. Large markup delays the loading of external files.
  3. The more you can move into external files, the more that can be cached for revisits of the current page, and pre-cache for sub-pages.
  4. Using selectors you can say style once in the stylesheet, instead of the WET (we enjoy typing) of crapping the same classes over and over again on sibling level elements. One of the most basic rules of HTML and CSS, if every sibling-level element is getting the exact same class, none of them should have that class!

Take agonizingly cryptic dumbassery like “Atomic

        <nav class="home_D(n)--xs">
            <ul class="M(0) Mt(3px) P(0)">
                <li class=" D(ib) Va(m) Pos(r)">
                    <a href="/quick-start.html" class="D(b) C(#fff) Td(n):h">Docs</a>
                </li>
                <li class=" D(ib) Va(m) Pos(r) Mstart(15px)">
                    <a href="/repl.html" class="D(b) C(#fff) Td(n):h">REPL</a>
                </li>
                <li class=" D(ib) Va(m) Pos(r) Mstart(15px)">
                    <a href="/reference.html" class="D(b) C(#fff) Td(n):h">Reference</a>
                </li>
                <li class=" D(ib) Va(m) Pos(r) Mstart(15px)">
                    <a href="/support.html" class="D(b) C(#fff) Td(n):h">Support</a>
                </li>
                <li class="D(n)--xs D(ib) Mstart(15px) Pos(r)">
                    <a class="D(b) C(#fff) Td(n):h" href="https://github.com/acss-io/atomizer">
                        <svg class="nav-on_D(n)--xs Va(m) Pos(r)" fill="#fff" height="24" aria-hidden="true" viewBox="0 0 16 16" version="1.1" width="24">
                            <path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path>
                        </svg>
                        <span class="D(n) nav-on_D(b)">GitHub</span>
                    </a>
                </li>
            </ul>
        </nav>

Switching everything to single letters to make it an even bigger mess of gibberish doesn’t help for what any competent developer would write as:

<nav id="mainMenu">
  <ul>
    <li><a href="/quick-start.html">Docs</a></li>
    <li><a href="/repl.html">REPL</a></li>
    <li><a href="/reference.html">Reference</a></li>
    <li><a href="/support.html">Support</a></li>
    <li>
      <a href="https://github.com/acss-io/atomizer" class="icon_github">
        <span>GitHub</span>
      </a>
    </li>
  </ul>
</nav>

With CSS something like this:

 #mainMenu li {
   list-style:none;
   display:inline;
 }

 #mainMenu li a {
   display:inline-block;
   position:relative;
   margin-right:1rem;
   text-decoration:none;
   color:#FFF;
 }

 #mainMenu li a:after {
   content:"";
   position:absolute;
   top:50%;
   left:50%;
   width:0;
   height:0;
   padding:0;
   border-radius:100%;
   translate:-50% -50%;
   background:#FFF3;
   transition:padding 0.3s;
 }

 #mainMenu li a:focus:after,
 #mainMenu li a:hover:after {
   padding:calc(50% + 1rem);
 }

Which good for a laugh combined is as much code (if we skip the SVG) that idiocy like atomizer wastes on markup ALONE. And then they need their bloated pre-built stylesheet nonsense on top? Hurr-durrz. It’s as much if not more work, in as cryptic a manner as possible, to piss away caching, parallelism, and quite possibly accessibility given they don’t even use media targets.

That anyone would claim crapping on the markup with classes that way is “Easier” or “better” is outright delusional.

Maybe We Need A Catchy Name To Fight It?

I mean if they’re going to start making up terms to justify their ignorant, broken practices in an attempt to steer the narrative, why not play their game? Or better still, meet their deceptive lies with a little bit of truth.

I mean they ARE presentational classes no matter how much they try to use other terms to describe it. Their willful “Wah wah is not” doesn’t change that fact, though it does seem to sway the foolish, gullible, and ill informed masses.

Thus we need something else. How about:

“Wanking Classes”

Since sitting there spanking oneself onto the HTML does seem to be their intent, much less sitting around circle-jerking each-other in their echo-chambers of like minded head-bobbers and blow-jobbers. Seems to fit what’s really going on quite well.

In many ways no different from the halfwitted mental masturbation that are “thoughts and prayers” and other such religious indoctrinational affirmation rituals.

All of this is done because they “can’t get any” when it comes to what HTML is, what CSS is for, how to use either properly. It’s as I wrote in my little hit piece, where the people who create idiocy like Bootstrap, Tailwind, W3.css, and nearly every other HTML/CSS front-end system flat out do not care about speed or ease of development, server load, server-side complexity, sustainability, maintainability, page load times, caching, pre-caching, parallelism, accessibility, search, or any other meaningful metric of the quality of a website.

Which is why the claims that all those systems and broken approaches provide those very things makes them fraudulent.

Atomic Css
CSS
Framework
HTML
Propaganda
Recommended from ReadMedium