IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 浏览器进程与浏览器的渲染机制 -> 正文阅读

[JavaScript知识库]浏览器进程与浏览器的渲染机制

1. 浏览器进程

1. 浏览器的多进程架构

  • 一个好的程序常常被划分为几个相互独立又彼此配合的模块,浏览器也是如此。
  • 以 Chrome 为例,它由多个进程组成,每个进程都有自己核心的职责,它们相互配合完成浏览器的整体功能,
  • 每个进程中又包含多个线程,一个进程内的多个线程也会协同工作,配合完成所在进程的职责。
  • Chrome 采用多进程架构,其顶层存在一个 Browser process 用以协调浏览器的其它进程。

2. 浏览器的主要进程与功能

详见下面的思维导图
在这里插入图片描述

2. 浏览器渲染流程

在这里插入图片描述

  1. 解析 HTML 文件,构建 DOM 树,同时浏览器主进程负责下载 CSS 文件
  2. CSS 文件下载完成,解析 CSS 文件成树形的数据结构,然后结合 DOM 树合并成 RenderObject 树,CSSOM 的解析过程与 DOM 的解析过程是并行的。
  3. 布局 RenderObject 树 (Layout/reflow),负责 RenderObject 树中的元素的尺寸,位置等计算,计算图层布局
  4. 绘制 RenderObject 树 (paint),绘制页面的像素信息,绘制图层
  5. 浏览器主进程将默认的图层和复合图层交给 GPU 进程,GPU 进程再将各个图层合成(composite),最后显示出页面,整合图层成界面
    在这里插入图片描述
    在这里插入图片描述

3. 一些题解

1.为什么js是单线程

这是因为 Javascript 这门脚本语言诞生的使命所致!
JavaScript 为处理页面中用户的交互,以及操作 DOM 树、CSS 样式树来给用户呈现一份动态而丰富的交互体验和服务器逻辑的交互处理。
如果 JavaScript 是多线程的方式来操作这些 UI DOM,则可能出现 UI 操作的冲突。
如果 Javascript 是多线程的话,在多线程的交互下,处于 UI 中的 DOM 节点就可能成为一个临界资源,
假设存在两个线程同时操作一个 DOM,一个负责修改一个负责删除,那么这个时候就需要浏览器来裁决如何生效哪个线程的执行结果。
当然我们可以通过锁来解决上面的问题。但为了避免因为引入了锁而带来更大的复杂性,Javascript 在最初就选择了单线程执行。

2. 为什么js阻塞页面加载

js能够操作dom,如果在修改dom的时候渲染界面,那么渲染线程先后获得的元素数据可能会不一致,为了防止渲染出现不可预期的结果,GUI渲染线程与js引擎线程互斥,js引擎执行时,GUI线程被挂起,保存在队列中等到js引擎线程空闲时立即被执行,因此如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。

3. css加载会造成阻塞吗

dom和cssdom是并行构建的,所以css加载不会阻塞dom的解析,然而,由于 Render Tree 是依赖于 DOM Tree 和 CSSOM Tree 的,
所以他必须等待到 CSSOM Tree 构建完成,也就是 CSS 资源加载完成(或者 CSS 资源加载失败)后,才能开始渲染。因此,CSS 加载会阻塞 Dom 的渲染。

4. 优化策略

1. css样式表优化:

SS 引擎查找样式表,对每条规则都按从右到左的顺序去匹配
eg:

#myList  li {}

查找所有的li,并且每次去确认这个li的父元素id是不是mylist

* {
 margin:0
 padding:0
}

会匹配遍历所有元素

所以,css优化策略为:

  1. 避免使用通配符,只对需要用到的元素进行选择。
  2. 关注可以通过继承实现的属性,避免重复匹配重复定义。
  3. 少用标签选择器。如果可以,用类选择器替代,举个🌰:
    错误示范:#myList li{}
    课代表:.myList_li {}
  4. 减少嵌套,后代选择器的开销是最大的,我们应该尽量将选择器的深度降到最低(最高不要超过三层),尽可能使用类来关联每一个标签元素。

2.css与js的加载顺序优化

1.css的阻塞

  1. 必须等到csson树的生成才能与dom合并为renderTree,即便 DOM 已经解析完毕了,只要 CSSOM 不 OK,那么渲染这个事情就不 OK(这主要是为了避免没有 CSS 的 HTML 页面丑陋地“裸奔”在用户眼前)。
  2. 我们开始解析 HTML 后、解析到 link 标签或者 style 标签时,CSS 才登场,CSSOM 的构建才开始。很多时候,DOM 不得不等待 CSSOM。因此我们可以这样总结:

CSS 是阻塞渲染的资源。需要将它尽早、尽快地下载到客户端,以便缩短首次渲染的时间。

  1. 策略:
  • 把css往前放:放在head标签里
  • 启用csn实现静态资源加载速度的优化

2. js的阻塞

页面没有css也可以呈现,只不过毫无交互,死气沉沉,如前面的题解所说,js不光会阻塞dom,还会阻塞csson,因为js会对style和dom进行一些操作,那么渲染线程先后获得的元素数据可能会不一致,为了防止渲染出现不可预期的结果,GUI渲染线程与js引擎线程互斥

eg:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>JS阻塞测试</title>
  <style>
    #container {
      background-color: yellow;
      width: 100px;
      height: 100px;
    }
  </style>
  <script>
    // 尝试获取container元素
    var container = document.getElementById("container")
    console.log('container', container)
  </script>
</head>
<body>
  <div id="container"></div>
  <script>
    // 尝试获取container元素
    var container = document.getElementById("container")
    console.log('container', container)
    // 输出container元素此刻的背景色
    console.log('container bgColor', getComputedStyle(container).backgroundColor)
  </script>
  <style>
    #container {
      background-color: blue;
    }
  </style>
</body>
</html>

三个console的结果是
在这里插入图片描述

  1. 浏览器之所以阻塞,是因为不知道js会做出什么改变,若不阻止,会造成混乱,但是为什么作为程序员,可以确认js的执行时间,是要立马执行,还是需要等页面渲染完毕再执行,假如我们可以确认一个 JS 文件的执行时机并不一定非要是此时此刻,我们就可以通过对它使用 defer 和 async 来避免不必要的阻塞,这里我们就引出了外部 JS 的三种加载方式。

js的三种加载方式

  • 正常模式:
    <script src="index.js"></script>
    这种情况下 JS 会阻塞浏览器,浏览器必须等待 index.js 加载和执行完毕才能去做其它事情。
  • async 模式:
    <script async src="index.js"></script>
    async 模式下,JS 不会阻塞浏览器做任何其它的事情。它的加载是异步的,当它加载结束,JS 脚本会立即执行。
  • defer 模式:
    <script defer src="index.js"></script>
    defer 模式下,JS 的加载是异步的,执行是被推迟的。等整个文档解析完成、DOMContentLoaded 事件即将被触发时,被标记了 defer 的 JS 文件才会开始依次执行。
    从应用的角度来说,一般当我们的脚本与 DOM 元素和其它脚本之间的依赖关系不强时,我们会选用 async;当脚本依赖于 DOM 元素和其它脚本的执行结果时,我们会选用 defer。
    通过审时度势地向 script 标签添加 async/defer,我们就可以告诉浏览器在等待脚本可用期间不阻止其它的工作,这样可以显著提升性能。
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-06 12:53:25  更:2022-03-06 12:58:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:07:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码