【问题标题】:Responsive menu (mmenu) cause high CLS响应式菜单 (mmenu) 导致高 CLS
【发布时间】:2020-12-09 11:37:17
【问题描述】:

我在我的网站上使用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 问题?

【问题讨论】:

  • 不确定究竟是什么导致了 cls,这也取决于菜单在之前/之后的外观,但我想说在 mmenu 执行之前尝试隐藏菜单是值得的。添加一个类做菜单,使其占据所需的空间,可能是一个加载器,并在 mmenu 执行后删除这个类,这样可以最大限度地减少布局更改并避免任何硬闪烁。

标签: javascript html jquery performance google-search-console


【解决方案1】:

如果没有任何使用 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>

【讨论】:

  • 其实我不知道你为什么被否决。这是一个简单且有效的解决方法。
【解决方案2】:

如果没有看到实际代码很难回答,但不必等待整个页面准备好,您可以以不需要使用 jQuery 的 ready 调用的方式定位脚本.

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

另一个选择是让你的 body 显示加载动画,直到 jQuery 和其他 cdn 加载完毕,这样你就可以获取所有内容,运行该 mmenu 调用,然后才向用户显示内容,这个方法是比我建议的更人性化一点,因为它实际上会显示一些反馈,即正在为连接速度较慢的用户加载内容,而不是空白屏幕。

【讨论】:

    【解决方案3】:

    我处理此问题的方法是使用与问题元素具有相同大小/形状/颜色的虚拟元素充当占位符,同时隐藏问题元素。加载 jQuery 后,我将删除/隐藏虚拟元素并显示问题之一。

    【讨论】:

      【解决方案4】:

      要解决此类问题,您需要更改一些代码结构以及 java 脚本和 CSS 的顺序,这需要一些努力/测试。

      但您可以尝试显示加载器/进度条,直到加载“mmenu”,这可能会解决您的问题。

      【讨论】:

        猜你喜欢
        • 2020-11-05
        • 1970-01-01
        • 2013-05-10
        • 1970-01-01
        • 2015-02-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多