Skip to main content

YOOtheme Pro and Cumulative Layout Shift (CLS) problem in PageSpeed Insights

Since Google started to use Cumulative Layout Shift (CLS) metric in PageSpeed Insights, most of websites with YOOtheme Pro template were affected and the mobile page score is much lower than before.

The issue can be related to high CLS which also affects the indexing probability of these pages since Google applies mobile-first logic.

Cumulative Layout Shift (CLS): measures visual stability. To provide a good user experience, pages should maintain a CLS of 0.1. or less.

You can find more details about CLS here.

The origin of the problem is that left and right header toolbars are not initially positioned into single line. Additionally, if you are using the modal mobile menu (like our site) the modal block is not hidden by default.

Only once the UIkit has parsed elements with special attributes like <div id="tm-mobile" class="uk-modal-full" uk-modal> and <nav uk-navbar="container: .tm-header-mobile">, it adds the special CSS classes which position the elements in the proper way.

You will not see any issues on page load, but actually before CSS classes are applied the header toolbars and mobile menu modal consume vertical space and the #tm-main block with main content is far below the final location.

This results to huge shift of #tm-main and PageSpeed doesn't like it.

The issue was spotted after hours of investigation and finally using the debugger; code in UIkit's function scheduleFlush helped to see what happens.

Simple custom CSS will help you to significantly reduce the CLS value:

#tm-mobile:not(.uk-modal) {display: none;}
.tm-header-mobile nav[uk-navbar] {display: flex;position: relative;}

Additionally, you need to set the width and height attributes for all images.

Also set the height and visibility for slider images.

Also use font-display: swap; for all @font-face declarations.

UPDATE:

UIkit uses custom attributes for own components, next the CSS classes are added and re-position the element. The solution for initial closest element position is to have position-related CSS properties.

This code helps in most cases:

[uk-modal] {display: none; position: fixed}
nav[uk-navbar] {display: flex;position: relative;}
[uk-grid] {display: flex;flex-wrap: wrap;list-style: none;}