- React: Hello Web Programmer
- What is Magento PWA Studio
- Magento PWA Studio: Looking at the Tools
- A note on the PHP UPWARD Server
- Hyvä Admin: UI Components you can use
- Magento Front End 2020: A Preview and Review of Hyvä
Is our previous two articles we took a look at Magento’s PWA Studio.
This Magento PWA solution has been a long time coming. Immediately after Magento 2’s release the limitations and — “not fully baked-ness?” — of Magento’s UI Components system were very apparent, but Magento spokespeople immediately started talking up Progressive Web Applications as the future. I had more than one person tell me (both publicly and privately) that the UI Components system wasn’t going to get any more real attention and that Magento Inc. was all-in on PWA.
Five years of Magento developers struggling with UI Components suggest that a more subtle form of product management was necessary. Magento’s culture turned PWA Studio into an all-or-nothing bet, and the quality of the actual product in the hands of its users suffered greatly.
If you’ve ever imagined what a more simple approach to a modern Magento frontend would have looked like you might have imagined something a lot like the new Hyvä Themes product that’s set to land in 2021.
Hyvä is a complete reimagining of Magento’s frontend that lives within the traditional Magento 2 MVC application, and is built by a team of working Magento professionals.
I had a chance to see a preview of this new system, and I wanted to talk a bit about what makes it special. Before we get to that though, we’ll need to briefly review how Magento 2 handles CSS and Javascript. This article will touch briefly on some of Magento’s layout and theme system features. If you’re interested in learning more about these systems my book, No Frills Magento Layout, is a good place to get the real story.
Magento’s CSS Rules
Magento’s theming system allows theme developers to add CSS and LessCSS style rules to their system, as well as change or add-to the stock blocks and phtml
templates that Magento’s modules add to the system. Themes also allow developers to add or change static files (like CSS, javascript, and image files) that will be <link/>
ed or <script/>
ed into the final HTML page served by Magento
Magento 2 ships with two themes: Magento/blank
and Magento/luma
. The Magento/blank
theme is where Magento’s main style sheets are added to the system.
<!-- File: vendor/magento/theme-frontend-blank/Magento_Theme/layout/default_head_blocks.xml -->
<head>
<!-- confusingly, although configured with .css, these directive will
load the .less file located here
vendor/magento/theme-frontend-blank/web/css/styles-m.less
vendor/magento/theme-frontend-blank/web/css/styles-l.less
vendor/magento/theme-frontend-blank/web/css/print.less
-->
<css src="css/styles-m.css"/>
<css src="css/styles-l.css" media="screen and (min-width: 768px)"/>
<css src="css/print.css" media="print"/>
<meta name="format-detection" content="telephone=no"/>
</head>
These stylesheets are LessCSS files that are compiled into CSS behind the scenes. The Magento/blank
theme is also where all the default .less
files for a Magento system live. Interestingly, there are some _module.less
files located in Magento modules. This is interesting because without the main styles-m.less
file added by the Magento/blank
theme, these _module.less
files will not be loaded into the system.
The intent behind the Magento/blank
theme is to give users a basic, plainly styled Magento system.
The Magento/luma
theme uses Magento/blank
as a parent. The intent behind the Magento/luma
theme is to provide a site whose style and design reflects the trends of 2014/2015 web design, and to demonstrate Magento’s theme inheritance.
Magento’s Main Javascript Library
Magento 2’s main javascript library is RequireJS. However, this library is not loaded by either the Magento/luma
or Magento/blank
theme.
When Magento 2 renders out the HTML for a page, it starts with a basic root skeleton page. Then, the layout system builds the contents of of the <body/>
tag. The layout system also has directives that control what’s rendered in the HTML page’s <head/>
tag.
This <head/>
/<body/>
split was a big change from Magento 1. If you’re curious, you can see the skeleton template we’re talking about here.
<!-- File: vendor/magento/module-theme/view/base/templates/root.phtml -->
<!doctype html>
<html <?= /* @noEscape */ $htmlAttributes ?>>
<head <?= /* @noEscape */ $headAttributes ?>>
<?= /* @noEscape */ $requireJs ?>
<?= /* @noEscape */ $headContent ?>
<?= /* @noEscape */ $headAdditional ?>
</head>
<body data-container="body"
data-mage-init='{"loaderAjax": {}, "loader": { "icon": "<?= /* @noEscape */ $loaderIcon ?>"}}'
<?= /* @noEscape */ $bodyAttributes ?>>
<?= /* @noEscape */ $layoutContent ?>
</body>
</html>
with those variables being set here
#File: vendor/magento/framework/View/Result/Page.php
$requireJs = $this->getLayout()->getBlock('require.js');
$this->assign([
'requireJs' => $requireJs ? $requireJs->toHtml() : null,
'headContent' => $this->pageConfigRenderer->renderHeadContent(),
'headAdditional' => $addBlock ? $addBlock->toHtml() : null,
'htmlAttributes' => $this->pageConfigRenderer->renderElementAttributes($config::ELEMENT_TYPE_HTML),
'headAttributes' => $this->pageConfigRenderer->renderElementAttributes($config::ELEMENT_TYPE_HEAD),
'bodyAttributes' => $this->pageConfigRenderer->renderElementAttributes($config::ELEMENT_TYPE_BODY),
'loaderIcon' => $this->getViewFileUrl('images/loader-2.gif'),
]);
The end result is a set of script tags that look something like this
<script type="text/javascript" src="http://example.com/static/version1607639848/frontend/Magento/luma/en_US/requirejs/require.js"></script>
<script type="text/javascript" src="http://example.com/static/version1607639848/frontend/Magento/luma/en_US/mage/requirejs/mixins.js"></script>
<script type="text/javascript" src="http://example.com/static/version1607639848/frontend/Magento/luma/en_US/requirejs-config.js"></script>
These <script/>
tags initialize a system that does a lot more than your usual RequireJS module loading. One feature of Magento 2’s javascript system is scanning the page for x-magento-init
sections — each of these sections initializes an individual UI Component which renders KnockoutJS templates. I wrote a bunch about these systems back in the 2015/2016 time frame in my Magento 2 Advanced Javascript, Magento 2 UI Components, and uiElement Internals series — but don’t feel I got to the heart of how best to use these systems. Perhaps their hearts were missing.
I had hopes that, as time went on, these systems would see evolution and improvement. Unfortunately, Magento put them into a support-only mode — eligible for small bug fixes, but not for significant improvements and iteration.
What Makes Hyvä Different
The Hyvä templates project bills itself as a theme, but it’s more than that.
Most third party Magento 2 themes follow the pattern establish by Magento/luma
: They use Magento/blank
as a parent theme. Even themes that don’t inherit from Magento/blank
often use a copy of Magento/blank
as their starting point.
The HTML rendered by Magento’s modules includes class and ID names that are built to be used by the default .less
files. By starting with Magento/blank
a theme gives itself a head start and builds on the work done by the Magento 2 core team.
As a theme developer, straying too far from what’s in the Magento/blank
theme means you risk breaking Magento’s design. There’s nothing that says a theme developer MUST use Magento/blank
— but for most theme developers “Why take a chance” is the operating assumption. Whether it’s a third party theme for distribution, or a single project’s theme, a theme developer has enough work to do that they’re not going to risk breaking things in new and time consuming ways.
When the team behind Hyvä asked themselves the question “Why take a chance” — their answer was: “Because things could be so much better”.
Hyvä’s Technical Approach
The preview of the Hyvä project I saw has two different themes: Hyva/reset
and Hyva/default
. In one way these themes have a relationship that’s similar to the relationship between Magento’s default Magento/blank
and Magento/luma
themes. The Hyva/default
theme has Hyva/reset
set as its parent. The Hyva/reset
theme is a base theme with no parent.
However — the Hyva/reset
theme has a very different job than Magento’s blank theme. The Hyva/reset
theme removes Magento’s LessCSS styles completely in favor of a system built around Tailwind CSS. This isn’t unprecedented — the SnowdogApps SASS theme does something similar in order to use the Sass CSS system.
What happens next is, in my experience, unprecedented. In addition to removing LessCSS in favor of Tailwind CSS, the Hyva/reset
theme uses layout handle XML override files to remove every block that Magento’s modules would normally add to the base page layouts, and removes every frontend asset file (javascript, CSS, etc.) file as well. The goal of Hyva/reset
is to make every page in Magento render as a blank skeleton HTML page.
Unlike Magento/blank
, the Hyva/reset
theme creates a useless website. The Hyva/default
theme is where the actual “theme” is implemented — but this is more than a theme. Page by page, the Hyva/default
theme rebuilds the entire Magento 2 frontend experience with new blocks and templates (sometimes based on the old blocks and templates) using HTML, TailwindCSS and the AlpineJS javascript framework.
Hyvä is a complete rebuild of Magento 2’s frontend cart system using a proven modern technology stack that, unlike PWA Studio, fits inside Magento 2’s traditional application architecture.
It takes what’s there, and makes it better.
Better How?
So why is this an improvement? Magento’s UI Components system requires a tremendous amount of javascript. Magento’s UI Components system is architected in such a way that the loading of these javascript resources is inefficient and hard to optimize. All the UI Component module files and KnockoutJS template files slow down the frontend rendering. Thanks to Magento 2’s static file server, each request for a new (or changed) frontend asset requires the invocation of a full PHP process with a partial Magento bootstrap. This can quickly overwhelm a filesystem and make things very slow.
The switch to AlpineJS means the number of javascript files loaded per page is dramatically reduced. For example, on the Category Listing page a stock Luma theme makes two hundred and fifty five network requests.
While Hyvä’s version of the same page makes thirteen network requests
And because there’s so few we can tell five of them are from Commerce Bug, which is not part of Hyvä.
Magento does have options for bundling those two hundred and fifty-ish files, but with bundling
- You’ve introduced one more thing you need to deal with and your developer experience is still tremendously slow.
- You get to handle a whole host of issues with bundling in Magento 2 that don’t have great solutions.
It’s a similar story for Magento’s layout/block system. Here’s a zoomed out diagram of the block hierarchy of a Luma Category Listing Page
and here’s the same hierarchy with Hyvä.
Commerce Bug counts it at sixty eight blocks vs. twenty three blocks. Again, a less complex page will be both a more performant page and require less cognitive overhead to reason about.
Why Hyvä?
Hyvä’s currently in a pre-release/limited beta, with a full release planned for 2021. The theme has a “hefty for a consumer theme” price tag, but when you consider the work that went into it and what you’d need to pay a team to perform the same tasks manually it’s a steal. It’s also worth noting that a Hyvä purchase gets you access to the Hyvä community slack room where you and your team can get support directly from the Hyvä core team and other community members.
Hyvä’s also a chance to open your Magento practice to a whole set of developers who’ve come up on TailwindCSS and AlpineJS’s angular-like javascript. Also, it’s a chance for teams who specialize in TailwindCSS and angular-like javascript frameworks to break into Magento 2 work.
What excited me most about Hyvä is it’s built by real, working, Magento 2 developers. Hyvä’s origin story isn’t mine to tell, but I do know the Hyvä team has taken their project tested approach to building modern Magento sites and productized it into this theme. In that way Hyvä’s getting back to Magento’s original roots in a way we haven’t seen since before the eBay acquisition — this is software built by developers for developers.
If you still find yourself in the business of building Magento 2 sites, Hyvä is worth checking out.