专栏首页WebJ2EE【前端】:async、defer、onload、DOMContentLoaded

【前端】:async、defer、onload、DOMContentLoaded

1. async、defer

1.1. 基础

The HTML <script> element is used to embed or reference executable code; this is typically used to embed or refer to JavaScript code.

不引入 defer、async 时

<script> 资源并行下载、按引入顺序执行

<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<!DOCTYPE html>
<html>
<head>
    <title>Title</title>
    <meta http-equiv="x-ua-compatible" content="IE=edge,chrome=1">
    <script type="text/javascript" src="delay2s.js"></script>
    <script type="text/javascript" src="delay1s.js"></script>
    <script type="text/javascript" src="delay4s.js"></script>
</head>
<body>
    <script type="text/javascript" src="delay3s.js"></script>
    <h1>defer-async</h1>
    <script>
        document.addEventListener('DOMContentLoaded',function(){
            console.log("DOMContentLoaded!");
        });
        window.onload = function(){
            console.log("onload!");
        }
    </script>
    <script type="text/javascript" src="delay8s.js"></script>
</body>
</html>

1.2. async

For classic scripts, if the async attribute is present, then the classic script will be fetched in parallel to parsing and evaluated as soon as it is available. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#Attributes

示例:

<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<!DOCTYPE html>
<html>
<head>
    <title>Title</title>
    <meta http-equiv="x-ua-compatible" content="IE=edge,chrome=1">
    <script type="text/javascript" src="delay2s.js" async></script>
    <script type="text/javascript" src="delay1s.js" async></script>
    <script type="text/javascript" src="delay4s.js" async></script>
</head>
<body>
    <script type="text/javascript" src="delay3s.js"></script>
    <h1>defer-async</h1>
    <script>
        document.addEventListener('DOMContentLoaded',function(){
            console.log("DOMContentLoaded!");
        });
        window.onload = function(){
            console.log("onload!");
        }
    </script>
    <script type="text/javascript" src="delay8s.js" async></script>
</body>
</html>

1.3. defer

This Boolean attribute is set to indicate to a browser that the script is meant to be executed after the document has been parsed, but before firing DOMContentLoaded. Scripts with the defer attribute will execute in the order in which they appear in the document. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#Browser_compatibility

示例:

<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<!DOCTYPE html>
<html>
<head>
    <title>Title</title>
    <meta http-equiv="x-ua-compatible" content="IE=edge,chrome=1">
    <script type="text/javascript" src="delay2s.js" defer></script>
    <script type="text/javascript" src="delay1s.js" defer></script>
    <script type="text/javascript" src="delay4s.js" defer></script>
</head>
<body>
    <script type="text/javascript" src="delay3s.js"></script>
    <h1>defer-async</h1>
    <script>
        document.addEventListener('DOMContentLoaded',function(){
            console.log("DOMContentLoaded!");
        });
        window.onload = function(){
            console.log("onload!");
        }
</script>
    <script type="text/javascript" src="delay8s.js" defer></script>
</body>
</html>

1.4. 总结

Both async and defer scripts begin to download immediately without pausing the parser and both support an optional onload handler to address the common need to perform initialization which depends on the script. The difference between async and defer centers around when the script is executed. Each async script executes at the first opportunity after it is finished downloading and before the window’s load event. This means it’s possible (and likely) that async scripts are not executed in the order in which they occur in the page. The defer scripts, on the other hand, are guaranteed to be executed in the order they occur in the page. That execution starts after parsing is completely finished, but before the document’s DOMContentLoaded event.

2. load、DOMContentLoaded?

2.1. DOMContentLoaded

当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像和子框架的完成加载注意:DOMContentLoaded 事件必须等待其所属script之前的样式表加载解析完成才会触发

兼容性:

行为模拟:

在IE8中,可以使用readystatechange事件来检测DOM文档是否加载完毕.在更早的IE版本中,可以通过每隔一段时间执行一次document.documentElement.doScroll("left")来检测这一状态,因为这条代码在DOM加载完毕之前执行时会抛出错误(throw an error)。

测试示例1:

<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<!DOCTYPE html>
<html>
<head>
    <title>Title</title>
    <meta http-equiv="x-ua-compatible" content="IE=edge,chrome=1">
</head>
<body>
    <h1>defer-async</h1>
    <script>
        console.log(new Date());
        document.addEventListener('DOMContentLoaded',function(){
            console.log("DOMContentLoaded!", new Date());
        });
        window.onload = function(){
            console.log("onload!", new Date());
        }
    </script>
    <link rel="stylesheet" href="delay3s.css">
</body>
</html>

测试示例2:

<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<!DOCTYPE html>
<html>
<head>
    <title>Title</title>
    <meta http-equiv="x-ua-compatible" content="IE=edge,chrome=1">
</head>
<body>
    <h1>defer-async</h1>
    <link rel="stylesheet" href="delay3s.css">
    <script>
        console.log(new Date());
        document.addEventListener('DOMContentLoaded',function(){
            console.log("DOMContentLoaded!", new Date());
        });
        window.onload = function(){
            console.log("onload!", new Date());
        }
    </script>
</body>
</html>

总结:

  • CSS 会阻碍 DOMContentLoaded;
  • CSS 会阻塞 JS 执行;

2.2. onload

The load event is fired when the whole page has loaded, including all dependent resources such as stylesheets and images. This is in contrast to DOMContentLoaded, which is fired as soon as the page DOM has been loaded, without waiting for resources to finish loading. https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event

兼容性:

2.3. jQuery.ready(fn) 源码摘录

API:

// jQuery offers several ways to attach a function 
// that will run when the DOM is ready. 
// All of the following syntaxes are equivalent:
$( handler )
$( document ).ready( handler )
$( "document" ).ready( handler )
$( "img" ).ready( handler )
$().ready( handler )

源码摘录:

参考:

jQuery .ready() API: https://api.jquery.com/ready/ DOMContentLoaded: https://developer.mozilla.org/zh-CN/docs/Web/Events/DOMContentLoaded load: https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event Google's opinionated reference for building amazing web experiences. https://developers.google.cn/web/fundamentals/performance/why-performance-matters async vs defer attributes https://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html caniuse: https://caniuse.com/#search=async https://kinsta.com/blog/eliminate-render-blocking-javascript-css/

本文分享自微信公众号 - WebJ2EE(WebJ2EE),作者:WEBJ2EE

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-12-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【前端】:对象、原型、继承

    在 ES5 之前,JavaScript 语言本身并没有提供可以直接检测属性特性的方法,比如判断属性是否是只读。但是从 ES 开始,所有的属性都具备了属性描述符。

    WEBJ2EE
  • 如何统一、美化编码风格?

    它们配置简单、主流IDE都支持、Ctrl+S就能触发(忘了 Ctrl+Shift+F 吧

    WEBJ2EE
  • 算法:最长公共子序列(LCS)

    LCS 是 Longest Common Subsequence 的缩写,即最长公共子序列。一个序列,如果是两个或多个已知序列的子序列,且是所有子序列中最长的,...

    WEBJ2EE
  • Simditor富文本编辑器的调用

    简单、
  • 跨站脚本攻击(反射型xss)笔记(一)

     payload:  【    ';})</script><script>alert(1)</script>   】

    逆向小白
  • angularjs学习第六天笔记(指令简介学习)

      您好,由于周末有事情,没哟学习angularjs,几天晚上开始继续学习angularjs,坚持加油每一天。谢谢

    小小许
  • angularjs学习第六天笔记(指令简介学习)

      您好,由于周末有事情,没哟学习angularjs,几天晚上开始继续学习angularjs,坚持加油每一天。谢谢

    小小许
  • bootstrap typeahead 输入填充 常用

    <!doctype html> <html> <head> <meta charset="utf-8"> <title>联想控股</title> <m...

    用户5760343
  • 前端切图:一句代码实现返回顶部

    祈澈菇凉
  • 【数据科学家】数据科学家修炼之路

    经常有人问我“要成为数据挖掘工程师或者数据科学家应该读什么书?”类似的问题。下面是一份建议书单,同时也是成为数据科学家的指南,当然,这不包括取得合适大学学位的要...

    陆勤_数据人网

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动