1. 前言
- 在浏览器地址中从输入url地址到页面显示出来,这个过程发生了什么?
- 浏览器拿到页面资源后是怎么加载的?
- 浏览器又是怎么渲染页面的?
- ...
2. 从资源加载到浏览器解析的过程
当我们在浏览器输入一个url后,浏览器会进行一系列的操作:
- 浏览器查看缓存,如果资源存在缓存,直接加载。如果资源未缓存,则发起新的请求
- 在发起新的请求前,会进行DNS解析(也就是把输入的url解析成真实的IP地址)
- 创建TCP连接(三次握手的过程)
- TCP连接创建成功后,发起http请求
- 服务器处理请求并返回对应的资源文件
- 浏览器解析渲染页面
3. 浏览器加载资源
客户端从服务器获取到需要渲染页面的源代码后,会开启一个GUI渲染线程,自上而下的解析代码,最后绘制出对应的页面。
这个自上而下的解析代码的过程是同步的,但是有一些操作也是异步的
- 关于css资源的加载
- 遇到 style 标签:这是同步的,直接交给GUI渲染线程解析
- 遇到 link 外链样式:这是异步的,会开启一个http网络请求线程去请求资源文件,同时GUI渲染线程继续向下渲染。当GUI渲染线程同步操作都处理完成后,再把请求回来的资源文件进行解析渲染
- 遇到 @import 导入样式:这是同步的,会开启一个http网络请求线程去请求资源文件,但是在资源文件没有请求回来之前,此时的GUI渲染线程是被阻塞的,不会继续向下解析和渲染
- 关于js资源的加载
- 默认都是同步的,必须基于http网络线程把js文件请求回来,并且交给 “S引擎(渲染)线程”解析完成后,GUI渲染线程才会继续向下渲染。所以才尽可能把js文件写在页面底部
- script的async属性:此时文件的加载是异步的,不会阻止GUI线程。但是一旦资源请求回来后,会中断GUI线程,先把请求回来的js文件进行解析渲染
- script的defer属性:此时文件的加载是异步的,不会阻止GUI线程。与async不同,defer不会中断GUI线程的渲染,而是在GUI渲染完成后,再把请求回来的js文件进行解析渲染
- 关于img或是音视频资源的加载
- 基于http网络线程把资源请求回来,不会阻塞GUI线程。是在GUI渲染完成后,再把请求回来资源进行渲染
4. 浏览器渲染机制
4.1 渲染引擎的一般渲染过程
- HTML解析器:解析HTML文本,浏览器会把HTML结构字符串解析转换DOM树形结构
- CSS解析器:渲染样式代码,生成CSSOM Tree
- Javascript引擎:等到Javascript 脚本文件加载后, 通过 DOM API 来操作 DOM Tree
4.2 页面渲染的过程
5. 重绘和回流
- 重绘:元素样式的改变(但宽高,大小,位置等不变)
- 如:color,background-color等
- 回流:元素的大小或位置发生变化(当页面布局和几何信息发生变化的时),触发重新布局,导致Render Tree重新计算布局和渲染
- 如:增删DOM节点,浏览器窗口尺寸发生变化,元素尺寸,内容发生变化等等
5.1 如何减少重绘和回流
- 样式集中修改:如dom.style.cssText = 'width: 100; height: 200px;'
- 减少直接操作 DOM,使用现代流行的框架等
6. 性能优化
基于DOM 和 CSSOM 结构构建顺序,以及文件加载的过程,可以对页面渲染做些优化,提升页面性能:
- 针对 DOM 的优化:
- 优化 DOM 结构,减少 DOM 的层级嵌套
- 不要使用非标准的标签等
- 针对 css 的优化:
- 尽可能不要使用 @import(阻塞GUI渲染)
- css 选择器链短一些
- link 引入css 放在head中
- link 标签的 rel属性 中的属性值设置为 preload 能够让你在你的HTML页面中可以指明哪些资源是在页面加载完成后即刻需要的,最优的配置加载顺序,提高渲染性能
- ...
- 其他资源的优化
- 对于 script 标签,尽可能放在页面底部(防止其阻塞GUI渲染),对于部分的 script 需要使用async 和 defer
- 对于 img ,使用懒加载
- 减少 DOM 回流和重绘
- ...
7. 参考文章
- 你不知道的浏览器页面渲染机制
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!