页面📃的生命周期小记

488 阅读3分钟

首发于掘金
原文链接
转载请写明掘金链接

前言 🎤

整个页面加载是用户体验界面最重要的一部分,当你对浏览器对页面生命周期更为了解后,可以更好优化很多场景下的问题。

三个事件 DOMContentLoaded load beforceunload/unload

一个页面由三个重要事件构成

  • DOMContentLoaded 表示浏览器已经完全加载完HTML并且构建完成DOM树🌲,但是此时一些外部资源并不一定完成,比如(样式表,图像,iframe等等)。
  • load 表示浏览器已经彻底的加载完成了所有的内容
  • unload 当用户离开页面时
  • beforceunload 当用户离开页面前 同时,DOMContentLoaded为document上的事件,而其他的为window上。

DOMContentLoaded

监听:

document.addEventListener("DOMContentLoaded",()=>{})

要注意的是,文档中任何<script>都会在DOMContentLoaded触发之前执行完成。

Script

要注意的是,当浏览器在处理页面的时候,遇到了任何<script>,都会让脚本先执行完成。
除了动态插入的脚本或者具有async的脚本。

Style

DOMContentLoaded一般不会被样式表堵塞,但是如果在<link>标签之后有任何的<script>标签出现,那么就会强制等待样式表加载完成才会触发DOMContentLoaded
请注意,是任何的<script>标签

自动填充

浏览器会尝试自动填充表单,而且是在触发DOMContentLoaded的时候,如果说页面被某个奇怪的东西堵塞了,那么自动填充也不会被触发。

onload

当整个页面上一切的东西动被加载完成的时候,便会执行window.onload回调。在这个阶段,任何内容(除了动态插入的)都已经准备就绪。

onbeforceunload/onunload

beforceunload和unload比较特殊,在这两个事件中,任何alert,confirm都会被浏览器阻止。但是如果在beforeunload的回调中return false,浏览器则会提醒用户是否要离开此页面,当然unload中是无法做到此类操作的,因为在unload中,已成定局。

时机不对

如果你在页面加载完成之后才去监听DOMContentLoaded,那你永远也不会得到任何回应。不过浏览器中可以通过读取状态标识来判断是否加载完成。比如可以通过document.readyState进行判断。它的值有三种情况:

  • loading 页面正在加载
  • interactive 页面已经加载了,但是外部资源的状况还不明朗
  • complete 这个页面上的任何东西都已经被加载了

async defer

既然提到了,那么也就顺势的讲一下。 async和defer都是让script脚本进行并行加载的关键词,他们的区别其实在于执行时间点。同时,如果两个同时存在,那么会优先async

关于defer

  • 即使加载完成,也会按照出现顺序执行。
  • 只会在页面解析完成后执行,但是在DOMContentLoaded之前执行。(和文章开始时的观点一致) 关于async
  • 加载完成立刻执行,没有先后顺序

但是,如果<script>标签中有脚本内容,这两个属性都无效。

总结 👨‍🏫

页面在加载时有三层状态

  1. 完全什么都不知道的情况
  2. DOM元素已经加载完成了,但是外部资源的情况不太清楚
  3. 全部的东西都加载完成了,包括外部资源

DOMContentLoaded处于(2)的状态。onLoad处于(3)的状态。但是两者都可以获取到DOM元素。