最初的模型:

  • 浏览器下载 html

  • 开始解析 html

    • 遇见外链资源, 保存起来, 并且继续解析

    • html 解析结束

    • 开始下载外链

      • 下载结束

        • 开始处理

          • css 处理

          • js 处理

            • 处理完毕, 开始渲染

            • 用户看到界面

这个模型的基础是: 浏览器是单线程的.

但是实际上: 浏览器不是单线程, 是多个线程.
浏览器有如下几个线程:
1 javascript引擎线程
2 界面渲染线程
3 浏览器事件触发线程
4 http请求线程

也就是说: 下载和解析是可以同步的, 遇见外链就开始下载.

更改之后的模型

  • 浏览器下载 html

  • 开始解析 html

    • 遇见外链资源, 开始下载, 并且继续解析

    • html 解析结束

    • 下载结束

      • 开始处理

        • css 处理

        • js 处理

          • 处理完毕, 开始渲染

          • 用户看到界面

这个模型的基础是:
资源下载和 html 解析是同步的, 所有的资源下载结束, 才开始进行下一步:渲染.
实际情景是:
资源大致可以分成
css
js
imgs
others

imgs以及 others 这种, 如果一个资源过大, 比如说一个媒体文件100M, 非要等到用户下载结束
才开始下一步, 这显然是不合理的.
而 css 和 js 是可以对页面产生修改和效果的, 所以必须要等待它们的参与才能进行下一步操作,
比如说 css,js 都没有下载解析执行结束, 就开始下一步渲染, 最终渲染的结果是一个没有样式的
页面.

看浏览器是不是这么想的?
实验:
在demo 中加一个 p 标签, 在底部加一个 css 外链
如果 css 都没有加载完毕, p 标签就显示出来了, 说明浏览器就没有等 css 文件
也就是说: html 解析结束之后, 什么都不管, 就开始下一步渲染了.

demo:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>demo</title>
</head>
<body><p>hello world</p><link rel="stylesheet" href="https://www.google.com.hk/test.css">
</body>
</html>

结果:
css 没有加载之前, 页面空白, 说明 html 解析结束之后, 会等到css加载出来再开始渲染.

更一步的实验:
资源变成 js, 页面先渲染出来, js 还在加载.
资源变成 img, 页面会先渲染出来, img 还在加载.

结论:
**html 解析结束之后, 会先等到 css 下载和解析结束之后(通过 link 标签知道是 css 文件)
再开始下一步, 并不会等所有的非 js 资源.**

所以模型变成:

  • 浏览器下载 html

  • 开始解析 html

    • 遇见外链资源, 开始下载, 并且继续解析

    • html 解析结束

    • 等到css下载结束

      • 开始处理 css

        • 处理完毕, 开始渲染

        • 用户看到界面

现在考虑一种情况:
js 是有能力去改变 DOM, 那么如果都渲染结束了, js 这个时候开始执行了,然后把页面重新干掉了.
这个时候怎么办?


只能将修改应用到已经渲染好的页面上.

考虑一种极端情况, 页面里面有成千上万的节点, 比如说1万个节点, css 文件都 一两百k
辛辛苦苦浏览器把页面渲染出来了, 然后这个时候, js 下载结束开始执行, 啪的一下把页面


document.write('中奖啦');

这种情况肯定不能允许发生.

为了避免这种情况, 可以这样
先全局检测下是不是有 script 标签, 如果有的话, html 就等着 script 加载执行之后,
再开始渲染.

这种方式有一个不好: 也就是说, 即使我们现在有了 html 和 css, 其实都可以把页面渲染出来了
但是还是要等 script 下载执行之后才敢进行渲染, 有点投鼠忌器的感觉.
有时候等半天, 可能 script 返回的就一句话:

console.log('逗你玩');

而且全局检测 script 标签, 这句话说的简单, 实际上是要建立在你已经把 html 解析结束了之后才知道
到底有没有 script 标签.

所以实际的情况是:

浏览器不知道页面里面有没有 script 标签
不知道script 里面会不会有 DOM 操作, 是 '中奖啦' 还是 '逗你玩'

面对这种情况, 实际上只能赌, 或者说博弈.

浏览器拿到 html 和 css 之后依旧开始解析渲染
为了减小万一中奖之后全盘都输的情况, 当遇见 script 之后

停止解析, 专心下载 js 文件这样即使中奖, 我也就渲染了前面了一点内容, 后面的还没有渲染, 输少点但是这样后面如果还有资源要加载。。。

所以更新策略:

浏览器遇见 script, 开始下载, 把后面的html 解析掉, 所有的资源都开始下载
然后回头安心等这个 script, 看看到底中奖不中奖.

所以模型变成:

  • 浏览器下载 html

  • 开始解析 html

    • 遇见外链, 开始下载

      • 发现 script 外链, 继续html解析

        • 将页面分成两部分, script 标签之前, 之后

          • 处于 script 之前的页面

            • css 下载结束

              • 渲染

              • 处于 script 之后的页面

                • script 下载完毕, 执行

                  • css 下载完毕

                    • 渲染

浏览器不是等所有的资源都下载结束才开始渲染
浏览器也不是等到所有的 js 都执行结束之后才会渲染

具体的渲染过程

当 html 解析成 DOM tree, css 解析成 CSSOM, 二者合并成
Render Tree, 就可以开始渲染了.

首先要先计算这棵树上面的所有的节点的位置, 这一步叫做 layout
然后要给每个节点上色, 这一步叫做 paint
layout 和 paint 统称为 render.

当页面的元素的位置修改之后, 就会出现 relayout (重绘)
relayout 必定会造成 repaint.

附录: defer, async 之间的区别.

defer
之前说了, 浏览器遇见 js 之后会始终等着它执行, 后面的内容都不渲染了
然后经常就报错了, 我草获取某个节点怎么没有, 想要获取后面的节点但是节点还没有
渲染出来, 所以呢, 所以就有了 defer
相当于说, 我等你全部渲染之后再执行吧, 要不然我老是出错, 烦人.
执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。

async
还有一种情况, 就是说, 浏览器辛辛苦苦等到 js 下载执行结束发现哎吆我草这个玩意
对dom屁改动都没有, 我等她干嘛啊, 我草草, 那就出来 async
这个东西就是说, 不需要等我, 也不需要关心我的执行, 我不会干扰你的, 你做自己的事情就好.
同时也解决了多个js之间的依赖, 加上这个就表示, 我是孤立的, 我不依赖任何其他js也不给任何其他
js 依赖.

通俗的说下浏览器的渲染过程相关推荐

  1. vuex中的值变化 页面重新渲染_浅谈浏览器的渲染过程,重绘与回流

    浏览器的渲染过程 首先,我们先来了解一下浏览器的渲染过程是什么样的,也就是说浏览器把一堆代码呈现到页面上的过程是什么样子的,浏览器采用流式布局模型(Flow Bsaed Layout),根据下图,我们 ...

  2. 输入URL后浏览器的渲染过程

    铅笔头课堂,有态度的前端培训 输入URL后浏览器的渲染过程 背景 作为前端开发,浏览器是与我们日常相伴的工具,以chrome为例,我们可以利用它调试页面的element节点.network网络.con ...

  3. 10分钟看懂浏览器的渲染过程及优化

    一.浏览器概述   目前的主流浏览器有5个:Internet Explorer.Firefox.Safari.Chrome和Opera浏览器.根据 StatCounter 浏览器统计数据,目前(截止2 ...

  4. Alternate Realities大赛作品引发的思考(一)——用通俗的语言解释shader的渲染过程

    背景 本科学了四年的数字媒体技术,如今对流行的shader技术,合成(compositing),渲染还是一窍不通. 基本写作业就是面向tutorial,没有办法响应需求,更没有办法形成自己的风格. 思 ...

  5. 彻底搞清楚浏览器渲染过程

    一.概述 在分析浏览器的渲染过程之前,我们先了解一下什么是进程和线程: (1)什么是进程? 进程是CPU进行资源分配的基本单位. (2)什么是线程? 线程是CPU调度的最小单位,是建立在进程的基础上运 ...

  6. 前端开发这么多年,你真的了解浏览器页面渲染机制吗?

    作者 | 浪里行舟 前言 浏览器的内核是指支持浏览器运行的最核心的程序,分为两个部分的,一是渲染引擎,另一个是JS引擎.渲染引擎在不同的浏览器中也不是都相同的.目前市面上常见的浏览器内核可以分为这四种 ...

  7. 浏览器渲染机制面试_面试官不讲码德,问我Chrome浏览器的渲染原理(6000字长文)...

    前言 对于HTML,css和JavaScript是如何变成页面的,这个问题你了解过吗?浏览器究竟在背后都做了些什么事情呢?让我们去了解浏览器的渲染原理,是通往更深层次的开发必不可少的事情,能让我们更深 ...

  8. js一定要放在body的最底部么?聊聊浏览器的渲染机制

    今天看了一篇前段大全推送的"js一定要放在body的最底部么?聊聊浏览器的渲染机制".正好今天在<javascript Dom 编程艺术>上看到有说,<scrip ...

  9. 前端开发这么多年,你真的了解浏览器页面渲染机制吗? | 技术头条

    作者 | 浪里行舟 前言 浏览器的内核是指支持浏览器运行的最核心的程序,分为两个部分的,一是渲染引擎,另一个是JS引擎.渲染引擎在不同的浏览器中也不是都相同的.目前市面上常见的浏览器内核可以分为这四种 ...

最新文章

  1. 临时表空间过大解决方法
  2. 韩梦飞沙-屏幕录像专家 win10 含注册机
  3. 搞对象的时候走神儿了
  4. 游标卡尺尺身的刻度间距为_【物业】游标卡尺使用及读数方法
  5. MYSQL数据库VALUES_MYSQL入门大全来啦!
  6. Qt工作笔记-QHash与QMap查找速度粗略比较实战
  7. 2-3:配置与环境之定制提示符
  8. 我的swagger上面怎么没有models_浅析特斯拉Model S的采样板
  9. LeetCode 263. Ugly Number
  10. kali linux切换更新源_KALI更新源2020版(永久实用)
  11. u-boot移植随笔:u-boot启动流程简图
  12. 11-Elasticsearch的X-Pack
  13. ipv6单播地址包括哪两种类型_IPV6中为啥没有ARP了呢?一文带你搞懂NDP邻居发现协议...
  14. 「ZJOI2019」麻将
  15. 01 Oracle 导入SQL文件
  16. 微信开发者工具历史版本下载
  17. JAVA环境变量配置方法(Windows)
  18. 游戏开发如此简单?我直接创建了一个游戏场景【python 游戏实战 02】
  19. JavaScript的map方法
  20. androidnbsp;强大的adbnbsp;测试工具

热门文章

  1. python anaconda下载包_【Python开发】anaconda3 安装python包
  2. linux gitlab 9 邮件不发送,gitlab无法发送邮件
  3. java comparable接口_Java面试题之Java集合篇三
  4. 5加载stm32 keil_「keil」嵌入式STM32开发环境之Keil5的安装(附资源) - 金橙教程网
  5. 18年石油大学c语言网考答案,石油大学华东C语言2018在线考试.doc
  6. 目标函数、损失函数、代价函数
  7. 【阿里云课程】从零开始1小时快速掌握Pytorch核心功能,完成完整的项目实践...
  8. 【6月月报】新书加印与勘误,七大专栏齐上线,知识星球大改版!
  9. 中国餐饮连锁行业前景预测及未来战略规划建议报告2022年版
  10. centons7编译安装zabbix3.4【转https://www.cnblogs.com/kowloon/p/7771495.html】