响应式菜单 (mmenu) 导致高 CLS

Responsive menu (mmenu) cause high CLS

我在我的网站上使用 mmenu 作为响应式菜单。我最近注意到,在 Google 的搜索控制台中,由于高 CLS(累积布局偏移)而出现错误。我检查了一下,这是真的,当我尝试以“慢速”模式打开我的页面半秒时,我看到了原始菜单结构,然后加载了 mmenu(在 jQuery 准备好等之后)并且页面显示正确。

我的简化页面结构是:

    $(document).ready(function() {
        $("#menu").mmenu({
            "extensions": ["pageshadow"],
            "header": {
                "title": "Menu",
                "add": true,
                "update": true
            }
        }, {
            // config
            offCanvas: {
                pageSelector: "#container"
            }
        });
    });
    <html>
    <head>
    </head>
    <body>
    <nav id="menu">
        <ul>
            
            <li><a>Categories</a>
            <ul>
                <li>
                    <a href="https://example.com/1">Link 1</a>
                </li>
                <li>
                    <a href="https://example.com/2">Link 2</a>
                </li>
                <li>
                    <a href="https://example.com/3">Link 3</a>
                </li>
            </ul>
        </nav>
        <div class="content">This is content</div>
    </body>
    </html>

您怎么看,是否可以在此处应用任何快速修复来解决我的 CLS 问题?

没有任何使用 mmenu 的经验,使用 CSS 隐藏 #menu 并仅在菜单初始化后才显示它是否足够?

这似乎对我有用:

<html>
<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jQuery.mmenu/8.5.20/mmenu.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jQuery.mmenu/8.5.20/mmenu.min.css" />
</head>
<script type="text/javascript" data-no-instant>
$(document).ready(function() {
    $("#menu").mmenu({
        "extensions": ["pageshadow"],
        "header": {
            "title": "Menu",
            "add": true,
            "update": true
        }
    }, {
        // config
        offCanvas: {
            pageSelector: "#container"
        }
    }).css("display", "");
});
</script>
</head>
<body>
    <nav id="menu" style="display: none">
      <!-- <nav> content from your example -->
    </nav>
    <a href="#menu">open menu</a>
    <div class="content">This is content</div>
</body>
</html>

如果没有看到实际代码很难回答,但不必等待整个页面准备就绪,您可以将脚本放置在不需要使用 ready 调用 jQuery.

尝试以下操作:
1 - 在本地加载 jQuery 而不是从 CDN
2 - 将 jQuery 脚本标记放在实际 Body html 数据之前,并将 mmenu 调用紧跟在 body 的 html 代码之后,这样在所有内容加载完成之前不会显示内容

另一个替代方法是让您的 body 显示加载动画,直到 jQuery 和其他 cdns 加载完毕,这样您就可以获取所有内容,运行 mmenu调用然后才向用户显示内容,此方法比我建议的方法多 user-friendly 因为它实际上会显示一些反馈,表明正在为速度较慢的用户加载内容连接。

要解决此类问题,您需要更改 java 脚本和 CSS 的一些代码结构和顺序,这将需要一些 efforts/testing.

但您可以尝试显示 loader/progress 栏,直到加载“mmenu”,这可能会解决您的问题。

我处理这个问题的方法是使用一个与您的问题元素具有相同 size/shape/color 的虚拟元素作为占位符,同时隐藏问题元素。 jQuery 加载后,我将 remove/hide 虚拟元素并显示问题一。