js修改背景图片路径_前端面试题————关键渲染路径(Critical Rendering Path)...
前端面试,总是会被问到这样一类问题:
为什么最好把 CSS 的<link>标签放在<head></head>之间?为什么最好把 JS 的<script>标签放在</body>之前?
为什么JS 会阻塞DOM解析,而CSS会阻塞渲染??
<script>标签当中的async和defer都是做什么的???
如何优化关键渲染路径????
好了好了,其实理解了关键渲染路径之后,这些问题会变得so easy。妈妈就再也不用担心我的前端面试了。那么,我们就来看看,什么是关键渲染路径
关键渲染路径都有哪些步骤呢?
关键渲染路径一共分为6个步骤,如下图所示:
具体分为:
- 创建DOM树
- 创建CSS树
- 执行脚本(就是JavaScript)
- 生成渲染树
- 布局
- 绘制
我们接下来一步一步地分析。
创建DOM树
下面是一段很简单的HTML代码:
<!DOCTYPE html>
<html><head><meta name="viewport" content="width=device-width,initial-scale=1"><link href="style.css" rel="stylesheet"><title>Critical Path</title></head><body><p>Hello <span>web performance</span> students!</p><div><img src="awesome-photo.jpg"></div></body>
</html>
浏览器读到这一段代码之后,会把标签转换成DOM树中对应的节点,保留每个节点的属性,并根据节点与节点之间的父子关系,生成树形结构:
这就是DOM树。
创建CSSOM树
上个例子中,当浏览器在创建DOM树的时候,会遇到外部CSS标签:<link href=”style.css” rel=”stylesheet”>。浏览器这个时候会发出http请求,向服务器请求这个文件的内容:
body { font-size: 16px }
p { font-weight: bold }
span { color: red }
p span { display: none }
img { float: right }
浏览器收到这个文件之后,会把文件中的CSS转换成CSSOM树。这个过程并不是更新现在这棵DOM树,而是同时去生成一个新的,完全独立的树形结构。 DOM树和CSSOM树是两个不同的数据结构。
生成渲染树
上个例子中,当DOM树和CSSOM树都准备好了之后,浏览器就会合并这两棵树,生成渲染树,如下图所示:
有几点需要注意的:
- 我们可以看到,渲染树是需要DOM树和CSSOM树建立完成之后才能够生成的,因此,HTML和CSS都是会阻塞渲染的!
- 然而,没有CSS的页面看起来是很糟糕的,因此,我们应该尽早完成CSS的下载与解析,因此CSS标签应当被放到head当中。
- <head>以及其内部的标签不会出现在渲染树当中
- 被隐藏的属性也不会出现在渲染树当中,例如例子中display: none的span标签。注意:visibility: hidden的元素虽然被隐藏,但是仍在文档流中占据空间,不会从渲染树当中移除。
执行脚本
如果代码当中有script标签,那么浏览器就会下载(这个只针对外联JS代码)然后运行JS代码。
有几点需要注意的:
- JS代码可以修改DOM结构,更改CSS样式,因此,JS可以查询和修改DOM树和CSSOM树。
- 脚本在哪里插入,就会在哪里执行。浏览器解析DOM的时候,如果遇到script标签,会停止解析DOM,JS引擎会运行script中的脚本,运行结束后,才继续解析DOM。因此,脚本会阻塞DOM的解析。
- 如果脚本想要修改CSSOM的内容,而此时,CSSOM还未构建完成,那么浏览器会选择先下载并创建CSSOM,然后再运行脚本。
因此,script标签的位置很重要,我们往往选择在</body>之前加入script,这样可以保证DOM树的解析,把页面尽早呈现给用户。
那么,什么是async,什么是defer?
Async是不会阻塞关键渲染路径的,async告诉浏览器,如果遇到带有async的script标签时,这段脚本的下载不会阻塞浏览器构建DOM树,浏览器向服务器发送script请求的时候,仍然可以继续构建DOM树。
Defer也是告诉浏览器立即下载脚本文件(同样不会阻塞DOM),但是延迟到整个页面都解析完毕之后再运行。
用一张图表示就是:
布局
上面的例子当中,有这样一段代码:
<meta name="viewport" content="width=device-width,initial-scale=1">
这段代码中,width=device-width是告诉浏览器页面宽度要符合设备的DIP(设备独立像素)宽度,而initial-scale=1则告诉浏览器DIP与设备像素之间的比例为1(这个不懂也没关系,以后有空的话,我也会发文给大家简单解释解释)。
浏览器会从根节点开始,确定每个节点在页面上的大小和位置,使用盒模型把每个元素定位在页面当中。
绘制
最后一步,把渲染树上的节点绘制在页面当中,并画上花花绿绿的样式。
如何优化关键渲染路径
优化关键渲染路径,主要从三个方面下手:
- 减少文件大小:最小化文件;压缩文件;以及缓存文件
- 减少关键资源的数量:CSS和JS文件放在bundle当中;在link上使用media query(media=”print”文件中的样式只有在打印时才会被使用,因此,media=”print”告诉浏览器,我并不会阻塞关键渲染路径);在script标签中使用async或者defer
- 减少关键渲染路径的长度(这是获取所有关键资源所需的往返次数或总时间)
结束
希望看完这篇文章之后,你能够回答开头提出的那几个问题了。祝大家前端学习一切顺利。
js修改背景图片路径_前端面试题————关键渲染路径(Critical Rendering Path)...相关推荐
- js 定时网页点击_前端面试题整合(JS进阶篇)(二)
Ajax 是什么? 如何创建一个Ajax? AJAX全称是Asychronous JavaScript And Xml(异步的 JavaScript 和 XML) 它的作用是用来实现客户端与服务器端的 ...
- js 定时网页点击_前端面试题熬夜吐血(js进阶篇)
Ajax 是什么? 如何创建一个Ajax? AJAX全称是Asychronous JavaScript And Xml(异步的 JavaScript 和 XML) 它的作用是用来实现客户端与服务器端的 ...
- JS——修改背景图片
问题描述 使用JS修改元素的背景图片 解决方法 1 使用 css() 给元素添加背景图片 这种方法添加的样式优先级相当于行内样式,会覆盖掉优先级比他低的样式 代码如下: $("css选择器& ...
- css grid 自动高度_前端面试题:关于CSS布局
金三银四求职季 各位同学面试是否顺利呢? 在这关键时刻 小狮送上前端面试题一份 有用就赶紧收藏起来吧!!! 1 Q:三栏布局,高度已知,左右两栏固定,中间自适应的三栏布局有几种实现方式,各自的优缺点是 ...
- dom vue 加载完 执行_前端面试题——Vue
前言 前几天整理了一些 html + css + JavaScript 常见的面试题(https://segmentfault.com/u/youdangde_5c8b208a23f95/articl ...
- dom vue 加载完 执行_前端面试题Vue
前言 前几天整理了一些 html + css + JavaScript 常见的面试题,然后现在也是找了一些在 Vue 方面经常出现的面试题,留给自己查看消化,也分享给有需要的小伙伴. 如果文章中有出现 ...
- 如何获取元素在父级div里的位置_前端面试题--元素的BFC特性和实例
1.BFC 是什么? Block Formatting Contexts 块级格式化上下文.(不懂? 没关系,后文有介绍.) 2.为什么需要BFC? 在传统布局中出现的问题需要一种统一的解决方案. 首 ...
- react全局方法_前端面试题 ---react
高阶组件相关 什么是高阶组件,它有哪些运用? 高阶组件就是一个函数,接收一个组件,经过处理后返回后的新的组件: 高阶组件,不是真正意义上的组件,其实是一种模式: 可以对逻辑代码进行抽离,或者添加某个共 ...
- php 统计二维数组次数最多_前端面试题(数组篇)
前端面试中,数组是少不了的.因为数组使用度比较频繁,我在项目中就经常使用.JavaScript拼接Html,数据结构计算,等等. 汇总一下面试中数组会问到的几个问题,这个问题在面试经常被问到,但是一般 ...
最新文章
- Android之调用js常见错误
- Delphi IDE扩展工具,在IDE中增加Google翻译器
- 利用redis实现分布式锁:加锁与解锁
- 找出不是两个数组共有的元素
- [luoguP1013] 进制位(搜索)
- 物联网-移远M26模块OpenCPU开发第3讲(看门狗)
- 洛谷 P1508 Likecloud-吃、吃、吃
- Android动态切换主题
- php utf8 正则中文表达式
- Mate7微信指纹支付来了 比Touch ID整合微信早一点
- 计算机在线考试系统监考,在线考试系统怎样实现监考功能
- 正确的java学习顺序--刚入门的同学可以看这里
- (实验)使用Protel 99se绘制2114存储器芯片(详细)
- Python实现简单的用户管理系统
- Activity任务栈
- diskgenius克隆硬盘无法启动_克隆分区
- c++ RMI demo(使用RCF库)
- 古时候的汉法,现代社会的红光光浴-种光光学
- 3.提取线稿(PS)
- ANO匿名飞控分析(2)— 任务调度