在浏览器输入一个URL后主要流程是怎么样的?

1. 浏览器辨别出是否是一个合理的URL,不是则用默认搜索引擎进行搜索。如果是合理的URL,则执行一次DNS的查询,DNS也可以从浏览器的缓存或者操作系统的hosts目录去查找,如果没有找到,则会往远程的DNS域名服务器上去查询,这个结果会被浏览器缓存下来,方便下次加速查询。

2. 如果是合理的URL,第一步看缓存,http1.1的cach-control 或者http1.0的expires,如果没有过期,则直接使用,流程结束。

3. TCP的三次握手,建立连接, 如果是Https协议,还会额外执行SSL/TLS的二次握手,通过非对称加密算法以及CA证书协商出对称加密密钥。

4. 握手结束后,就会发起真正的http数据请求,服务器收到请求后,可能访问数据库,redis等,经过业务层逻辑处理,最后生成页面返回Browse,如果是短连接,就会有4次挥手关闭连接,http1.1默认保持连接,方便其他请求复用这条链路。

5. 浏览器的网络进程收到响应html文件流后,JS主线程中的HtmlParse模块解析出Dom,CSSOM(内嵌,行内,link外置根据优先级合并,还有css尺寸单位标准化为px表示),最后把他们合并出布局树(Layout  Tree),它指出了DOM元素的几何位置信息。

6. 分层,它会根据是否出现3D转换,Z-Index, Fiilter,Transform,Opacity,定位属性,是否出现裁剪,文字区域是否出现滚动条等进行分出多个图层,类似与PS制图软件的分层思路。

7. 绘制, 实际这一步没有真正的绘制,只是把每一个图层的绘制拆分成很多小的绘制指令,再顺序组成一个绘制列表。

8. 栅格化,先会分块成比较小的的块,如256 x 256,512 x 512,视口附件优先生成位图的原则,将图块转换为位图。栅格化这个过程会使用GPU来加速生成,这个过程叫做快速栅格化,生成的位图会放到GPU中。

9 合成显示,栅格化完成后,浏览器进程会合并这些位图,最后显示到浏览器中。

 

优化点

如果JS中会操作的动画,可以事先用Will-Change再css中指定,比如will-change:transform/Opacity等。这样就可以单独给这个元素分一层,变化是只会操作这一层,效率就会好很多。

一帧16ms(1s/60)内没有生成一张图片,就会出现卡顿。

重排重绘是这主线程中完成的,会直接影响其他JS的执行,栅格化分块,合成操作时渲染流程后续的合成线程中完成的,不会占用js主线程的时间片。

相关优化

  • 减少请求和文件大小:合并和压缩CSS和JavaScript文件,减少网络请求的数量和文件的大小。可以使用构建工具(如Webpack)来实现文件的合并和压缩。

  • 使用浏览器缓存:利用浏览器缓存机制,将静态资源(如图片、CSS和JavaScript文件)设置为可缓存,并设置适当的缓存头部,以减少重复的网络请求。

  • 延迟加载和异步加载:对于大型或不必要的资源,可以延迟加载或异步加载,以避免阻塞页面的初始渲染。例如,使用<script>标签的asyncdefer属性来异步加载脚本。

  • 优化CSS选择器:避免使用复杂的CSS选择器,因为它们的匹配和计算成本较高。尽量使用简单的选择器,并避免使用通配符选择器和后代选择器。

  • 避免强制同步布局:当修改元素的样式时,会触发布局和绘制过程。避免在布局阶段触发强制同步布局的属性,如offsetTopoffsetWidth等,因为它们会导致浏览器强制进行回流。

  • 使用CSS3硬件加速:对于需要频繁重绘的元素(如动画效果),使用CSS3硬件加速(通过transformopacity属性)可以利用GPU加速渲染,提高性能。

  • 图片优化:使用适当的图片格式(如JPEG、PNG、SVG)和压缩技术,以减小图片文件的大小。可以使用工具(如ImageOptim、TinyPNG)自动压缩和优化图片。

  • 延迟加载图片:对于长页面或滚动加载的内容,可以使用延迟加载技术,仅在图片进入视口时再进行加载,以避免一次性加载大量图片。

  • 使用字体图标或矢量图形:使用字体图标或矢量图形(如SVG)替代大量的图像文件,以减少网络请求和文件大小。

  • 使用CDN(内容分发网络):将静态资源部署到全球分布的CDN上,可以提供更快的加载速度和更好的可扩展性。

 

Defer 和 Async 标识

defer属性用于异步加载脚本,它们会在文档解析完成后、DOMContentLoaded事件之前(jquery ready 事件绑定在这里)执行(load事件是所有资源加载完成才触发),不会阻塞页面的解析过程。而async属性也用于异步加载脚本,但它们在下载完成后立即执行,可能会中断文档的解析过程,因此一般三方不重要的js文件,监控,埋点等用defer处理
https://www.jb51.net/article/275729.htm


preload 和 prefetch

  • 如果首屏渲染需要的资源呢,我们可以标记<link preload>预先加载关键资源
    使用 preload 可以在页面加载过程中提前获取关键资源,以加快页面的渲染速度,而使用 prefetch 可以在闲置时间预取非关键资源,以备将来使用。根据具体的需求和资源特性,可以选择合适的方式来优化资源加载和页面性能。

  • preload是解析dom之前预先发请求加载资源,渲染时发现资源可能已经加载好了,首屏可展示信息更多。
    1. 浏览器开始加载主 HTML 文档。
    2. 在主 HTML 文档加载过程中,浏览器遇到带有 preload 属性的 <link> 标签,开始预加载指定的资源。
    3. 主 HTML 文档加载完成后,浏览器开始解析和渲染首屏内容,包括首屏所需的 CSS 文件、JavaScript 文件和图片等。
    4. 预加载的资源在首屏渲染过程中,如果已经下载完成,可以立即使用。否则,浏览器会在首屏渲染完成后使用这些预加载的资源。

 

posted @ 2020-03-21 23:38  lswtianliang  阅读(446)  评论(0编辑  收藏  举报