首页 > 其他分享 >性能优化之window.onload

性能优化之window.onload

时间:2023-07-03 10:47:14浏览次数:49  
标签:load onload 触发 window DOMContentLoaded 页面 优化 加载

前言

最近在做一些性能优化相关的工作,相信大家在工作过程中也会遇到一些性能优化相关的场景,这对于前端开发者来讲是一项加分技能。为了我们的用户在使用我们的产品时能够有一个非常好的体验,我们需要对页面进行诊断优化。在行业中,我们的页面P90在两秒内算是达标,超过这个时间那么你就可能会流失部分用户。

TIP:P90指的是页面性能数据从小到大排序,在90%位置的数据。

比如:P90为两秒,那它的意思就是90%的用户都能够在两秒内打开页面

对于性能优化内容可能比较多,我们这里就先着重了解window.onload相关内容。对于页面加载时长,我们就避免不了涉及window.onload

性能分析

做性能优化肯定免不了需要对页面性能进行分析,我们一般会使用ChromeDevTool作为基础的性能分析工具,观察页面性能情况

Network:观察网络资源加载耗时及顺序

Performace:观察页面渲染表现及JS执行情况

Lighthouse:对网站进行整体评分,找出可优化项

今天我们先着重来看Network的相关内容,比如我们打开浏览器控制台:

load-1.png

这里我们可以看到这两项数据:DOMContentLoaded时间为841ms、Load时间为2.06s

它俩分别对应两个事件:

DOMContentLoaded

当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像和子框架的完全加载。

Load

load 事件在整个页面及所有依赖资源如样式表和图片都已完成加载时触发。它与 DOMContentLoaded 不同,后者只要页面 DOM 加载完成就触发,无需等待依赖资源的加载。

看完两者的解释之后,相信大家应该明白了为什么Load花的时间要比DOMContentLoaded长了吧

因为load事件会被大量媒体资源阻塞,浏览器只有在它认为页面上的所有资源都加载完成了才会触发load事件。

两者的区别

  • DOM完整的解析过程:
    • 解析HTML
    • 加载外部脚本与样式文件
    • 解析并执行脚本
    • DOM树构建(DOMContentLoaded事件触发)
    • 加载图片等资源
    • 页面加载完毕(Load事件触发)
  • DOM的解析受JS加载和执行的影响,我们在优化时应尽量对JS进行压缩、拆分处理(HTTP2下),能减少 DOMContentLoaded 时间
  • 图片、视频、CSS等资源,会阻塞 onl oad 事件的触发,我们在优化过程中需要优化资源的加载时机,让load事件尽快触发

深入理解window.onload

onload触发时机

JS 加载并执行完毕且页面中所有外链资源加载完成之后大约 3 - 4ms(这个值跟机型和浏览器有关)

比如:

window.onload = () => {
  console.log('load')
}
setTimeout(() => {
  console.log('timeout')
}, 3)

结果是setTimeout先执行,这里把值改的稍大一点你会发现就是load先执行了

load-2.png

哪些因素会影响window.onload

JS执行

window.onload = () => {
  console.log('load')
}
for(let i = 0; i < 100000; i++) {
  console.log(i)
}

当我们写了一个非常耗时的JS任务时,你会发现DOMContentLoadedLoad事件都会等很久才会触发。

load-3.png

说明JS的执行不仅会阻塞DOMContentLoaded事件的触发,也会阻塞Load事件的触发。所以在优化过程中,JS也是一个重点关注对象。

async异步加载脚本

<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.2.47/vue.cjs.js" async></script>
<script src="https://cdn.bootcdn.net/ajax/libs/Chart.js/4.2.1/chart.js"></script>

为了对比,这里我加载了两个JS文件,一个使用async异步加载,一个直接加载,我们再到控制台来查看此时的加载情况。

load-4.png

这里我们可以看到两个文件都是在Load之前就会加载,只不过使用了async异步加载会比正常加载的后加载,说明使用了async异步加载脚本依然会阻塞Load的触发。

关于async的解释MDN上是这样说的:

对于普通脚本,如果存在 async 属性,那么普通脚本会被并行请求,并尽快解析和执行。

对于模块脚本,如果存在 async 属性,那么脚本及其所有依赖都会在延缓队列中执行,因此它们会被并行请求,并尽快解析和执行。

该属性能够消除解析阻塞的 Javascript。解析阻塞的 Javascript 会导致浏览器必须加载并且执行脚本,之后才能继续解析。

这里可能会有误解,我觉得它应该是不会阻塞其它脚本内容的加载与执行,由于它的加载是在load之前的,所以它依然会阻塞load的触发,但从整体上来看,它对性能优化还是有帮助的。

defer异步加载脚本

这里还是跟上面一样的场景,我们把async换成defer

<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.2.47/vue.cjs.js" defer></script>
<script src="https://cdn.bootcdn.net/ajax/libs/Chart.js/4.2.1/chart.js"></script>

load-5.png

这里看上去跟async的加载没什么不同,它的加载依然会比正常加载的方式滞后,但会在load之前。

关于defer:

这个布尔属性的设置是为了向浏览器表明,该脚本是要在文档被解析后,但在触发 DOMContentLoaded 事件之前执行的。

包含 defer 属性的脚本将阻塞 DOMContentLoaded 事件触发,直到脚本完成加载并执行。

包含 defer 属性的脚本会按照它们出现在文档中的顺序执行。

这个属性能够消除阻塞解析的 JavaScript,在这种情况下,浏览器必须在继续解析之前加载和执行脚本。

所以这里跟上面差不多,对性能优化也是有帮助的,需要注意使用场景。

图片预加载

在工作过程中我们可能会有一些图片预加载的使用场景,主要是为了能够让一些较大的图片资源能够快速的渲染呈现给用户,我们一般会提前加载一次图片,等到真正使用时浏览器就可以直接从缓存中取出并渲染。

<div class="container">
  <img src="https://imgservices.image.com/s06012023/9ac85415.g0q5wz.png" class="zan_icon" />
</div>

<script>
  window.onload = () => {
    console.log('load')
  }
  const img = new Image();
  img.src = 'https://router.vuejs.org/logo.svg';

</script>

比如这里,我们在html里面通过img加载了一张图片,在JS中预加载了一张图片,虽然这张图片并没有真实渲染,但它也是会发起请求的,并影响load事件的触发。

load-6.png

所以我们在做预加载时也需要考虑给页面性能带来的影响

影响load时间执行的内容还有很多,在对页面进行性能优化时,这些内容都是可以进行优化方向

onload与native

我们都知道H5页面在通过native得webview容器进行渲染时,顶部都会有一个加载进度条,有时候在弱网环境下,这个进度条会一直在那慢慢加载,很长时间不会消失,非常影响用户体验,这最主要的原因是onload 的触发被阻塞,从而客户端控制的进度条不会消失,页面调用客户端的方法不会执行。

iOS 中判断 webview 加载完成的 webViewDidFinishLoad 方法,Android 中判断 webview 加载完成的 onPageFinished 方法本质触发时机上都对应页面上的 window.onload,一般来说会稍晚于 window.onload(某些特殊情况会早于 window.onload,比如页面里有 iframe 等情况)。

也就是说 对 onl oad 有影响的因素也同样会影响这些 Native 方法。而在 Hybrid 开发中,一些 Native 和 Web 之间的交互和调用往往要在webViewDidFinishLoad / onPageFinished 之后。因此如果 onload 的触发被推迟了,那么这些 Native 相关的调用也都会被推迟。

因此如果是Hybrid应用,尤其要注意让onload尽快触发。

performance性能统计

DOMContentLoaded事件与Load事件花费的时间,我们可以通过performance 这个对象的一些属性进行统计,时间精确到纳秒级。很多公司的性能监控平台也主要是利用这个对象的数据进行上报的。
load-performance.png

  • connectStart:HTTP(TCP)开始建立连接的时间。如果是持久连接,则和 fetchStart 的时间相等,注意,如果在传输层发生了错误且重新建立连接,这里显示的是新建立连接的开始时间。

  • connectEnd: 完成建立连接的时间。

  • domComplete:DOM 树解析完成,并且资源准备就绪的时间,Document.readyState 变为 complete,并将抛出 readystatechange 相关事件。

  • domContentLoadedEventEnd:DOM 解析完成后,网页内资源加载完成的时间(如 JS、css 加载执行完毕)。

  • domContentLoadedEventStart:DOM 解析完成后,网页内资源加载开始的时间在 DOMContentLoaded 事件抛出前发生。

  • loadEventStart:load 事件触发,也即 load 回调函数开始执行的时间。注意:如果没有绑定 load 事件,值为 0。

  • loadEventEnd:load 事件的回调函数执行完毕的时间。

  • 等...更详细内容可查看MDN文档

如果这篇文章有帮助到你,❤️关注+点赞❤️鼓励一下作者,关注 前端南玖 第一时间获取最新文章~

标签:load,onload,触发,window,DOMContentLoaded,页面,优化,加载
From: https://www.cnblogs.com/songyao666/p/17522140.html

相关文章

  • 全志 Linux 系统启动优化 启动优化速度方式 优化启动流程 优化uboot 优化kernel等
    文章目录1概述2启动速度优化简介2.1启动流程2.2测量方法2.2.1printktime2.2.2initcall_debug2.2.3bootgraph.2.2.4bootchart2.2.5gpio+示波器.2.2.6grabserial.2.3优化方法2.3.1boot0启动优化2.3.1.1非安全启动.2.3.1.2安全启动2.3.2uboot启动优化2.3.2.1完全去......
  • 在凸优化中,标准形式的概念是什么?为什么我们需要它?
    在凸优化中,标准形式(StandardForm)是指将一个凸优化问题转化为一种特定的标准形式表示。标准形式包括以下几个要素:目标函数:要求最小化的凸函数。约束条件:一组线性等式和不等式约束。变量限制:对变量的非负性约束。标准形式的转化是为了方便问题的求解和分析,其原因有以下几点:......
  • 如何构建一个群体智能优化算法?
    构建一个群体智能优化算法可以遵循以下步骤:定义问题:明确需要解决的问题,包括问题的目标、约束条件和可行解空间等。设计群体结构:确定问题的群体结构,包括群体中个体的数量、个体之间的交互方式和信息传递方式等。常见的群体结构包括蚁群、粒子群、鱼群等。设计个体行为规则......
  • 神经网络通过优化方法进行训练。然而,优化技术似乎不是深度学习中最重要的主题。为什么
    在深度学习中,神经网络通过优化方法进行训练,目的是最小化损失函数并获得最佳的模型参数。然而,优化技术在深度学习中并不是最重要的主题,主要原因如下:数据和模型的重要性:在深度学习中,数据的质量和数量以及模型的设计和复杂性对于模型的性能和泛化能力起着至关重要的作用。优化技术......
  • Windows修改Redis端口无效
    步骤1、如果开了Redis服务,先将服务关闭!2、在Window上找到Redis的安装目录,修改config\redis.windows.conf文件,在里面将默认端口改为你想要的端口号3、将redis.windows.conf文件直接拖入redis-server.exe,弹出窗口......
  • virtualbox——windows
    # 官网下载:https://www.virtualbox.org/      ......
  • 最优化问题简介及优秀教材《凸优化》介绍
    前言最优化广泛应用于科学与工程计算、数据科学、机器学习、人工智能、图像和信号处理、金融和经济、管理科学等众多领域。最优化问题可以归纳为如下定义: 最优化问题一般很难求解,除了一些特例。目前已经发展成熟的,能够有效求解的最优化问题可以归为以下三类:最小二乘问题l......
  • mysql性能优化(博学谷)
      索引可以理解为一本书的目录,也是占页数,占存储空间的。key(关键字)-value(磁盘地址或行记录)。 根据关键字去索引里面查,数据结构是B+数,查询速度快。   哈希冲突: 通过key(k1,k2)的hashcode()获取哈希值,经过算法取得在数组上得下标位置,2个key取到了同一个下标,这就是哈希......
  • 卸载Windows 预装App
    有些windows预装的App可能用不上,还会占开始菜单的位置。我卸载预装App的方法是使用Winget这个软件,在微软应用商店搜索Winget.注意不要把"截图和草图"卸载了,很多聊天软件的截屏就是调用的这个应用。安装好了打开一个管理员的Powershell。Wingetlistwingetuninstall--id<......
  • 最强优化指令大全 | 【Linux技术专题】「系统性能调优实战」终极关注应用系统性能调优
    Linux命令相关查看指标CPU指标vmstat指令vmstat-nm该命令用于每隔n秒采集系统的性能统计信息,共采集m次。[root@svr01]$vmstat13procs-----------memory-------------swap-------io------system-------cpu-----rbswpdfreebuffcachesiso......