【JavaScript性能优化】------理解Script标签的加载和执行
1.script标签是如何加载的?
当浏览器遇到一个 < script>标签时,浏览器会停下来,运行JavaScript代码,然后再继续解析、翻译页面。同样的事情发生在使用 src 属性加载 JavaScript 的过程中。浏览器必须首先下载外部文件的代码,需要占用一些时间,然后解析并运行此JavaScript代码。此过程中,页面解析和用户交互是被完全阻塞的。
2.script标签该放在何处?
HTML 4 文档指出,一个< script>标签可以放在 HTML 文档的或标签中,可以在其中多次出现。
这些代码存在性能问题:在< head>部分加载了三个 JavaScript 文件。因为每个< script>标签阻塞了页面的解析过程,直到它完整地下载并运行了外部 JavaScript 代码之后,页面 处理才能继续进行。用户必须忍受这种可以察觉的延迟。浏览器在遇到< body>标签之前,不会渲染页面的任何部分。用这种方法把脚本放在页面的顶端,将导致一个可以察觉的延迟,通常表现为:页面打开时,首先显示为一幅空白的页面,而此时用户即不能阅读,也不能与页面进行交互操作。
可以用一张图片来表示这些资源的加载过程,红色箭头表示js代码执行所用的时间
可以看到,第一个 JavaScript 文件开始下载,并阻塞了其他文件的下载过程。在 file1.js 下载完之后和 file2.js 开始下载之前有一个延时,这是 file1.js 完全运行所需的时间。每个文件必须等待前一个文件下载完成并运行完之后,才能开始自己的下载过程。当这些文件下载时,用户面
对一个空白的屏幕。
不过随着浏览器的发展,Internet Explorer 8, Firefox 3.5, Safari 4, 和 Chrome 2 允许并行下载 JavaScript 文件。这表明,当一个< script>标签正在下载外部资源时,不必阻塞其他< script>标签。不幸的是,JavaScript 的下载仍然要阻塞其他资源的下载过程,例如图片。即使脚本之间的下载过程互不阻塞,页面仍旧要等待所有 JavaScript代码下载并执行完成之后才能继续。所以,当浏览器通过允许并行下载提高性能之后,该问题并没有完全解决。脚本阻塞仍旧是一个问题。
因为脚本阻塞其他页面资源的下载过程,所以推荐的办法是:将所有< script>标签放在尽可能接近< body>标签底部的位置,尽量减少对整个页面下载的影响。
3.减少外部JavaScript文件的数量
由于每个 HTTP 请求都会产生额外的性能负担,下载一个 100KB 的文件比下载四个 25KB 的文件要快。当一个大型网站或网页应用需要多次请求 JavaScript 文件。可以将这些文件整合成一个文件,只需要一个< script>标签引用,就可以减少性能损失。
4.采用非阻塞脚本
保持 JavaScript 文件短小,并限制 HTTP 请求的数量,只是创建反应迅速的网页应用的第一步。一个应用程序所包含的功能越多,所需要的 JavaScript 代码就越大。尽管下载一个大 JavaScript 文件只产生一次 HTTP 请求,却会锁定浏览器一大段时间。为避开这种情况,需要向页面中逐步添加 JavaScript,某种程度上说不会阻塞浏览器。
非阻塞脚本的秘密在于,等页面完成加载之后,再加载 JavaScript 源码。这意味着在window 的 load 事件发出之后开始下载代码。有几种方法可以实现这种效果。
1. 使用defer(延时脚本)和async(异步脚本)
defer 属性指明元素中所包含的脚本不打算修改 DOM,因此代码可以稍后执行。注意:defer属性只对外部脚本有用
一个带有 defer 属性的< script>标签可以放置在文档的任何位置。对应的 JavaScript 文件将在< script>被解析时启动下载,但代码不会被执行,直到 DOM 加载完成。当一个 defer的 JavaScript 文件被下载时,它不会阻塞浏览器的其他处理过程,所以这些文件可以与页面的其他资源一起并行下载。
async用于异步加载脚本,与defer的区别是:async加载完成后自动执行,defer需要等到页面完成后(window.onload)才执行, 注意:多个标记为 async 的脚本并不保证按照指定它们的先后顺序执行(有可能是file3.js, file2.js, file4.js,取决于谁先返回),以为他们是异步加载的
2. 使用动态脚本元素
< script>元素与页面其他元素没有什么不同,所以他可以从文档中移动、删除,也可以被创建。一个新的< script>元素可以非常容易地通过标准 DOM 函数创建:
新的< script>元素加载 file1.js 源文件。此文件当元素添加到页面之后立刻开始下载。此技术的重点在于:无论在何处启动下载,文件的下载和运行都不会阻塞其他页面处理过程。甚至可以将这些代码放在< head>部分而不会对其余部分的页面代码造成影响。
【JavaScript性能优化】------理解Script标签的加载和执行的更多相关文章
- <script>标签的加载解析执行
转自原文 <script>标签的加载解析执行 看了很多网上的文章,都是大同小异.总结一下.内部原理还没有搞清楚,有机会再学习. 一.<script>标签的加载解析执行顺序 ht ...
- 性能优化-css,js的加载与执行
前端性能优化 css,js的加载与执行 javascript是单线程的 一个网站在浏览器是如何进行渲染的呢? html页面加载渲染的过程 html渲染过程的一些特点 顺序执行,并发加载 词法分析 并发 ...
- 前端性能优化 css和js的加载与执行
一个网站在浏览器端是如何进行渲染的? html本身首先会被渲染成 DOM 树,实际上 html 是最先通过网址请求过来的,请求过来之后,html 本身会由一个字节流转化成一个字符流,浏览器端拿的就是字 ...
- Web前端性能优化总结——如何提高网页加载速度
一.提高网页加载速度的必要性 国际知名的一组来自Jupiter Research的数据显示:购物者在访问网站过程中的不满会导致销售损失和品牌受损,其中 77%的人将不再访问网站 ,62%的人不再从该网 ...
- 动态script标签同步加载 ps:无打包编译,静态实现静态资源入口动态配置,无编译打包静态资源添加版本号
/**功能:创建动态标签加载css ,js文件,重点是js文件,利用onloading加递归实现动态标签的同步加载用法:在html文件body底部script内部声明并调用下列函数,obj中写要加载的 ...
- 大规模服务网格性能优化 | Aeraki xDS 按需加载
作者 钟华,腾讯云专家工程师,Istio project member.contributor,专注于容器和服务网格,在容器化和服务网格生产落地方面具有丰富经验,目前负责 Tencent Cloud ...
- js——<script>标签的加载顺序
用了很久的JavaScript,今天突然就碰见了将一个js文件放在<head></head>与<body></body>标签中,一个不可以执行,一个可以 ...
- Vue性能优化之组件按需加载(以及一些常见的性能优化方法)
关于Vue中的按需加载我就简单介绍一下:大概就是我们所有的东西都会在app.js里面,但是我们并不需要把所有的组件都一次性加载进来,我们可以在需要它的时候再将它加载进来,话不多说,开车! 1.webp ...
- web性能优化之js图片懒加载
html <div class="container"> <ul> <li> <div id="first" clas ...
随机推荐
- Numpy Ndarray对象1
标准安装的Python中用列表(list)保存一组值,可以用来当作数组使用,不过由于列表的元素可以是任何对象,因此列表中所保存的是对象的指 针.这样为了保存一个简单的[1,2,3],需要有3个指针和三 ...
- 55-python基础-python3-字典-删除键值对-del语句
字典-键值对的彻底删除 对于字典中不再需要的信息,可使用del 语句将相应的键—值对彻底删除. 使用del 语句时,必须指定字典名和要删除的键. 注意 删除的键—值对永远消失了.
- MVC路由学习:自定义路由参数(用户看不到参数名),重新定义路由规则
MVC路由:由于路由global中注册了,在程序第一次运行时,在MVC会自动生成路由,类似于字典的格式缓存下来,但路由生成的规则又是怎样的呢? 路由生成规则是: 1>更具你定义的的顺序查找路由规 ...
- 源码分析--HashSet(JDK1.8)
HashSet为无序不可重复集合.底层几乎全部借助HashMap实现,比较简单.本篇简要分析一下HashSet源码. 首先是成员变量: 1.真正保存数据的HashMap实例 private trans ...
- rabbitMQ实现推迟队列
一. 使用原生Api 1.RabbitMQ 相关 <dependency> <groupId>com.rabbitmq</groupId> <artifact ...
- Linux就该这么学08学习笔记
参考链接:https://www.linuxprobe.com/chapter-08.html 防火墙管理工具 众所周知,相较于企业内网,外部的公网环境更加恶劣,罪恶丛生.在公网与企业内网之间充当保护 ...
- mysql03--误删除了所有用户解决办法
误删除了所有用户解决办法 第一种方法(企业常用) 1.将数据库down掉 [root@db03 mysql]# /etc/init.d/mysqld stop Shutting down MySQL. ...
- CF960G Bandit Blues 第一类斯特林数+分治+FFT
题目传送门 https://codeforces.com/contest/960/problem/G 题解 首先整个排列的最大值一定是 \(A\) 个前缀最大值的最后一个,也是 \(B\) 个后缀最大 ...
- 前端每日实战:76# 视频演示如何用纯 CSS 创作一组单元素办公用品(内含2个视频)
效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/oMgmwB 可交互视频 此视频是可 ...
- struts2结果跳转和参数获取
一.结果跳转方式 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC ...