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

时间:2018-04-30 14:30:45

标签: javascript jquery performance jquery-deferred

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

<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>

这确实提高了页面加载性能。不幸的是副作用是处理表单帖子的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代码以使其正常工作?

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

在你的情况下,jQuery可以很容易地推迟,如果你可以打破一些(非常少的)浏览器的兼容性。有几种选择:

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

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

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

你会用

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

第二个代码段与$(function() {})完成相同的操作,但是在解析页面时不需要加载jQuery。所以当监听器执行时,jQuery将可用。

98% of browsers支持附加到DOMContentLoaded。 (虽然您仍在使用defer,但这会将您限制为95% support,最多。)

旧浏览器也有polyfills

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

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

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

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

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