我的编程空间,编程开发者的网络收藏夹
学习永远不晚

性能优化之window.onload

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

性能优化之window.onload

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

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

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

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

性能分析

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

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

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

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

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

这里我们可以看到这两项数据: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等资源,会阻塞 onload 事件的触发,我们在优化过程中需要优化资源的加载时机,让load事件尽快触发

深入理解window.onload

onload触发时机

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

比如:

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

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

哪些因素会影响window.onload

JS执行

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

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

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

async异步加载脚本


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

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

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

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

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

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

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

defer异步加载脚本

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

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

关于defer:

  • 这个布尔属性的设置是为了向浏览器表明,该脚本是要在文档被解析后,但在触发 DOMContentLoaded 事件之前执行的。
  • 包含 defer 属性的脚本将阻塞 DOMContentLoaded 事件触发,直到脚本完成加载并执行。
  • 包含 defer 属性的脚本会按照它们出现在文档中的顺序执行。
  • 这个属性能够消除「阻塞解析的 JavaScript」,在这种情况下,浏览器必须在继续解析之前加载和执行脚本。

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

图片预加载

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

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

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

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

onload与native

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

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

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

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

performance性能统计

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

  • 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文档

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

性能优化之window.onload

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

性能优化之window.onload

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

服务器性能优化之网络性能优化

今天分享一篇后台服务器性能优化之网络性能优化,希望大家对Linux网络有更深的理解。

Android性能优化之网络优化

在移动互联网的快速发展环境下,手机用户日益对网络的使用或体验有着更深度的诉求,因此应用中的网络体验已经显得由此重要。

性能优化利器之Constexpr

说明符constexpr​是自C++11引入,我相信很多人跟我一样,在第一次接触这个的时候,会很容易和const混淆。

Android性能优化之弱网优化详解

这篇文章主要为大家介绍了Android性能优化之弱网优化示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-11-13

React性能优化之useMemo、useCallback

记忆化用于提高React应用程序的性能,记忆化用于跳过组件的不必要重新渲染。useMemo和useCallback​钩子分别用于记忆化返回值和函数声明。虽然useMemo和useCallback​的行为类似,但两者之间存在关键差异。useM

Android性能优化之Bitmap图片优化详解

前言 在Android开发过程中,Bitmap往往会给开发者带来一些困扰,因为对Bitmap操作不慎,就容易造成OOM(Java.lang.OutofMemoryError - 内存溢出),本篇博客,我们将一起探讨Bitmap的性能优化。
2022-06-06

Android性能优化之运算篇

运算篇1) Intro to Compute and Memory ProblemsAndroid中的Java代码会需要经过编译优化再执行的过程。代码的不同写法会影响到Java编译器的优化效率。例如for循环的不同写法会对编译器优化这段代码
2022-06-06

Ceph OSD CPU 性能优化 之一

目前,我们正在进行多种方法来优化 Ceph 的数据路径,但现实情况是 Ceph 一直都是需要相当多的 CPU 才能充分发挥出比如像 NVMe 这样高速存储设备的性能。
Ceph数据CPU2024-12-13

Golang函数性能优化之存储分配优化

为了提高 go 函数性能,存储分配优化至关重要。通过预分配缓冲区、使用切片和使用对象池等技术,可以有效减少内存分配带来的开销。以读取大文件为例,预分配文件行缓冲区可以显著优化性能,因为它减少了频繁的内存分配。Go 语言函数性能优化:存储分配
Golang函数性能优化之存储分配优化
2024-04-16

Golang函数性能优化之内存对齐优化

内存对齐优化通过将数据对齐到特定地址来提高程序性能。它减少缓存未命中、优化 simd 指令,具体步骤如下:使用 alignof 函数获取类型的最小对齐值。使用 unsafe.pointer 类型分配对齐的内存。将数据结构强制转换为对齐类型。
Golang函数性能优化之内存对齐优化
2024-04-17

SQL性能优化策略之索引优化方法

SQL优化是优化工作中经常会涉及的问题,由于早期的开发人员往往只关注于SQL功能的实现,而忽略了性能。特别是复杂的SQL,上线之后很少修改,一旦出现问题,即使是当初的开发人员自己也很难理清其中的业务逻辑,需要花费大量的时间去理解代码之间的
SQL索引性能2024-12-03

热门标签

编程热搜

编程资源站

目录