切换到 JS Defer 将 jquery ajax 转换为重新加载整个页面

Switching to JS Defer converts jquery ajax to reload whole page

为了提高网站性能,我更新了我的 javascript 引用以使用延迟,例如:

<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous" defer></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.16.0/jquery.validate.min.js" defer></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validation.unobtrusive/3.2.6/jquery.validate.unobtrusive.min.js" defer></script>
<script src="js/plugins.js" defer></script>
<script src="js/main.js" defer></script>

这确实提高了页面加载性能。不幸的是,一个副作用是处理表单 post 的 jquery 函数不再使用 AJAX 完成,它试图重新加载整个页面,导致返回的内容出现在刷新页面,而不是仅仅更新 DIV.

代码:

<script>
    $(function () {
        $('form').submit(function () {
            if ($(this).valid()) {
                $.ajax({
                    url: this.action,
                    type: this.method,
                    data: $(this).serialize(),
                    success: function (result) {
                        $('#result').html(result);
                        document.getElementById('contactForm').style.display = "none";
                    }
                });
            }
            return false;
        });
    });
</script>

如何更新此 jquery 代码以在脚本延迟时正常工作?

我建议不要在 jQuery.js 参考中使用 defer。 jQuery 插件依赖于首先加载的主要 jQuery 库。

While there are ways to get around this 坦率地说,在大多数情况下,它们笨拙且过于复杂。

在你的情况下 jQuery 可以很容易地推迟,如果你不介意破坏某些(极少数)浏览器的兼容性。有几种选择:

1) 用事件处理器控制执行顺序

使用非 jQuery 方法附加到 DOMContentLoaded。即代替

$(function() {
    // handle form work
});

你会用

document.addEventListener("DOMContentLoaded", function(event) {
    // handle form work
});

第二个代码段完成与 $(function() {}) 相同的事情,但不需要在解析页面时加载 jQuery。因此,当侦听器执行时,jQuery 将可用。

最多 98% of browsers. (Though you're still using defer, which limits you to 95% support 支持附加到 DOMContentLoaded。)

还有 polyfills 适用于旧版浏览器。

2) 通过将一些代码移出页面来控制执行顺序

您可以将 $('form') 事件处理程序移动到外部脚本中,延迟在 jQuery 之后加载。正如 Rory 指出的那样,defer 有一些 compatibility issues。但在 95% 的支持下,它仍然是一个不错的选择。

3) 通过捆绑控制执行顺序

正如 Rory 指出的那样,您还可以捆绑(并缩小,以获得更好的性能)并推迟所有 JS。这将确保执行顺序(浏览器将从上到下执行单个 JS 文件)。不支持 defer 的浏览器可能不会获得 所有 的性能优势,但至少 JS 不会因错误排序单独的脚本而被破坏。

跨源、阻塞、外部脚本可以是庞大 performance drain。您必须权衡浏览器兼容性与性能。但是,如果您的目标受众主要使用现代浏览器,我强烈建议尝试推迟 jQuery.