Today we finished the last phase of speed optimization for the theme and this gives us 100 grade. I want to share you some details about what we did and which unique options we implemented.
1. First step – Files.
It was to find most heavy sized files that are generated on site. It was icon font in our case. We used Fontawesome icons as many other developers and this was a problem. FA icons added more and more size in each version. So, we decided to make our own icon font bundle. Size was reduced from 1 mb to 24kb. This was the first victory in this war.
2. Second step – Google fonts
Second step was to disable default google fonts. Google font is an external request and it can’t be cached and optimized. We studied a lot of sites and found the best set of fallback fonts which are very similar to Roboto. Now, we removed request to Roboto font and at the same time, if the user has no Roboto installed on the system, he will see very similar, cross-system, cross-browser universal fonts. This reduced another 100kb size on site and 1 external request.
3. Third step – CSS framework.
Third step was to build own css framework. Most of the themes use Bootstrap, Materialise, Foundary, Tailwind, or other frameworks. Yes, it has a sense because frameworks have all useful styles and you don’t need to make new styles again and again for all new blocks. But this has own price – Bootstrap has minimum 200kb for basic styles. At some point, we thought that we can use customized Bootstrap, but we decided to use another approach. Instead of adding all styles together, we decided that we will add only those styles which we need in the current point.
Example – Bootstrap has a lot of styles to control margins on Mobiles. You can add, for example, 10px right margin only for mobiles or only for tablets. But we found, that such styles never used. In 99.99% of cases, when you build a mobile site, you want all elements to be stacked under each other and have only margins at the bottom. So, we added styles only for the bottom mobile margin.
The result – instead of 200 kb, our framework for common styles is 20kb. At the same time, we are not limited to using flexbox or other popular systems and can use also CSS grid and other experimental features without waiting for updates for bootstrap or other frameworks.
4 Step – code refactoring
The fourth step was to refactor code and make all blocks to use new framework and modern styles for CSS grid and flexbox features. This saved near 100 kb.
5 – File loading.
The fifth step – refactoring for javascript and styles requesting. 5 years ago, before web vital requirements, google and gtmetrix reduced scores when you have many browser requests to files. All developers tried to add all scripts and files in one file. Today is different. Google wants to have less size of files instead of less requests. So, we divided all scripts and styles into logical parts and separate files. Even if it’s just a few lines of code. We made separate styles and scripts for all blocks, widgets, modules, shortcodes, Gutenberg blocks and enabled them only if the block is used on page. This saved another 120kb.
6 – Images
This is the weakest part of WordPress. It simply doesn’t have a good resizer. Of course, we can build our own, but then, we will lose compatibility with different plugins. We have a long journey in our fight with images and finally, we decided to use hybrid method. For small images and for blocks which are not very often in use on sites of our clients we used our own resizer. Even if it will have no compatibility with CDN or plugins, there is little chance that the client uses this block on site with CDN, also he can use another widget or block if he has issues.
For most common blocks and product loops, we created few predefined sizes of images and added a special wrapper around regular WordPress thumbnal function which allows us to add custom lazy load for images, custom fallbacks for images, support for Ajaxed parts, and in the same time this has compatibility with plugins, because we use regular WordPress functions.
On inner pages, we decided to use regular WordPress images without any modifications, especially in fact that WordPress 5.5 version has lazy load for inner images.
This was fixed problem with different kind of google warnings about image sizes. By the way, we see now, that google executes all scripts before checking page in first screen. So, we recommend to avoid using big images in first screen even if it has lazy load. For this purpose, we made many post layouts which show the small featured image. Looks like, big titles are more in trend now than big images.
7 – Shortcode and block optimization.
We found that some blocks have more impact on speed than other. Of course, if you use featured grids with big images or video playlist from YouTube, they will drop speed. So, we implemented special lazy loading bocks for videos and redesign many blocks by implementing lazy loading for blocks. Also, we made iframes for YouTube and playlist block to load only on click instead of initialization on loading. For blocks that uses background images we implemented special Background lazy loading. We also were forced to remove some outdated blocks for old plugins.
We also revisited Elementor blocks. Unfortunately, Elementor is a very slow plugin and not optimized, it generated tons of code and styles. We were forced to customize some core functions of Elementor for most weak parts, so, our Elementor pages usually get over 90 scores on Homepage with tons of blocks and animations. The same pages on other well optimized themes have near 70-80 score.
8. Step number eight
Animations. Most of the developers use CSS animation libraries. Yes, it’s good for development as it’s easy to use. But not good for speed because you need to load additional styles (usually 50-150 kb). We used GSAP instead. It’s the most optimized animation javascript library. In some scenarios, it’s even faster then CSS transformation and it’s very powerful. We added our WOW animation framework and you can see many powerful animations on our demos that are not rendered blocking and very smooth. We even replaced the popular revolution slider plugin hero headers. This saves near 200 kb and allows to remove one heavy plugin
Last step. Conditional non render blocking css.
Here we need to mention the biggest problem nowadays – CLS and render-blocking. The problem is that Google wants to see non render-blocking styles, but styles are loaded in the header in WordPress and are render-blocking. There is the reason for this. If you place styles in footer, page will be unstyled while loading, this causes big CLS (flashing and reflow while page loading). So, you can fix render-blocking, but this can cause CLS and score drop.
Again, we decided to use Hybrid method. We divided all styles on logical parts. Some of them are loaded globally in general style file, some of them are loaded only on special pages, for example, some styles are loaded only on inner pages, some styles are loaded in Account pages, etc. Plus, we created a special inline function which loads styles inline in code, this makes styles non render blocking and not affecting CLS. I hope WordPress will add some similar functionality but in current point we use our own unique approach and this allows to get 100 score and makes our theme one of best optimized theme.
What’s next?
Currently, we are concentrated to build our own page builder for Gutenberg which will be the fastest and most optimized, because it doesn’t generate any global scripts and styles at all + uses our WOW animations based on GSAP. Then, we can remove Elementor from our sites, this should make complex Homepages and complex inner pages work as fast as a simple post with text.
Also, we will continue to improve CLS for layouts. It’s really hard, because we simply can’t know which images are used by users. Sometimes they use rectangle ratio, sometimes external featured images, very big images or very tall and there is no special height and crop format which fits all users.
P.s. Theme and plugins are just 30-50% of your speed score. Another 50% is your hosting and cache optimization. What’s you need to check for hosting is TTFB. If it’s more than 500ms – maybe it’s better to change hosting.
Another thing that you MUST use is cache plugins. We added big step tutorial about free plugins that we use on our sites. Without a reasonable and good configured cache system, it’s not possible to get a 100 grade. I hope you understand this.
Check first comment for link on tutorial for WordPress about our cache system based on free plugins and some examples of our pages.