客户端容器(二)| 青训营笔记

94 阅读10分钟

Chrome 运行原理

浏览器地址输入 URL 后发生了什么?

地址输入之后,会经过以下流程:输入处理、开始导航、读取响应、寻找渲染进程(通过 IPC 方式与渲染进程交互)。

在浏览器中,不同的页面(或者说标签页)通常都是运行在独立的进程中的,这些进程之间需要进行进程间通信(IPC)来实现一些功能。主要的浏览器 IPC 通信方式包括:

  1. 消息通信(Message Communication):在浏览器中,通过 postMessage() 方法可以在不同的页面或者 iframe 之间进行消息通信。每个窗口都有自己的 window.postMessage() 方法,可以向其他窗口发送消息,也可以接收其他窗口发送过来的消息。
  2. websocket:websocket 是一种全双工通信协议,可以在客户端和服务器之间进行进行双向数据传输。在浏览器中,可以使用 WebSocket 对象进行 WebSocket 的创建和管理,从而在不同页面之间进行通信。
  3. WebRTC:WebRTC 是一个实时通信协议,它支持点对点(P2P)的音视频通讯以及文件传输等功能。如果需要在不同的页面之间进行音视频传输或文件传输,可以使用 WebRTC 技术进行实现。

需要注意的是,在浏览器中进行 IPC 通信需要考虑到安全性和隐私性。例如,在使用 postMessage() 进行消息通信时,需要防范跨域脚本攻击,保证消息的安全性和正确性;在使用 WebRTC 进行音视频通讯时,需要保证用户的隐私不被泄露。

输入处理

  1. 用户 URL 框输入内容后,UI 线程会判断输入都是一个 URL 地址还是一个 query 查询条件。
  2. 如果是 URL,直接请求站点资源。
  3. 如果是 query,将输入发送给搜索引擎。

开始导航

  1. 当用户按下回车,UI 线程通知网络线程发起一个网络请求,来获取站点内容。
  2. 请求过程中,tab 处于 loading 状态。

读取响应

  1. 网络线程接受到 HTTP 响应后,先检查响应头的媒体类型(MIME Type
  2. 如果响应主体是一个 HTML 文件,浏览器将内容交给渲染进程处理。
  3. 如果拿到的是其他类型文件,比如 Zipexe 等,则交给下载管理器处理。

寻找渲染进程

  1. 网络线程做完所有检查后,会告知主进程数据已准备完毕,主进程确认后为这个站点寻找一个渲染进程。
  2. 主进程通过 IPC 消息告知渲染进程去处理本次导航。
  3. 渲染进程开始接收数据并告知主进程自己已开始处理,导航结束,进入文档加载阶段。

渲染进程

资源加载

  1. 收到主进程的消息后,开始加载 HTML 文档。
  2. 除此之外,还需要加载子资源,比如一些图片,CSS 样式文件以及 JS 脚本。

构建渲染树

  1. 构建 DOM 树,将 HTML 文本转化成浏览器能够理解的结构。
  2. 构建 CSSOM 树,浏览器同样不认识 CSS,需要将 CSS 代码转化为可理解的 CSSOM。
  3. 构建渲染树,渲染树是 DOM 树和 CSSOM 树的结合。

页面布局

  1. 根据渲染树计算每个结点的位置和大小。
  2. 在浏览器页面区域绘制元素边框。
  3. 遍历渲染树,将元素以盒模型的形式写入文档流

页面绘制

  1. 构建图层:为特定的节点生成专用图层。

  2. 绘制图层:一个图层分成很多绘制指令,然后将这些指令按顺序组成一个绘制列表,交给合成线程

  3. 合成线程接收指令生成图块

  4. 栅格线程将图块进行栅格化。

    栅格线程将图块进行栅格化,是为了将大图片拆分成多个小的图块,并且对这些小图块进行处理,从而提高图片在网页加载过程中的响应速度和用户体验。

    一张大图片如果直接加载到网页上,会让页面的加载变得非常缓慢,特别是当网络速度不够快时。而将大图片拆分成多个小的图块,就可以把这些小的部分分开加载,而不是等待整张图片全部加载完成后再显示出来。

    具体来说,在栅格线程将图块进行栅格化后,可以对每个小的图块进行处理,例如压缩、裁剪、缩放等操作,还可以针对图块进行缓存或者延迟加载等策略,以提升用户的访问速度和流畅度。

    通过拆分图片和对图片进行处理,栅格线程可以优化图片的加载和渲染,提升网页的性能和用户的使用体验。

  5. 展示在屏幕上。

前端性能 performance

  1. 时间都花在哪
  2. 什么情况下卡顿

首屏优化

首屏优化是指通过一系列技术手段,尽可能地优化页面在用户访问时展示的效果,提高页面的加载速度和用户体验。常用的优化方式有以下几种。

  1. 压缩、分包、删除无用代码:对于 HTML、CSS、JavaScript 等资源文件,可以通过压缩、分包、删除无用代码等方式来减少它们的体积,从而减少页面的加载时间。使用一些工具,比如 Webpack,Gulp 等工具可以很方便地进行这些操作。
  2. 静态资源分离:将静态资源(如图片、CSS、JavaScript 等)与 HTML 文件分离,并将它们部署到不同的服务器上,以减轻服务器的负担并提高资源加载速度。
  3. JS 脚本非阻塞加载:使用异步加载方式加载 JavaScript 文件,避免 JavaScript 脚本的加载和执行阻塞页面的渲染。可以使用 defer 属性或者动态创建 script 标签等方式来实现。
  4. 缓存策略:利用浏览器的缓存机制来避免重复的请求和获取,减少网络传输时间,提高页面加载速度。可以设置 expires 和 cache-control 两种响应头来定义缓存时间,也可以使用 ETag 或者 last-modified 等机制来验证缓存的有效性。
  5. SSR:服务端渲染(Server-Side Rendering)可以在服务器端将页面 HTML 模板渲染成最终的 HTML 页面,然后再将其发送到客户端。这样可以减少客户端渲染所需要的时间,提高首屏加载速度和 SEO 效果。
  6. 预置 loading、骨架屏:在页面加载过程中,通过预置 loading 和骨架屏等方式,给用户一个良好的反馈,告诉用户内容正在加载中,避免出现长时间的空白页面或者等待状况,提高用户体验。

渲染优化

渲染优化是指通过一些技术手段,优化页面的渲染流程,提高页面的性能和用户体验。以下是几种常用的渲染优化方式。

  1. GPU 加速:在进行复杂的动画、过渡效果等操作时,可以利用 GPU 进行加速,提高渲染速度和帧数,从而提高用户体验。利用 CSS3 或者 Canvas 等技术,可以很方便地实现 GPU 加速。
  2. 减少回流、重绘:当页面元素位置、大小等属性发生变化时,浏览器会进行回流(重新计算元素布局)和重绘(重新绘制元素样式),这些操作会耗费大量的计算资源,影响页面渲染性能。因此,尽可能地减少回流和重绘操作,可以有效地提高页面性能。可以使用一些工具,如 Chrome 浏览器的 Performance、Paint 和 Layout 面板等来分析和调试页面的回流和重绘情况,找到优化的方向。
  3. 离屏渲染:将不需要频繁更新的元素渲染到离屏的画布上,避免其参与到主屏幕的渲染,从而提高页面的渲染速度。可以使用 CSS 的 transform 和 opacity 属性来触发元素的离屏渲染。
  4. 懒加载:在页面中,只有当用户滚动到某个位置时,才加载该位置下的图片或其他资源。这种方式可以减少页面一开始的加载时间和流量,提高首屏速度,同时支持按需加载,降低服务端压力。可以使用 JavaScript 插件,如 LazyLoad.js、Echo.js 等插件来实现懒加载效果。

JS 优化

JS 优化是指通过一些技术手段,优化 JavaScript 代码的性能,提高页面的响应速度和用户体验。以下几种 JS 优化方式。

  1. 防止内存泄露:在开发复杂的 JavaScript 应用程序时,容易出现内存泄漏的情况,导致内存占用越来越高,最终影响整个应用程序的性能。因此,需要特别注意防止内存泄漏的问题,避免不必要的资源浪费。可以使用浏览器自带的开发者工具进行内存分析,找到可能存在的内存泄漏问题。
  2. 循环尽早 break:在进行循环操作时,如果已经达到预期的结果,可以提前结束循环,避免浪费不必要的计算资源。比如,在数组中查找特定元素时,如果找到了目标元素,就可以使用 break 关键字提前结束循环,从而提高代码效率。
  3. 合理使用闭包:使用闭包可以有效地保护变量作用域,避免全局变量污染和命名冲突等问题。但是,如果过度使用闭包,会导致内存占用过大,从而影响 JavaScript 的性能。因此,需要合理使用闭包,避免出现滥用的情况。
  4. 减少 DOM 访问:在 JavaScript 中,访问 DOM 是一项非常耗时的操作,应该尽可能地减少对 DOM 的访问,以提高页面的响应速度和性能。可以使用缓存、批量操作、事件委托等方式来减少 DOM 访问次数。
  5. 防抖、节流:防抖和节流是两种优化 JavaScript 性能的方法。防抖是指在某个时间段内,只有最后一次操作会被执行,而其它操作都会被忽略。节流是指在一定时间间隔内,只执行一次操作,避免重复操作。这两种方法可以有效地降低浏览器的计算压力和网络资源消耗,提高性能和用户体验。
  6. Web Workers:Web Workers 是 HTML5 中的一个新功能,通过将 JavaScript 运行在独立的线程中,可以释放浏览器主线程的负担,从而提高 JavaScript 的性能和效率。Web Workers 可以用于后台计算、大数据处理、网络请求等操作。但是需要注意的是,Web Workers 模型不能直接访问 DOM,需要采用消息传递机制来与主线程通信。