Support » Plugin: Page Builder by SiteOrigin » SiteOrigin – Panels – Web Vitals – CLS

  • Resolved Shane

    (@shanemarsh28)


    Hi, looking for some advice.

    We use your layout builder in the headers of most of our sites. We are also now monitoring web vitals and have noticed most are having issues where the header is shifting. It appears that some inline CSS for siteorigin-panels is injected into the dom via a Javascript. Namely: <style type=”text/css” media=”all” id=”siteorigin-panels-layouts-footer”>…</style>

    If you view the site in question, the header content starts in the top left hand corner and then once the javascript executes the header moves (and all content below it). Is there a setting so it doesn’t do that or a work around so at least some of the critical CSS can be provided in a way that prevents the shift?

    Thanks in advance
    Shane ๐Ÿ™‚

    The page I need help with: [log in to see the link]

Viewing 15 replies - 1 through 15 (of 16 total)
  • Plugin Contributor alexgso

    (@alexgso)

    Hi Shane,

    The highlighted inline CSS isn’t being added by JavaScript. The delay is due to the browser not rendering it quickly enough. Unfortunately, it’s not possible to reposition that CSS out of the box. You’ll need to use a minify/performance plugin that allows you to do this. A popular plugin that allows this is Hummingbird.

    Kind regards,
    Alex

    Thread Starter Shane

    (@shanemarsh28)

    Hi Alex,

    If I emulate a slow 3G connection and stop the loading at the point where the class .siteorigin-panels-before-js exists in the body tag and JavaScript has not fired, <style> id#siteorigin-panels-layouts-footer does not exist. This is confirmed when I inspect the elements .panel-grid and the child .panel-grid-cell because the primary CSS that is being applied comes from: lsow-layouts.css, front-flex.min.css and <style> #siteorigin-panels-layouts-head. If your assessment was correct I would expect to see the <style> #siteorigin-panels-layouts-footer within the HTML source code too which is not the case.

    For further evidence please take a look at this webpagetest: https://www.webpagetest.org/video/compare.php?tests=200911_7B_2513f5a7bc0d5b79638a6e40b7d5a8c1-r%3A1-c%3A0&thumbSize=200&ival=16.67&end=visual

    Change the thumbnail interval to 60FPS and you’ll see that at 2.501 seconds the header shifts as described. This is also the point where element 26 (jquery.js) begins its execution, the left aligned text becomes right aligned and further margins are added (#pl-w5efc71048c641 .so-panel { margin-bottom:30px }) causing the content to shift downwards. These CSS definitions are added via <script> #siteorigin-panels-layouts-footer which did not exist earlier.

    Sorry to openly contradict you but please take another look at your plugins code because I feel very sure that your assessment is not accurate. I can’t see any other way this behaviour could be possible other than for CSS being injected and then redrawn into the DOM after the browsers largest contentful paint.

    Kind regards,
    Shane

    PS: We use mod_pagespeed for optimisation but note the query string in the links I have given disabled it for the purposes of making debugging easier.

    Thread Starter Shane

    (@shanemarsh28)

    Hi Alex,

    Further to my reply a few moments ago, I’ve done a little bit of digging and I think the issue is related to /js/styling.js and its associated enqueue within /inc/styles.php line 51. I believe the function on line 57 of the same file wp_localize_script() is the bit where the CSS contained within styling.js is echoed inline AFTER jquery (63). This is why it’s layout shifting.

    I realise wp_localize_script() was once upon a time the only “approved” way to pass PHP variables into Javascript but to do it with CSS looks a little unorthodox – I don’t see the advantage. Anyways to resolve the CSS needs to be built using PHP (which you’re probably doing at some point anyway), then enqueue inline using wp_add_inline_style() instead. Scrap styling.js/styling.min.js.

    Hope this is helpful. Have a lovely weekend.

    Kind regards,
    Shane

    Plugin Contributor alexgso

    (@alexgso)

    Hi Shane,

    You can verify #siteorigin-panels-layouts-footer isn’t being by JavaScript by opening your page and viewing the page source. Search for siteorigin-panels-layouts-footer and you’ll be able to find it. JavaScript is not able to run in the page source so that allows you to confirm what is, and isn’t present before anything is run on your page. You can also see it being added here using PHP.

    I canโ€™t see any other way this behaviour could be possible other than for CSS being injected and then redrawn into the DOM after the browsers largest contentful paint.

    That can be explained by how browsers render pages. The CSS is added towards the end of the document so it will only be displayed once the browser has processed everything prior to that point.

    The code in stylying.js is unrelated to the aforementioned CSS. That file contains a container breaker that allows for rows to be the full width of the page. To achieve this the code uses the DOM which means that the script won’t be executed until the DOM is ready. Depending on how large the document is that may result in a noticeable (and unfortunately unavoidable) delay. Unfortunately, that delay is not unavoidable. To be clear, the container breaker requires JavaScript to allow greater compatibility with a wide range of themes.

    It’s not possible for CSS to use anything added by wp_localize_script and the line you’re highlighted isn’t CSS being added.

    While it is true that we could use wp_add_inline_style to add the CSS inline (rather than outputting it directly), you won’t see any noticeable performance difference by us doing that. To be clear, the container breaker is likely why you’re seeing and not the CSS – that would explain why you’re seeing such a noticeable difference after jquery.js.

    Kind regards,
    Alex

    Thread Starter Shane

    (@shanemarsh28)

    Hi Alex,

    OK allow me to do some more digging, I’ll confer with my colleagues and I’ll come back to you.

    I have data ranging from a couple of hundred websites and almost all sites with layout builders in the header shift at the point the javascript executes and the ones using standard WordPress widgets only don’t fail. They have different activated plugins and themes. For me it wouldn’t be acceptable have a lot of site fail this metric and to just write off the problem by saying it’s just how browsers render the page. I think I need to work out and understand exactly what is happening then maybe with that information we’ll know how to proceed. I’ll do as much as I can but if you have any ideas then I’m all ears ๐Ÿ™‚

    Kind regards,
    Shane

    Plugin Contributor alexgso

    (@alexgso)

    Hi Shane,

    Try adding the following CSS to your critical CSS:

    body.siteorigin-panels-before-js .siteorigin-panels-stretch {
      margin-right: -1000px !important;
      margin-left: -1000px !important;
      padding-right: 1000px !important;
      padding-left: 1000px !important;
      overflow-x: hidden;
    }
    

    This CSS should reduce how noticeable the jump is when the page container breaker JS is run. This CSS is included in the page builder stylesheet, but if that’s been minified it may not be loaded until after the DOM is ready.

    Kind regards,
    Alex

    Thread Starter Shane

    (@shanemarsh28)

    Thanks Alex,

    Sadly adding your CSS hasn’t gained much improvement. Every test seems to show that the header jumps when siteorigin-panels-layouts-footer is read into the DOM – it’s most likely .so-panel{margin-bottom:30px} or the variants of it. I noticed there’s a filter so this could be a simple issue. Is there anyway to get siteorigin-panels-layouts-footer to load in wp_head()?

    Thank you for your patience with me ๐Ÿ™‚

    Kind regards,
    Shane

    Plugin Contributor alexgso

    (@alexgso)

    Hi Shane,

    Thanks for trying.
    You could maybe try adding that CSS directly to your critical CSS to see if that helps.

    Is there anyway to get siteorigin-panels-layouts-footer to load in wp_head()?

    You could in theory do this by hooking into this filter, output the CSS elsewhere, and then return an empty vlaue.

    Kind regards,
    Alex

    Thread Starter Shane

    (@shanemarsh28)

    Hi Alex,

    humm.. struggling to get that to work because I can’t run add_action(wp_header), ‘…’) during a filter thats running under wp_footer(). The action has already been run.

    **head in hands**

    Kind regards,
    Shane

    Thread Starter Shane

    (@shanemarsh28)

    Hi Alex,

    So I have resorted to a dirty trick. I have inserted the following css into the header. This does appear to stabilise things. I’ll let you know if overall scores improve (or not!).

    add_action('wp_head', 'SG_SiteOrigin_Header_Fix');
    function SG_SiteOrigin_Header_Fix() {
    	echo '<style type="text/css" media="all" id="siteorigin-panels-layouts-footer-sg-override">.panel-layout, .panel-grid-cell { width:100% } .so-panel { margin-bottom:30px } .so-panel:last-child { margin-bottom:0px } </style>';
    }

    Kind regards,
    Shane

    • This reply was modified 2 years, 2 months ago by Shane.
    Plugin Contributor alexgso

    (@alexgso)

    Hi Shane,

    Oh. In hindsight, you’re right.
    There’s another filter run just after the CSS is generated and before wp_head called siteorigin_panels_css_object. You should be able to use that filter.

    Kind regards,
    Alex

    Thread Starter Shane

    (@shanemarsh28)

    HI Alex,

    Sorry for my late reply, been a little snowed under ๐Ÿ™‚

    I will give that filter a go and report back. Thanks again.

    Kind regards,
    Shane

    Thread Starter Shane

    (@shanemarsh28)

    OK so we have applied an agricultural solution to the problem – we are now monitoring to see if CLS scores improve. This looks like it might work…

    <?php
    $GLOBALS['siteorigin_panels_css_object_to_head'] = null; //define global variable
    
    add_filter( 'siteorigin_panels_css_object', 'sg_siteorigin_panel_css', 10, 4 );
    function sg_siteorigin_panel_css( $css, $panels_data, $post_id, $layout_data ) {
    
        $css_array = (array) $css;
        foreach ($css_array as $innerArray) {
    
            //loop through outer css array
            $css_output = "";
            foreach ($innerArray as $screensize => $propertyarray) {
    
                if ($screensize >= 1900) {
    
                    //we are dealing with desktop css
                    foreach ($propertyarray as $value => $property) {
                        $css_output .= $property[0]." { ".$value."; }";
                    }
    
                } else {
    
                    //we need to wrap inside a media query
                    $css_output .="media (max-width: ".$screensize."px) {";
                    foreach ($propertyarray as $value => $property) {
                        $css_output .= $property[0]."{ ".$value."; }";
                    }
                    $css_output .= "}";
                }
            }
        }
    
        $GLOBALS['siteorigin_panels_css_object_to_head'] .= $css_output;
        return $css;
    
    }
    
    add_action('wp_head', 'siteorigin_panels_css_object_to_head', 999);
    function siteorigin_panels_css_object_to_head() {
        $siteorigin_panels_css_output = $GLOBALS['siteorigin_panels_css_object_to_head'];
        if(!empty($siteorigin_panels_css_output)) echo "<!-- SiteOrigin CSS Move --><style>".$siteorigin_panels_css_output."</style>";
    }

    Kind regards,
    Shane

    Plugin Contributor alexgso

    (@alexgso)

    Hi Shane,

    Awesome! Thanks for the snippet mate! ๐Ÿ™‚
    Let me know how the results look.

    Kind regards,
    Alex

    Thread Starter Shane

    (@shanemarsh28)

    We are seeing a significant improvement in CLS Scores. Issue resolved. Thank you for your assistance.

Viewing 15 replies - 1 through 15 (of 16 total)
  • The topic ‘SiteOrigin – Panels – Web Vitals – CLS’ is closed to new replies.