一个网站在浏览器端是如何进行渲染的?
html本身首先会被渲染成 DOM 树,实际上 html 是最先通过网址请求过来的,请求过来之后,html 本身会由一个字节流转化成一个字符流,浏览器端拿的就是字符流,然后通过词法分析之后,将相应的语法分析成相应的 token ,比如说 header token, 转化不同的 token tag ,然后通过 token 类型 append 到 dom 树。
遇到 link token tag,然后去请求 css ,请求过来之后再去对 css 进行解析,生成 CSSOM ,然后和 DOM 树进行结合形成 Render Tree 这样的渲染树。然后再进行布局和渲染。
遇到 script tag ,然后去请求 JS 相关的 web 资源,请求回来的 js 会交给浏览器的 v8 引擎进行解析,
HTML渲染过程的一些特点
1、顺序执行
因为他是使用词法分析的能力,从上到下依次分析整个html,tag 相应的情况,所以第一个特点是顺序执行。词法分析是对 html 这个文档解析的一个方式,对 tag 依次从上到下解析,这个从上到下决定了很多阻塞的情况。
2、并发加载
我们的html中可能会引入很多的 css,js 的 web 资源,这些 web 资源在浏览器端是并发加载的,这里需要优化的一点就是这个并发加载过程的并发度是受我们浏览器域名限制的。所以会设置 3 到 4 个 CDN 域名,防止单个域名的限制
3、是否阻塞
首先 css 的加载是否会阻塞 js 的加载,js 的加载是否阻塞 js 的执行, css 的加载是否会阻塞页面的渲染。
css 在 head 中通过 link 方式引入的话,他会阻塞页面的渲染。就是要等这个 css 加载完之后才会进行渲染。所以这个时候分析完之后是带样式的,所以推荐是放在 head 里面请求 css
css 通过 link 的方式,css会阻塞页面的渲染,css 会阻塞 js 的执行,因为 js 会影响样式,js 的执行会依赖一些 css 的属性,如果 css 没有加载完,可能会有问题。但 css 不阻塞外部脚本的加载,原因是 webkit 实际上有一个预先扫描器,他是可以预先扫描后面的词语的,所以他不会阻止加载的过程,但会阻止执行的过程。
直接引入的js会阻塞页面的渲染,因为 js 的执行会影响 dom 节点的修改,所以会阻塞后面的节点创建。这也是符合逻辑的。
4、依赖关系
html渲染过程中,是否有要遵循的依赖关系,如何保证依赖关系正确的情况下提高效率。比如有些情况 html 已经出来了,但是样式没有,然后突然闪了一下,样式出来了。这种情况就是没有遵循依赖关系,一般 css 放在 head tag 里面,页面就会等 css 加载好,生成 cssom ,再进行渲染,这个时候就不会出现 css 闪动的问题。有时候 js 会加 async,这个时候就是放弃的 js 的依赖关系,这时候需要关注js的依赖关系
页面渲染依赖于 css 的加载
js 的执行顺序的依赖关系
js 逻辑对于 dom 节点的依赖关系,有些 js 需要去获取 dom 节点
5、引入方式
比如是 link 引入,还是 import 引入,两者有什么区别。对于js,比如 tag,比如动态引入。
直接引入,会阻塞页面的渲染
defer,不会阻塞页面的渲染,在 defer 的时候,所有 dom 树都已经构建完成了。defer 是顺序执行
async,不会阻塞页面的渲染,跟 defer 不同的是,不保证执行顺序,哪个先从服务端回来,哪个先执行
异步动态引入js,需要的时候,动态引入新的js文件,spa 单页页面中非常广泛
根据这些特点,我们找到可以优化的点
1、css 样式表置顶
2、用 link 代替 import,指的是 css 里面的 import,这个 import 是写在最底层,这样引入 css 的时候是不好的
3、js 脚本置底,并发请求的时候不区分 css 和 js 的,js 写在顶部会影响 css 的加载,在渲染的时候,css 是由于 js的,所以跟页面渲染无关的 js 放于页面底部
4、合理使用 js 的异步加载能力,优化js的加载执行
实战
1、加载并发数是有上限的,js和css混合放置,会导致css的延迟,会导致页面闪动,所以js要置底
2、css放在header中,阻塞页面的渲染,css加载完,再加载dom,放置页面样式跳变,从而保证渲染一步到位
3、css不会阻塞后面js并发加载,但会阻塞js的执行。如果js放在header中,会阻塞html的渲染。
4、把js都放在header, 分别放 async,defer。
async 不阻塞页面渲染,不保证执行顺序,谁先回来谁执行,不保证dom书构造完成之后再执行。
defer 不阻塞页面渲染, 保证执行顺序,保证dom树构造完成之后再执行。
5、@import link 实操
@import 有两个重大缺陷,第一点它不支持并发执行。他要 import 之后,再去 import 第二个,他不支持并发。
第二点,他需要整个页面全部加载完之后,才去执行 import 里面的代码。
但是,,,可能这两个重大缺陷曾经存在过,但是现在这两个问题已经没有了,跟 link 的效果是一模一样的。他更适合用于 css 模块化。但是在不同 css 文件中 @import 的是不支持并发的,只有该 css 文件加载完之后才去加载 @import 里面的 css

前端性能优化 css和js的加载与执行的更多相关文章

  1. 性能优化-css,js的加载与执行

    前端性能优化 css,js的加载与执行 javascript是单线程的 一个网站在浏览器是如何进行渲染的呢? html页面加载渲染的过程 html渲染过程的一些特点 顺序执行,并发加载 词法分析 并发 ...

  2. 前端性能优化:细说JavaScript的加载与执行

    本文主要是从性能优化的角度来探讨JavaScript在加载与执行过程中的优化思路与实践方法,既是细说,文中在涉及原理性的地方,不免会多说几句,还望各位读者保持耐心,仔细理解,请相信,您的耐心付出一定会 ...

  3. Web前端性能优化总结——如何提高网页加载速度

    一.提高网页加载速度的必要性 国际知名的一组来自Jupiter Research的数据显示:购物者在访问网站过程中的不满会导致销售损失和品牌受损,其中 77%的人将不再访问网站 ,62%的人不再从该网 ...

  4. JS的加载和执行

    从JS的加载和执行谈性能优化 ---高性能JS读后感(第一章) 从脚本的"霸道"说起,随着浏览器的进步,js越来越听话了,所以,我们先说说以前的浏览器是怎么加载js的,以及js如何 ...

  5. JS 动态加载脚本 执行回调

    JS 动态加载脚本  执行回调 关于在javascript里面加载其它的js文件的问题可能很多人都遇到过,但很多朋友可能并不知道怎么判断我们要加载的js文件是否加载完成,如果没有加载完成我们就调用文件 ...

  6. 前端设计中关于外部js文件加载的速度优化

    在一般情况下,许多人都是将<script>写在了<head>标签中,而许多浏览器都是使用单一的线程来加载js文件的,从上往下,从左往右. 若是加载过程出错,那么网页就会阻塞,就 ...

  7. JS脚本加载与执行对性能的影响

    高性能JavaScript-JS脚本加载与执行对性能的影响 在web产品优化准则中,很重要的一条是针对js脚本的加载和执行方式的优化.本篇文章简单描述一下其中的优化准则. 1. 脚本加载优化 1.1 ...

  8. 页面加载异常 清除浏览器静态文件 js css 缓存 js动态加载js css文件,可以配置文件后辍,防止浏览器缓存

    js清除浏览器缓存的几种方法 - 兔老霸夏 - 博客园 https://www.cnblogs.com/Mr-Rocker/p/6031096.html js清除浏览器缓存的几种方法   一.CSS和 ...

  9. JS 动态加载脚本 执行回调_转

    关于在javascript里面加载其它的js文件的问题可能很多人都遇到过,但很多朋友可能并不知道怎么判断我们要加载的js文件是否加载完成,如果没有加载完成我们就调用文件里面的函数是不会成功的.本文讲解 ...

随机推荐

  1. 4.Vue双向绑定

    1.什么是双向数据绑定 Vue.js 是一个 MVVM 框架,即数据双向绑定,即当数据发生变化的时候,视图也就发生变化,当视图发生变化的时候,数据也会跟着同步变化.这也算是 Vue.js 的精髓之处了 ...

  2. [Taro] 解决 使用 Taro UI 小程序下 Iconfont 图标 不显示问题

    Taro UI 配置 第三方 的 文档 配置即可解决 https://taro-ui.jd.com/#/docs/icon 解决问题: 之前 只有在H5下 才显示 Iconfont 图标 后来按照此文 ...

  3. vue_02day

    目录 vue_02 表单指令: 条件指令: 循环指令: 前端数据库: 分隔符: 过滤器: 计算属性: 监听属性: vue编译不生效,闪烁 冒泡排序: vue_02 表单指令: <form act ...

  4. Word中怎么快速选中并组合多个文本框图形

    目的: 选中全部的文本框或者图形.图像,然后组合到一起 步骤: 点击开始(Home),点击右侧 选择--选择对象 (select -- select objects) -- 鼠标拖放框选图形 -- 右 ...

  5. 调用其他python脚本文件里面的类和方法

    问题描述: 自己编写了若干个Python脚本. 在testC.py里面需要调用testA.py和testB.py里面的若干类和方法.要怎么办? 需要都打包.安装,再去调用吗? 其实不必那么麻烦. 这里 ...

  6. 使用 Valgrind 检测 C++ 内存泄漏

    Valgrind 的介绍 Valgrind 可以用来检测程序是否有非法使用内存的问题,例如访问未初始化的内存.访问数组时越界.忘记释放动态内存等问题.在 Linux 可以使用下面的命令安装 Valgr ...

  7. 获取豆瓣电影数据(R与API获取网页数据)

    一般成熟的网站都会有反爬虫策略,例如限制访问次数,限制访问 IP,动态显示数据等.爬虫和反爬虫就是一直相爱相杀地互相钳制.如果要通过爬虫来获取某些大型网站的数据,那是一件很费时费力的活.小白总遭遇过在 ...

  8. Java 8创建Stream流的5种方法

    不知不觉间,Java已经发展到13了,来不及感慨时间过得真的太快了,来不及学习日新月异的技术更新,目前大多数公司还是使用的JDK8版本,一方面是版本的稳定,另一方面是熟悉,所以很多公司都觉得不升级也挺 ...

  9. PYTHON的ASCII码转换

    首先,我们要知道ASCII的ord 这个变值,附上代码: c=input("请输入一个字符:") print (c+"的ASCII码为 ".ord(c)) #用 ...

  10. winfrom判断程序是否运行,并给提示

    在Program.cs文件中修改为: private static System.Threading.Mutex mutex; /// <summary> /// 应用程序的主入口点. / ...