Developing a product from scratch takes a lot of compatibility code, code maintenance, cross-browser testing and user testing. Building a WordPress theme/plugin bundle requires a lot of frontend/backend compatibility code starting with PHP/Node.js, the actual WordPress CMS (pre- and post-5.0), all the way to Intersection Observer and Fetch APIs, Promises and CSS variables.
As a quick example, Intersection information is needed for many reasons, such as:
- Lazy-loading of images or other content as a page is scrolled.
- Implementing “infinite scrolling” web sites, where more and more content is loaded and rendered as you scroll, so that the user doesn’t have to flip through pages.
- Reporting of visibility of advertisements in order to calculate ad revenues.
- Deciding whether or not to perform tasks or animation processes based on whether or not the user will see the result.
The Fetch API provides an interface for fetching resources (including across the network), similar to XMLHttpRequest, but with a more powerful and flexible feature set.
For CSS, I want to use Flex, Grid and CSS variables. Oh, and
fit-content. And no CSS preprocessors, as nothing they do can’t be reproduced in CSS.
While Edge is, somewhat, on top of things, IE doesn’t even try. So, what am I supposed to do?
Know Your Audience
The first step is to assess the audience. Is it worth dropping that user segment? Do they bring any benefit to our product and is the respective user segment worth maintaining all the compatibility code we have? We decided that, no, the extra time and maintenance were not justified.
After careful measurements and analysis of user technology, browsers and devices, we started removing things gradually.
As a first example, we use lazy loading. Until Chrome and Firefox will implement the new native lazy loading parameters, we are using a library called yall.js (Yet Another Lazy Loader), implementing all the best practices based on IntersectionObserver. This feature is not available in IE, so yall.js version 2 uses compatibility code, detecting user scrolling. This is rather expensive and delays user interaction time.
yall.js version 3 removes this compatibility and makes the codebase smaller. Instead, they introduce a polyfill, which we disabled by default, but allowed site administrators to enable, based on their audience.
As a second example, we use colour customisation and all the user settings are read on every page load. That’s a lot of inline style. After we switched to CSS variables, all the inline style (sometimes up to 500 lines) disappeared. All CSS variables are written as data attributes and cached. Yay for blazing speed!
Again, we added an optional polyfill for IE10 and IE11, disabled by default.
Moving on to frontend development, Flex CSS requires a bunch of prefixes for MS browsers, old Firefox versions, Safari and Opera. Invariably, something was always breaking in IE. So we added a small note, fixed on top of screen, stating that IE is not meant to be supported. It’s our small contribution to web progress.
Removing jQuery, implementing the Fetch API, removing all browser detection, and using
localStorage instead of PHP cookies, made our product 3 to 4 times faster.
Next in the pipeline – maybe early next year – are CSS snap points,
<details> accordions, autocomplete datalists and WOFF2 custom fonts only, reducing TTI (Time To Interactive) to mere nanoseconds :) – they add up, you know.
More Speed Improvements
As we work a lot with various layouts and templates, we can’t afford to go old-school with our typography, but I can still ask anybody out there, what’s wrong with Times New Roman? Or using the native system fonts (
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Segoe UI Symbol, Segoe UI Emoji, Apple Color Emoji;)? Look at GitHub, they’ve been doing it for a while.
pushState + AJAX) works by fetching HTML from the server via AJAX and replacing the content of a container element on the page with the loaded HTML. It then updates the current URL in the browser using
pushState. This results in faster page navigation for two reasons:
- No page resources (JS, CSS) get re-executed or re-applied.
- If the server is configured for Pjax, it can render only partial page contents and thus avoid the potentially costly full layout render.
As a conclusion, I am happy to say that we have an almost perfect product, streamlined for our clients’ needs (which are all in the same niche), fast, performant, up-to-date, mobile ready and modern-first with enough graceful degradation on antiquated (or stubborn) browsers.