js加载和长任务

news2024/10/7 16:15:25

js加载和长任务

本文将讲解以下浏览器如何加载js,并介绍一些可以提高网页加载速度的方法。

Evaluate Script

如果我们在devtoolsperformance中分析过网站的加载性能,可能会看到一个很长的任务,叫做Evaluate Script.

在这里插入图片描述

在这种情况下,该工作足以导致长时间任务,从而阻止主线程承担其他工作(包括驱动用户交互的任务).

Evaluate Script是在浏览器中执行 JavaScript 的必要部分,因为 JavaScript在执行前即时编译。当评估脚本时,首先会分析它是否有错误。如果解析器没有发现错误,则脚本将被编译为字节码,然后可以继续执行。

因为用户可能会在页面最初显示后不久就尝试与页面进行交互=,这样就会导致Evaluate Script出现问题(页面已呈现并不意味着页面已完成加载。由于页面正忙于评估脚本,因此加载期间发生的交互可能会延迟)。

总阻塞时间 (TBT)是一个可以让我们深入了解页面加载期间是否发生过多脚本评估的指标,因为它是一种负载响应指标。

script和评估它们的任务之间的关系

负责脚本评估的任务如何启动取决于网站正在加载的脚本是否是通过常规<script>元素加载的,或者脚本是否是使用type=module. 由于浏览器倾向于以不同的方式处理事物,因此主要浏览器引擎如何处理脚本评估将涉及它们之间的脚本评估行为的不同之处。

使用script元素

分派评估脚本的任务数量通常与页面上的<script>元素数量有直接关系。每个<script>元素都会启动一个任务来评估所请求的脚本,以便可以对其进行解析、编译和执行。

我们可以通过避免加载大块 JavaScript 来分解脚本评估工作,并使用其他<script>元素加载更多单独的、更小的脚本。

由于设备的功能各不相同,因此很难为单个脚本的大小定义一个设定的限制。为了在压缩效率、下载时间和脚本评估时间之间取得良好的平衡,每个脚本的大小限制为 100 KB 是一个不错的指标。

因此我们在页面加载期间应该加载尽可能少的 JavaScript,通过拆分脚本可确保我们拥有大量不会阻塞主线程的较小任务,而不是一个可能阻塞主线程的大型任务。

在这里插入图片描述

由于页面 HTML 中存在多个<script>元素,因此产生了多个任务来评估脚本。这比向用户单独发送一个体积非常大的js包更好,因为这样更有可能阻塞主线程。

在script元素添加type=module属性

通过在script元素上添加type=module属性可以在浏览器中本地加载 ES 模块。这种脚本加载方法具有一些开发人员体验优势,例如在生产环境中不需要转换代码就可以使用。但是,以这种方式加载脚本会根据浏览器的不同而具有不同的任务。

基于 Chromium 的浏览器

Chrome 等浏览器(或衍生自 Chrome 的浏览器)中,使用type=module属性加载 ES 模块会产生与不使用时看到不同类型的任务。例如,每个将执行的模块脚本(携带type=module)的任务,都呗标记为Compile module tasks

在这里插入图片描述

每个模块脚本都会生成一个编译模块任务,在评估之前编译其内容。

模块编译完成后,随后在其中运行的任何代码都标记为Evaluate module tasks

在这里插入图片描述

从上图可以看见使用type=module需要承担一些不可避免的成本。虽然我们应该努力提供尽可能少的 JavaScript,但使用 ES 模块(无论浏览器如何)都可以提供以下好处:

  • 所有模块代码都会在严格模式下自动运行,这允许 JavaScript 引擎进行潜在的优化,而这些优化在非严格上下文中是无法实现的。
  • 使用type=module属性在加载时会默认当作为defer。可以在ES加载的脚本上使用设置async来更改此行为。

基于Safari 和 Firefox 的浏览器

当在 SafariFirefox 中加载type=module模块时,每个模块都会在单独的任务中进行评估。这意味着理论上我们可以将仅包含静态import语句的单个顶级模块加载到其他模块中,并且加载的每个模块都会产生单独的网络请求和任务来进行评估。

使用动态import()

动态import()是加载脚本的另一种方法。import与需要位于 ES 模块顶部的静态语句不同,动态import()调用可以出现在脚本中的任何位置,以按需加载 JavaScript 块。这种技术称为代码分割。

使用动态import()有两个好处:

  1. 推迟加载的模块(设置defer)通过减少当前加载的 JavaScript 量来减少启动期间的主线程争用。这释放了主线程,因此它可以更好地响应用户交互。
  2. 当进行动态import()调用时,每次调用都会有效地将每个模块的编译和评估分离到自己的任务中。当然,import()加载非常大的模块的动态将启动相当大的脚本评估任务,并且如果交互与动态调用同时发生,import()则可能会干扰主线程响应用户输入的能力。因此,加载尽可能少的 JavaScript 还是非常重要的。

动态import()调用在所有主要浏览器引擎中的行为都类似:结果的脚本评估任务将与动态导入的模块数量相同。

在web worker中加载js

Web Worker是一个特殊的 JavaScript 用例。Web Worker 在主线程上注册,然后 Worker 中的代码会在自己的线程上运行。这可以减少主线程拥塞,并有助于保持主线程对用户交互的响应更加灵敏。

除了减少主线程工作之外,Web Worker本身还可以importScripts或者静态import来加载外部js,这样通过 Web Worker 请求的任何脚本都会在主线程之外进行评估。

总结

虽然将脚本分解为单独的较小文件有助于限制长时间任务,但是在决定如何分解脚本时也需要考虑以下几点:

压缩效率

压缩是分解脚本的一个因素。当脚本较小时,压缩效率会有所降低。较大的脚本将从压缩中受益更多。虽然提高压缩效率有助于尽可能缩短脚本的加载时间,但确保将脚本分解为足够小的块以在启动期间促进更好的交互性也是需要权衡决定的。

打包工具是一个非常理想的工具,可以用来管理我们的js打包结果:

  • 比如说webpack,可以通过SplitChunksPlugin插件来管理打包后的js的大小。
  • 对于Rollupesbuild而言,可以通过在代码中使用动态import()来管理脚本文件大小。这些打包工具会自动将动态import()的资源分解到其他的文件中,从而避免生成较大的文件。

缓存

缓存对于一些需要重复访问时页面加载的速度起着重要作用。当我们的js包非常大时,每次更新,之前的一些打包文件都会失效(多个文件都打包在一个js文件里,当修改里边的一些代码时,整个打包文件都是更新过的),必须要重新下载。

通过分解脚本,我们不仅可以将脚本评估工作分解为较小的任务,还可以让用户尽量从浏览器的缓存中获取之前的页面内容,而不是需要重新下载文件。这意味着整体页面加载速度更快。

为了使缓存既高效又可以避免从缓存中提供过时的资源,可以在打包出的文件设置哈希值作为文件名。

嵌套模块和加载性能

我们要是在生产环境中使用 ES 模块并使用type=module属性加载它们,则需要了解模块嵌套如何影响启动时间。模块嵌套是指一个 ES 模块静态导入另一个 ES 模块,而另一个 ES 模块又静态导入另一个 ES 模块:

// a.js
import {b} from './b.js';

// b.js
import {c} from './c.js';

如果这些模块没有被打包在一起,那么就会导致生成一个请求链:当一个script元素中包含了a.js的代码的时候,就会发送一个请求去请求b.js文件,然后b.js文件又会发送一个请求去请求c.js文件。这种情况下除了修改代码将这些打包在一起外,还可以通过 modulepreload方式提前预加载 ES 模块以避免网络请求链(仅支持基于 Chromium 的浏览器).

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/800198.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IDS(Intrusion Detection Systems)

计算机安全的三大中心目标是&#xff1a;保密性(Conf idential ity)、完整性(Integrity)、可用性(Availability)。 身份认证与识别、访问控制机制、加密技术、防火墙技术等技术共同特征就是集中在系统的自身加固和 防护上&#xff0c;属于静态的安全防御技术&#xff0c;缺乏主…

【微服务架构设计】微服务不是魔术:处理超时

微服务很重要。它们可以为我们的架构和团队带来一些相当大的胜利&#xff0c;但微服务也有很多成本。随着微服务、无服务器和其他分布式系统架构在行业中变得更加普遍&#xff0c;我们将它们的问题和解决它们的策略内化是至关重要的。在本文中&#xff0c;我们将研究网络边界可…

上门居家养老小程序社区养老小程序开发方案详解

居家养老管理社区养老小程序有哪些功能呢&#xff1f; 1.选择养老服务类型 医疗护理&#xff0c;家政服务预约&#xff0c;上门助浴、上门做饭&#xff0c;上门助餐&#xff0c;生活照护&#xff0c;康复理疗、精神慰藉、委托代办等。各项服务的详情介绍。 2.选择预约时间 选择…

Linux_NVR_SDK 编译应用 -基于iTOP-RK3568开发板

在源码 build/app 目录下有发布版本的 RKMPI 以及编译配置&#xff0c;目前的编译方式只支持 Cmake 脚本。如果要编译其他应用&#xff0c;可以参考 build/app/build/build.sh 脚本配置编译工具链。 以编译 RKMPI 应用程序为例&#xff0c;进行示范&#xff1a; 1. 使能 sdk…

BIM与GIS融合:公路设计施工信息化的创新解决方案

随着信息技术的不断发展和应用&#xff0c;建筑行业也迎来了数字化转型。BIM&#xff08;建筑信息模型&#xff09;和GIS&#xff08;地理信息系统&#xff09;作为建筑行业中的重要技术&#xff0c;它们的融合对于实现公路施工信息化具有重要意义。Bim技术可以提供精细的建筑信…

(无人机方向)ros小白之键盘控制无人机(终端方式)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一&#xff1a;配置pycharm的ros开发环境二&#xff1a;核心代码讲解三 效果演示XTDrone 四 完整代码 前言 ubuntu 18.04 pycharm ros melodic 做一个在终端中…

Android 截图功能实现

Android 截图功能实现 简介效果图功能实现1. 截取当前可见范围屏幕2. 截取当前可见范围屏幕&#xff08;不包含状态栏&#xff09;3. 截取某个控件4. 截取ScrollView5. 长截图6. 截屏动画效果7. 显示截屏结果&#xff0c;自动消失6. 完整代码 简介 在Android应用中开发截图功能…

Kibana+Prometheus+node_exporter 监控告警部署

下载好三个软件包 一、prometheus安装部署 1、解压 linxxubuntu:~/module$ tar -xvf prometheus-2.45.0-rc.0.linux-amd64.tar.gz 2、修改配置文件的IP地址 # my global config global:scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is ever…

xshell连接Windows中通过wsl安装的linux子系统-Ubuntu 22.04

xshell连接Windows中通过wsl安装的linux子系统-Ubuntu 22.04 一、安装linux子系统 1.1、 启动或关闭Windows功能-适用于Linux的Windows子系统 1.2 WSL 官方文档 使用 WSL 在 Windows 上安装 Linux //1-安装 WSL 命令 wsl --install//2-检查正在运行的 WSL 版本&#xff1a;…

LeetCode221.Maximal-Square<最大正方形>

题目&#xff1a; 思路&#xff1a; 这题是动态规划&#xff0c;但是不会写。想着判断dp的 <上&#xff0c;左&#xff0c;左上> 去了。发现只能这样最大只能判断面积为4的正方形因为只会判断另外三个方格。而要想判断更大的正方形那就需要递归操作了。那肯定会超时了。…

乌班图安装MySQL5.7时的故障求解

wget https://dev.mysql.com/get/mysql-apt-config_0.8.12-1_all.deb dpkg -i mysql-apt-config_0.8.12-1_all.deb apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 467B942D3A79BD29 apt update

微信小程序云开发快速入门

什么是云开发&#xff1f; 云开发是可以帮助我们快速成为全栈的一种后端云服务&#xff0c;采用的是Serverless的架构。开发者无须搭建服务器&#xff0c;可直接使用其中的云数据库、云存储、云函数等云服务基础功能。 那么这个时候你可能会想&#xff0c;这和现在的传统开发…

Educational Codeforces Round 152 (Rated for Div. 2) D题 1849D Array Painting

传送门 https://codeforces.com/contest/1849/problem/D D. Array Painting 题意 题解 分类讨论 这题的精髓在于欠债 用一个a0表示当前有没有负债 当前欠债最多为1 首先我们讨论, 在不欠债的情况下遇到0是怎么模拟的: 前面有能够产生贡献的12连通块 例如: 12110 很明显答案…

vue element ui el-tree 通过子节点反向递归查找父节点

今天做了一个项目采用的是element tree组件&#xff0c;要求子父节点不强关联&#xff0c;但是当我点击子节点时&#xff0c;会反向的选择所有的父节点&#xff0c;如下图&#xff1a; 当我点击电话时&#xff0c;往上一层的“电话”和“我的”均为父级以上的节点&#xff0c;全…

Practice1|1207. 独一无二的出现次数、1365. 有多少小于当前数字的数字、941. 有效的山脉数组

1207. 独一无二的出现次数 1.题目&#xff1a; 给你一个整数数组 arr&#xff0c;请你帮忙统计数组中每个数的出现次数。 如果每个数的出现次数都是独一无二的&#xff0c;就返回 true&#xff1b;否则返回 false。 示例 1&#xff1a; 输入&#xff1a;arr [1,2,2,1,1,3…

安卓的播放器对比与选型(vlc,EXOplayer,Ijkplayer,GSYVideoPlayer)详细过程

安卓的播放器对比与选型&#xff08;vlc&#xff0c;EXOplayer&#xff0c;Ijkplayer&#xff0c;GSYVideoPlayer&#xff09;&#x1f4fa;详细过程 前言一、vlc二、EXOplayer三、Ijkplayer四、GSYVideoPlayer&#x1f525;&#x1f525;&#x1f525;五、其他的开源播放器jia…

婚庆服务小程序app开发方案详解

开发一款婚庆行业服务小程序有哪些功能呢&#xff1f; 1、选择分类 选择婚庆、婚车、婚宴、司仪、彩妆、婚庆用品、跟拍、摄影等&#xff0c;筛选出对应的商家 2、选择商家 选择分类后&#xff0c;可以选择商家&#xff0c;查看各个商家的详细介绍情况。 3、选择服务套餐 各…

Linux虚拟机(lvm)报Unmount and run xfs_repair

问题 linux系统没有正常关机&#xff0c;今天启动虚拟机无法进入系统&#xff0c;提示metadata corruption deleted at xxxx&#xff1b; Unmount and run xfs_repair 分析 主机异常掉电后里面的虚拟机无法启动&#xff0c;主要是损坏的分区 解决 看出来应该是dm-0分区损坏…

应急响应经典案例-FTP 暴力破解

应急响应经典案例-FTP 暴力破解 应急场景日志分析应急处理措施 应急场景 从昨天开始&#xff0c;网站响应速度变得缓慢&#xff0c;网站服务器登录上去非常卡&#xff0c;重启服务器就能保证一段时间的正常访问&#xff0c;网站响应状态时而飞快时而缓慢&#xff0c;多数时间是…

华为云安装MySQL后,本地工具连接MySQL失败

华为云安装MySQL后&#xff0c;本地连接失败 排查问题步骤&#xff1a; 在此之前需要在MySQL创建用户&#xff0c;并赋予权限。 1、能否ping通。 在本地命令行(Windows&#xff1a;winR)通过ping命令&#xff0c;ping服务器地址&#xff0c;看能否ping通。不能则需要检查本地…