JS的加载和执行
从JS的加载和执行谈性能优化
---高性能JS读后感(第一章)
从脚本的"霸道"说起,随着浏览器的进步,js越来越听话了,所以,我们先说说以前的浏览器是怎么加载js的,以及js如何个霸道法.
1.阻塞的脚本
在以前,js很霸道.
问:当我们在网页中使用<script></script>时,到底发生了什么?
答:无论是内嵌的<script>标签代码还是用<script>引入文件,当浏览器解析到<script>元素时,浏览器就会去加载js内容,这时,页面的其他资源的加载和渲染都会停止,可以说<script>元素是老大,当他说话(加载)时,其他人都不敢说(其他资源都会停止加载和渲染),这就是我们常说的js会阻塞资源加载和页面渲染.这是<script>的霸道(特点).单加载就阻塞了,执行就更不用说了.
所以,我们一般把js放在页面的底部,</body>之前,这样当页面加载到底部的js时,页面的结构和渲染都完成了,这个时候你阻塞也不影响我页面的加载.
后来浏览器开始进步
当浏览器解析到<script>元素时,依旧会阻塞页面其他资源的加载(比如图片)和渲染(css的渲染),但是如果页面有多个<script>,就是说如果我们引入两份js文件,那么这两份js文件是可以并行加载的,不用像之前一样,得第一份加载完再去加载第二份.
浏览器继续进步
2.无阻塞的脚本
无阻塞脚本的秘诀在于,在页面加载完成后才加载js代码.就是说在window对象的load事件触发后再下载脚本.
无阻塞脚本之延迟的脚本(这里的延迟指的是延迟执行,而不是延迟加载)
在现在的主流浏览器,js的加载已经不会阻塞页面了,他能够与其他资源和平共处,就是说他越来越乖巧了,当他在加载时,他允许图片等其他资源的加载,当然执行的话还是会阻塞的.
如下图,js与图片并行加载.(主流浏览器)

js的加载说完了,我们说说js的执行.
问:js执行为什么会阻塞页面的渲染.
答:js在执行时,一般都会操作DOM,操作DOM就会影响到DOM树的渲染,所以js的执行肯定会阻塞渲染.
注意:js是单线程,但浏览器是多线程,js在执行时,DOM树在构建,同时渲染树也在渲染,这个时候如果js构建和浏览器即将渲染的是同一个节点怎么办?所以,为免冲突,js在执行时,停止渲染.
现在js的加载和执行略懂略懂,那么问题来了.
问:js放置的最优位置的底部,我现在有一份js必须在head,等页面结构加载完(window.onload)就马上执行,就是说我要先加载后执行,那么我该怎么办?
答:用defer,在<script>加上defer属性
<script type="text/javascript" src="jquery-1.8.3.min.js" defer></script>
defer的功能:指明本元素所含的脚本不会修改DOM,(即只加载不执行),因此代码能安全的延迟执行.阻塞的脚本变成延迟的脚本了.
问:我现在有一份js必须在head,想让它加载完马上执行怎么办?
答:用async,在<script>加上async属性
<script type="text/javascript" src="jquery-1.8.3.min.js" async></script>
async的功能:异步并行加载js,加载完之后立即执行.defer是加载后等页面加载后再执行,两者的区别是执行方式的不同.
问:我们什么时候用defer,什么时候用async?
答:
1.当js并不需要立马加载的时候,我们把js放在页面底部就可以了,不需要用到这两个属性.
2.当某段js需要立马加载时,判断其是否需要立即执行,需要就用async,不需要立即执行就用defer.
当然,这里需要强调下,js立即执行,这个时候是会阻塞页面的渲染的.
也需要考虑到,这两个属性的浏览器支持情况,在不支持这两个属性的浏览器上,其实他们是会阻塞页面的渲染的(不支持的情况下,加载js不阻塞,但是加载完后的js会去立马执行,这个时候就会阻塞了).
3.DOM树创建完并不意味着页面资源加载完,所以在DOM树创建完,触发window.onload的时候,中间还是有一点时间的,这个时间就是加载其他资源的时间.(比如说加载js)
4.其实,在不考虑多个js文件有多个http请求数的情况下,当你把js放在页面底部的时候,其实已经是一种无阻塞的脚本了.
总结:(摘自书中内容)
减少js对性能的影响:
1.</body>闭合标签之前,将所有的<script>标签放到页面底部.这能确保在脚本执行前页面已经完成了渲染.
2.合并脚本.页面的中的<script>标签越少,加载也就越快,响应也更迅速.无论外链文件还是内嵌脚本都是如此.
3.有多种无阻塞下载js的方法:(可自行搜索用法)
- 使用<script>标签的defer属性
- 使用动态创建的<script>元素来下载并执行代码
- 使用XHR对象下载js代码并注入页面中
个人觉得,在目前,js模块加载器,js模块打包器都有,解决文件的依赖关系并且打成一个包是比较容易的,再把打成的包放到</body>,可以减少http请求,也不会阻塞页面加载和渲染(可以说这是一个无阻塞的脚本),虽然这个文件可能很大,但相对于减少了http请求数来说,还是利大于弊的,因为我们一个页面不打包可能有很多个js,这样请求数会很多.
当然对于一些库,我们可以单独引入,这样可以缓存起来,缓存起来的文件加载就更快了.
有错请指出,欢迎交流~
JS的加载和执行的更多相关文章
- JS 动态加载脚本 执行回调
JS 动态加载脚本 执行回调 关于在javascript里面加载其它的js文件的问题可能很多人都遇到过,但很多朋友可能并不知道怎么判断我们要加载的js文件是否加载完成,如果没有加载完成我们就调用文件 ...
- 性能优化-css,js的加载与执行
前端性能优化 css,js的加载与执行 javascript是单线程的 一个网站在浏览器是如何进行渲染的呢? html页面加载渲染的过程 html渲染过程的一些特点 顺序执行,并发加载 词法分析 并发 ...
- JS 动态加载脚本 执行回调_转
关于在javascript里面加载其它的js文件的问题可能很多人都遇到过,但很多朋友可能并不知道怎么判断我们要加载的js文件是否加载完成,如果没有加载完成我们就调用文件里面的函数是不会成功的.本文讲解 ...
- JS脚本加载与执行对性能的影响
高性能JavaScript-JS脚本加载与执行对性能的影响 在web产品优化准则中,很重要的一条是针对js脚本的加载和执行方式的优化.本篇文章简单描述一下其中的优化准则. 1. 脚本加载优化 1.1 ...
- 前端性能优化 css和js的加载与执行
一个网站在浏览器端是如何进行渲染的? html本身首先会被渲染成 DOM 树,实际上 html 是最先通过网址请求过来的,请求过来之后,html 本身会由一个字节流转化成一个字符流,浏览器端拿的就是字 ...
- 高性能javascript学习笔记系列(1) -js的加载和执行
这篇笔记的内容主要涉及js的脚本位置,如何加载js脚本和脚本文件执行的问题,按照自己的理解结合高性能JavaScript整理出来的 javascript是解释性代码,解释性代码需要经历转化成计算机指令 ...
- js并行加载,顺序执行
js并行加载,顺序执行 <script>运行脚本或加载外部文件时,会阻塞页面渲染,阻塞其他资源的加载.如果页面中需要加载多个js文件,在古老浏览器中性能会比较糟糕. 因此有了最原始的优化原 ...
- jquery js 动态加载 js文件
jquery方法 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://ww ...
- 使用getScript()方法异步加载并执行js文件
使用getScript()方法异步加载并执行js文件 使用getScript()方法异步请求并执行服务器中的JavaScript格式的文件,它的调用格式如下所示: jQuery.getScript(u ...
随机推荐
- 一张图理解"Figure", "Axes", "Axis"
Figure is the object with the highest level in the hierarchy. It corresponds to the entire graphical ...
- JAVA学习笔记--方法中的参数调用是引用调用or值调用
文献来源:<JAVA核心技术卷Ⅰ>,第4章第5节 (没有相关书籍的可看传送门) ps:测试demo因为偷懒,用的是String对象 结论:Java使用的是对象的值引用.即将任何对象所在内存 ...
- mobx学习笔记03——mobx基础语法(decorator修饰器)
在声明阶段实现类与类成员注解的一种语法. function log(target){ const desc = Object.getOwnPropertyDescriotors(target.prot ...
- sonarqube6.7.1使用
1.插件安装 方法1.登入sonarqube-web安装 admin/admin 配置--应用市场--全部 英文片:administration--configuration--marketplace ...
- 华为交换机telnet配置
1.在路由器上和交换机相连的借口上配置一个IP地址:比如192.168.1.1 24 2.在交换机上配置如下:<switch>system-view[switch]vlan 10[swit ...
- Linux后台执行脚本 &与nohup
Linux后台执行脚本的方式: 0.脚本代码 [root@VM_1_3_centos apps]# cat test.php <?php sleep(5); echo "hello w ...
- webpack cssloader报错问题
运行webpack4.+的时候出现 ERROR in ./src/css/index.cssModule build failed (from ./node_modules/css-loader/di ...
- sdb报告-10 错误问题定位
# sdb报告-10 错误问题定位在sdb 的集群环境中,如果面对的是一个高并发的操作场景,有时候会莫名其妙地报告 -10 错误. 在 sdb 的错误列表中,-10 错误代表:系统错误. 这是一个笼统 ...
- linux超级块和inode 详解 和 df 、du 命令详解与环境变量
一.inode块,Unix文件的核心. 首先需要明白的是,在Unix操作系统中的任何资源都被当作文件来管理.如目录.光驱.终端设备等等,都被当作是一种文件.从这方面来说,Unix操作系统中的所有的目录 ...
- SetWindowsHookEx 其他进程的 记录
SetWindowsHookEx( WH_GETMESSAGE,CallWndProc, HInstance, h2); WH_GETMESSAGE 这个类型 hook 其他窗体的 线程是正常的 ...