HTML
语义化相关
语义化
在HTML5出来之前,习惯于用div来表示页面的章节,但是div是没有语义的。HTML5通过加入语义标签,如header\nav\main\aside\section(如果想把一块内容分为几块应该使用section)等,来更加清晰的表达文档结构
HTML的语义化是指:通过使用包含语义的标签(如
h1
-h6
)恰当地表示文档结构CSS的语义化是指:为HTML标签添加有意义的class
为什么需要语义化:
HTML语义化让页面的内容结构化,结构更清晰
去掉CSS样式后页面呈现清晰的结构,是容易阅读的
盲人使用读屏器更好地阅读
搜索引擎的爬虫也依赖于HTML标记来确定上下文和各个关键字的权重,语义化利于SEO
便于团队项目的可持续运作及维护
使阅读源代码的人对网站更容易将网站分块,便于阅读维护理解
div标签本身不具有语义,但是可以结合class、title、lang属性来表示具有语义的一组内容
HTML5特性
如何区分HTML和HTML5?
- DOCTYPE声明
- 新增的结构元素
- 新增的功能元素
HTML5的新特性(语义标签、本地存储、媒体播放器、新增选择器)
- 新增选择器 document.querySelector、document.querySelectorAll
- 拖拽释放(Drag and drop) API
- 媒体播放的 video 和 audio(方法有:加载load、播放play、暂停pause;事件有:play、pause、seek、abort;属性有:preload设置是否在页面加载后载入视频、autoplay设置是否在加载后立即播放、buffered返回用户已缓冲音视频的范围、controller返回音视频的当前媒体控制器)
- 本地存储 localStorage 和 sessionStorage
- 离线应用 manifest
- 桌面通知 Notifications
- 语意化标签 article、footer、header、nav、section
- 增强表单控件 calendar、date、time、email、url、search
- 地理位置 Geolocation
- 多任务 webworker
- 全双工通信协议 websocket
- 历史管理 history
- 跨域资源共享(CORS) Access-Control-Allow-Origin
- 页面可见性改变事件 visibilitychange
- 跨窗口通信 PostMessage
- Form Data 对象
- 绘画 canvas
Geolocation API
- 存在于navigator对象中,只包含三个方法:1.getCurrentPosition获取当前位置 2.watchPosition监视位置 3.clearWatch 清除监视
HTML5移除了哪些元素?
- 纯表现的元素:basefont、big、center、font、s、strike、tt、u
- 对可用性产生负面影响的元素:frame、frameset、noframes
- 只有部分浏览器支持的元素:applet、bgsound、blink、marquee
如何处理HTML5新标签的浏览器兼容问题(如何解决IE9及以下版本对H5新增标签不识别、CSS不起作用的问题)?
- 为网站创建多套模板,通过程序对User-Agent的判断给不同的浏览器用户显示不同的页面,但这样成本高,也失去了响应式设计的意义
- 通过 document.createElement 创建新标签
- 使用 html5shiv.js,原理是利用脚本document.createElement(“”)创建对应的脚本,CSS选择器便能正确应用到该标签。html5shiv主要解决HTML5提出的新的元素不被IE6-8识别,这些新元素不能作为父节点包裹子元素,并且不能应用CSS样式。让CSS 样式应用在未知元素上只需执行 。document.createElement(elementName) 即可实现。html5shiv就是根据这个原理创建的。
SGML和DTD(了解即可)
- SGML一种国际标准,该标准定义独立于平台和应用的文本文档格式,索引和链接信息,为用户提供一种类似于语法的机制,用来定义文档的结构和指示文档结构的标签。制定SGML的基本思想是把文档内容于样式分开。SGML规定了在文档中嵌入描述标记的标准格式,指定了描述文档结构的标准方法,这是SGML的精华。换句话说,你可以使用SGML为你创作的每一种类型的文档设置层次结构模型。SGML是一个包含超文本链接的综合语言,在Web上使用的HTML格式是使用固定标签集的一种SGML文档。
- 一个典型的文档可被分为3个层次:结构,内容,样式。SGML主要是处理结构和内容之间的关系。结构:为了描述文档的结构,SGML定义了一个称为“文档类型定义(Document Type Definition,DTD)”的文件,它为组织文档的文档元素(例如章和章标题,节和主题等)提供了一个框架。此外,DTD还为文档元素之间的相互关系指定了规则。例如,“章的标题必须是在章开始之后的第一个元素”,“每个列表至少要有两个项目”等。DTD定义的这些规则可以确保文档的一致性。
- 内容:这里指的内容就是信息本身。内容包括信息名称(标题)、段落、项目列表和表格中的具体内容,具体的图形和声音等。确定内容在DTD结构中的位置的方法称为“加标签”,而创建SGML文档实际上就是围绕内容插入相应的标签。这些标签就是给结构中的每一部分的开始和结束做标记。
- 样式:SGML本身正在定义样式(style)的设置标准,即文档样式语义学和规范语言(Document Style Semantics and Specification Language,DSSSL)。
- 为什么HTML5不使用SGML?W3C 在制定 HTML5 标准时,希望摆脱 SGML 的一些无用的功能和声明,并延续 HTML4 的风格,而非严格的 XHTML 的风格。
HTML5为什么只需要写<!DOCTYPE HTML>
?
- HTML5 不基于 SGML,因此不需要对DTD进行引用,但是需要doctype来规范浏览器的行为,告诉浏览器应该用什么文档标准来解析这个文档
- 而HTML4.01基于SGML,所以需要对DTD进行引用,才能告知浏览器文档所使用的文档类型
Doctype的作用?标准(严格standards)模式与兼容(混杂quirks)模式有什么区别?
<!DOCTYPE>
声明位于位于HTML
文档中的第一行,处于<html>
标签之前。告知浏览器的解析器用什么文档标准解析这个文档。DOCTYPE
不存在或格式不正确会导致文档以兼容模式呈现- 标准模式的排版和JS运作模式都是以该浏览器支持的最高标准运行。在兼容模式中,页面以宽松的向后兼容的方式显示,模拟老式浏览器的行为以防止站点无法工作。
严格模式与混杂模式的语句解析有哪些不同点?
- 混杂模式下盒模型的宽高包括padding和border
- 混杂模式下可以设置行内元素的宽高
- 混杂模式下可以设置百分比的高度
- 混杂模式下无法使用margin: 0 auto;设置水平居中
- 混杂模式下设置图片padding会失效
- 混杂模式下table中的字体属性不能继承上层的设置
- 混杂模式下white-space:pre会失效
HTML5的DTD
<!DOCTYPE html>
HTML5的form如何关闭自动完成功能?
- 自动完成功能:当你往输入框输入内容的时候,浏览器会从你以前的同名输入框的历史记录中查找出类似的内容并列在输入框下面,这样就不用全部输入进去了,直接选择列表中的项目就可以了。
- 方案:给不想要提示的 form 或某个 input 设置为 autocomplete=off。
HTML5编码
- UTF-8称为万国码,使用此编码方式可以在网页上显示中文简体繁体及其他语言,例如英语、日文、韩文等
- GBK是汉字编码,是双字节码,可表示繁体字和简体字
网页验证码是干嘛的,是为了解决什么安全问题
- 区分用户是计算机还是人的公共全自动程序。可以防止恶意破解密码、刷票、论坛灌水
- 有效防止黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试
DOM常见的节点类型
- Element(元素节点):HTML标签,树构建块
- Attr(属性节点)
- Text(文本节点):包含文本
- Comment(注释节点):可以将信息放入此类节点,它不会显示,但JS可以从DOM中读取它
- Document(文档节点):DOM的入口点
- DocumentType(文档类型节点)
- DocumentFragment(文档片段节点)
获取Element对象的方法
- getElementById()
- getElementsByTagName()
- getElementsByClassName()
- getElementsByName()
meta
- width用于控制viewport的大小
- height用于控制viewport的高度
- initial-scale表示初始缩放比例(0-10之间的正数,1表示无缩放)
- minimum-scale表示viewport能缩放到的最小值(0-10之间的正数)
- maximum-scale表示viewport能缩放到的最大值(0-10之间的正数)
- user-scalable表示是否可以手动缩放(yes or no)
浏览器
简述浏览器内核
- 主要分成两部分:渲染引擎(
layout engineer
或Rendering Engine
)和JS
引擎 - 渲染引擎:负责取得网页的内容(HTML、XML、图像等等)、整理讯息(例如加入CSS等),以及计算网页的显示方式,然后会输出至显示器或打印机。浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同。所有网页浏览器、电子邮件客户端以及其它需要编辑、显示网络内容的应用程序都需要内核
- JS引擎:解析和执行javascript来实现网页的动态效果
- 最开始渲染引擎和JS引擎并没有区分的很明确,后来JS引擎越来越独立,内核就倾向于只指渲染引擎
常用的浏览器内核有哪些?
Trident
内核:IE,MaxThon,TT,The World,360
,搜狗浏览器等。[又称MSHTML]Gecko
内核:Netscape6
及以上版本,Firefox,MozillaSuite/SeaMonkey
等Presto
内核:原Opera7
及以上。 [Opera
内核原为:Presto,现为:Blink
;]Webkit
内核:Safari,原Chrome
等。 [Chrome
的Blink
(WebKit
的分支)]Blink
内核:新版google、新版opera
如何实现浏览器内多个标签页之间的通信?[占坑,代码及演示效果]
- localstorge、cookies等本地存储方式
- iframe + contentWindow
- postMessage
- SharedWorker(Web Worker API)
- WebSocket
websocket如何兼容低版本浏览器?[占坑,代码及演示效果]
- Adobe Flash Socket 、
- ActiveX HTMLFile (IE) 、
- 基于 multipart 编码发送 XHR 、
- 基于长轮询的 XHR
浏览器渲染流程
- 构建HTML并构建DOM树
- 构建render树
- 布局render树
- 绘制render树
window对象
- window对象表示浏览器的窗口,可用于检索有关窗口状态的信息
- window对象是浏览器所有内容的主容器
- 浏览器打开HTML文档时,通常会创建一个window对象
- 如果文档定义了多个框架,浏览器会为每个框架创建window对象
离线存储
工作原理
原理:用户在线时,保存更新用户机器上的缓存文件;当用户离线时,可以正常访问离线储存站点或应用内容。HTML5的离线存储是基于一个新建的cache.manifest文件的缓存机制,通过这个文件上的解析清单离线存储资源,这些资源就会像cookie一样被存储了下来。之后当网络处于离线状态时,浏览器会把离线存储的数据进行页面展示。
使用:
在页面头部加上manifest属性
1
2
3
4
<html manifest = "cache.manifest">
...
</html>在项目中新建 manifest 文件,例如cache.manifest。在manifest文件的编写离线存储的资源。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16CACHE MANIFEST
//v0.11
//manifest文件一般由三个部分组成:CACHE\NETWORK\FALLBACK
CACHE:
//CACHE:表示需要离线存储的资源列表,由于包含manifest文件的页面将被自动离线存储,所以不需要把页面自身也列出来。
js/app.js
css/style.css
NETWORK:
//NETWORK:表示在它下面列出来的资源只有在在线的情况下才能访问,他们不会被离线存储,所以在离线情况下无法使用这些资源。不过,如果在CACHE和NETWORK中有一个相同的资源,那么这个资源还是会被离线存储,也就是说CACHE的优先级更高。
resourse/logo.png
FALLBACK:
//FALLBACK:表示如果访问第一个资源失败,那么就使用第二个资源来替换他,比如如果访问根目录下任何一个资源失败了,那么就去访问offline.html。
offline.html在 web 服务器配置正确的 MIME-type,即 text/cache-manifest
在离线状态时,操作window.applicationCache进行需求实现
浏览器对HTML5离线存储资源进行管理和加载的过程
- 在线的情况下,浏览器发现html头部有manifest属性,它会请求manifest文件,如果是第一次访问app,那么浏览器就会根据manifest文件的内容下载相应的资源并且进行离线存储。如果已经访问过app并且资源已经离线存储了,那么浏览器就会使用离线的资源加载页面,然后浏览器会对比新的manifest文件与旧的manifest文件,如果文件没有发生改变,就不做任何操作,如果文件改变了,那么就会重新下载文件中的资源并进行离线存储。
- 离线的情况下,浏览器就直接使用离线存储的资源。
使用的注意点
- 如果服务器对离线的资源进行了更新,那么必须更新manifest文件之后这些资源才能被浏览器重新下载,如果只是更新了资源而没有更新manifest文件的话,浏览器并不会重新下载资源,也就是说还是使用原来离线存储的资源。
- 对于manifest文件进行缓存的时候需要十分小心,因为可能出现一种情况就是你对manifest文件进行了更新,但是http的缓存规则告诉浏览器本地缓存的manifest文件还没过期,这个情况下浏览器还是使用原来的manifest文件,所以对于manifest文件最好不要设置缓存。
- 浏览器在下载manifest文件中的资源的时候,它会一次性下载所有资源,如果某个资源由于某种原因下载失败,那么这次的所有更新就算是失败的,浏览器还是会使用原来的资源。
- 在更新了资源之后,新的资源需要到下次再打开app才会生效,如果需要资源马上就能生效,那么可以使用
window.applicationCache.swapCache()
方法来使之生效,出现这种现象的原因是浏览器会先使用离线资源加载页面,然后再去检查manifest是否有更新,所以需要到下次打开页面才能生效。
本地存储方式
cookies、sessionStorage和localStorage的区别?
- cookie是网站为了标示用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)
- cookie数据始终在同源的http请求中携带(即使不需要),记会在浏览器和服务器间来回传递
sessionStorage
和localStorage
不会自动把数据发给服务器,仅在本地保存- 存储大小:
cookie
数据大小不能超过4ksessionStorage
和localStorage
虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大
- 有期时间:
localStorage
存储持久数据,浏览器关闭后数据不丢失除非主动删除数据sessionStorage
数据在当前浏览器窗口关闭后自动删除cookie
设置的cookie
过期时间之前一直有效,即使窗口或浏览器关闭
标签
页面导入样式时,使用link和@import有什么区别?
link
属于XHTML
标签,除了加载CSS
外,还能用于定义RSS
,定义rel
连接属性等作用;而@import
是CSS
提供的,只能用于加载CSS
。也就是说,link
是HTML范畴,@import
是CSS范畴。- 页面被加载时,
link
会同时被加载,而@import
引用的CSS
会等到页面被加载完再加载 link
是XHTML
标签,无兼容问题,而import
是CSS2.1
提出的,只在IE5
以上才能被识别。link
方式样式的权重高于@import
link
可以通过JS操作DOM动态引入样式表改变样式,而@import
不可以
行内元素和块级元素
- 行内元素的特点:1)在一行上显示 2)不能直接设置宽高 3)元素的宽和高就是内容撑开的宽高
- 块级元素的特点:1)独占一行 2)可以设置宽高 3)嵌套下,子块元素宽度(没有定义的情况下)和父块元素宽度默认一致
行内元素有哪些?块级元素有哪些? 空(void)元素有那些?
- 行内元素有:
a b span img input select strong
- 块级元素有:
div ul ol li dl dt dd h1 h2 h3 h4…p table form
- 常见的空元素:
<br> <hr> <img> <input> <link> <meta> <embed>
label的作用是什么?是怎么用的?
- label标签用来定义表单控件间的关系,当用户选择该标签时,浏览器会自动将焦点转到和标签相关的表单控件
- 使用方法1:
<label for="mobile">Number:</label>
<input type="text" id="mobile"/>
- 使用方法2:
<label>Date:<input type="text"/></label>
- 使用方法3:
<input type="checkbox" id="c1"/><label for="c1">记住我</label>
- label标签可以嵌套a标签,且点击a标签可以跳转
- 不要在label标签内部放置可交互的元素,例如anchors或buttons。这样会让用户更难触发与label相关联的表单输入元素。
- label标签只有两个属性:for(规定label绑定到哪个表单元素)、form(规定label字段所属的一个或多个表单)
title与h1的区别、b与strong的区别、i与em的区别?
title
属性没有明确意义只表示是个标题,h1
则表示层次明确的标题,对页面信息的抓取也有很大的影响strong
是标明重点内容,有语气加强的含义,使用阅读设备阅读网络时:会重读,而是展示强调内容;b
表示粗体。i
内容展示为斜体,语义上与普通文本无区别;em
表示斜体强调的文本,语义上也表示为斜体,不加粗文本。em
可以被设备识别,而i
不行。- 自然样式标签:
b
,i
,u
,s
,pre
- 语义样式标签:
strong
,em
,ins
,del
,code
- 应该准确使用语义样式标签, 但不能滥用。如果不能确定时,首选使用自然样式标签
<img>
的title
和alt
有什么区别
title
通常当鼠标滑动到元素上的时候显示alt
是<img>
的特有属性,是图片内容的等价描述,用于图片无法加载时显示、读屏器阅读图片。可提图片高可访问性,除了纯装饰图片外都必须设置有意义的值,搜索引擎会重点分析。
元素事件有哪些
- onblur:元素失去焦点时触发
- onfocus:元素聚焦时触发
- onsearch:用户向搜索域或文本搜索时触发
- onload:元素被载入
- onreset:表单元素被重置
- onchange:当域内容改变时
audio和vedio
属性
- currentTime:设置或返回视频播放的当前位置,设置该属性时,播放会跳跃到指定的位置
- duration:规定造成过渡效果需要花费的时间
- defaultPlaybackRate:设置或返回音频或者视频播放的默认速度
- playbackRate:设置或返回视频当前的播放速度
<meta>
标签的作用
- 表示支持响应式设计
- 支持正常的绘制和缩放
table常用的属性
- cellpadding:单元格边沿与其内容之间的空白
- cellspacing:单元格之间的空白
iframe
iframe的缺点?
- iframe的创建比一般的DOM元素慢了1-2个数量级。且iframe会阻塞主页面的Onload事件。
- 搜索引擎的检索程序无法解读这种页面,不利于SEO
- iframe和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载
- 使用
iframe
之前需要考虑这两个缺点。如果需要使用iframe
,最好是通过javascript
动态给iframe
添加src
属性值,这样可以绕开以上两个问题
iframe的优点
- 用来加载速度较慢的内容(如广告)
- 可以使脚本可以并行下载
- 可以实现跨子域通信
iframe使用场景
- 典型系统结构,左侧是功能树,右侧是常见table或表单等。为了将每个功能单独分离,使用iframe
- ajax上传文件
- 加载其他网站的内容,如广告
- 上传图片时,避免当前页刷新
- 跨域访问的时候可以用到iframe请求不同域名下的资源,与第三方域名下的页面共享cookie
页面
页面可见性(Page Visibility API) 可以有哪些用途?
- 通过 visibilityState 的值检测页面当前是否可见,以及打开网页的时间等;
- 在页面被切换到其他后台进程的时候,自动暂停音乐或视频的播放
- 当用户浏览其他页面,暂停网站首页幻灯自动播放
- 完成登陆后,无刷新自动同步其他页面的登录状态
如何在页面上实现一个圆形的可点击区域?
- map+area或者svg
- border-radius
- 纯js实现 需要求一个点在不在圆上简单算法、获取鼠标坐标等等
实现不使用 border 画出1px高的线,在不同浏览器的标准模式与怪异模式下都能保持一致的效果
1 | <div style="height:1px;overflow:hidden;background:red"></div> |
数据序列化技术
定义:
1 | 将内存对象转化成字节流的过程,它直接决定了数据解析效率以及模式演化能力 |
方法:
1 | - JSON数据格式 |
跨文档传输
定义:
1 | 网页文档之间相互接收和发送消息 |
特点:
1 | - 可以实现同域内和跨域的web页面之间的相互通信 |
获取焦点
定义:
1 | 输入框焦点:当鼠标在某个输入框中点击一下,输入框中出现光标,此时输入框获得了焦点 |
例子:
1 | a标签没有href属性的话获取不到焦点 |
跨域
例子:
1 | - web字体受浏览器跨域限制 |
3D
- 在Blink和webkit的浏览器中,某个元素具有3D或透视变换的CSS属性,会让浏览器创建单独的图层。
- 我们平常会使用left和top属性来修改元素的位置,但left和top会触发重布局,更好的方法是使用translate,这个不会触发回流,这是因为translate重新绘制了一个图层。
- 解决浏览器渲染的性能问题时,首要目标是要避免层的重绘和重排。
- 过多触发3D加速会导致严重的性能问题。
事件对象
DOM事件对象(符合W3C标准):
- preventDefault():取消默认事件
- stopImmediatePropagation():取消事件冒泡同时阻止当前节点上的事件处理程序被调用
- stopPropagation():取消事件冒泡,对当前节点无影响
IE事件对象
- cancelBubble():取消事件冒泡
- returnValue():取消事件默认行为
事件模型
- DOM0级模型。只支持冒泡,不支持捕获。同一个类型的事件只能绑定一次,希望为同一个元素绑定多个同类型事件的时候,后绑定的事件会覆盖之前的事件。
- IE事件模型。有事件处理和事件冒泡阶段。通过attachEvent来添加监听函数,可以添加多个监听函数,按顺序依次执行。
- DOM2级模型。有事件捕获、事件处理和事件冒泡三个阶段。第一阶段是事件捕获。捕获指事件从document一直向下传播到目标元素,依次检查经过的节点是否绑定了事件监听函数,如果有则执行。第二阶段是事件处理,执行目标元素绑定的监听事件。第三阶段是冒泡,当子元素(事件源)事件触发,事件会沿着包含关系,依次往上级传递,每一级都可以感知到事件,直到触发根元素(根源)。依次检查经过的节点是否绑定了事件监听函数,如果有则执行。这种模型通过addEventListener来添加监听函数,其中第三个参数可以指定事件是否在捕获阶段执行。
addEventListener的参数
第一个参数是事件名、第二个参数是事件处理函数、第三个参数用于指定事件处理的时期。当第三个参数为false的时候,表示在冒泡阶段进行事件处理;为true的时候,表示在事件捕获的时候处理。
事件委托
- 概念:通俗的讲就是把一个元素响应事件的函数委托到另一个元素。把一个或一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,当事件响应到需要绑定的元素上时,会通过冒泡机制触发它的外层元素的绑定事件,然后在外层元素上执行函数。
- 优点:1.只需要将同类元素的事件委托给父级或者更外层的元素,不需要给所有元素都绑定事件,减少了内存占用空间,提升了性能。2.动态新增的元素无需重新绑定事件。
- 缺点:1.事件委托基于冒泡,对于不冒泡的事件不支持。2.层级过多,冒泡过程中,可能会被某层阻止。
target与currentTarget的区别
- target为触发事件的某个具体对象
- currentTarget为绑定事件的对象
不支持冒泡的事件
- mouseenter
- mouseleave
- blur
- resize
- load
- focus
- unload
- 妈妈不让浪费昂
DOM常用API
- 创建新节点
- document.createDocumentFragment()//创建DOM片段
- document.createElement()//创建一个具体的元素
- document.createTextNode()//创建一个文本节点
- 添加、移除、替换、插入新节点
- document.appendChild(node)
- document.removeChild(node)
- document.replaceChild(new, old)
- document.insertBefore(new, old)
- 查询节点
3.1 查询某一节点
- document.getElementById(id)
- document.getElementsByName(‘test’)
- document.getElementsByTagName(‘input’)
- document.getElementsByClassName()
- document.querySelector(‘myClass’)//返回第一个类名为myClass的元素/标签元素
- document.querySelectorAll()
3.2 查询父节点
- curnode.parentElement
- curnode.parentNode
3.3 查询子节点
- curnode.children
- curnode.getElementsByTagName()
- curnode.getElementsByClassName()
- curnode.firstElementChild//第一个子元素
- curnode.lastElementChild//最后一个子元素
3.4 查询兄弟节点
- curnode.nextElementSibling//下一个兄弟节点
- curnode.previousElementSibling//上一个兄弟节点
- 属性操作
- curnode.attributes//返回值为{name, value}
- curnode.getAttribute(key)
- curnode.setAttribute(key, value)
- curnode.hasAttribute(key)
- curnode.removeAttribute(key)
- innerHTML \ outerHTML \ innerText \ outerText
- innerHTML:
<p>Text in DIV</p>
- outerHTML:
<div><p>…</p></div>
- innerText: Text in DIV
- outerText: Text in DIV
- innerText与outerText的区别:outerText赋值时会把标签一起赋值掉
浏览器渲染机制
渲染步骤
- 解析HTML,构建DOM树
- 解析CSS,生成CSSOM树
- 合并DOM树和CSSOM树,生成render渲染树
- 根据render渲染树进行布局
- 调用GPU对渲染树进行绘制,合成图层,显示在屏幕上
注意:1.构建CSSOM树的时候,会阻塞渲染,直到CSSOM树构建完成。2.HTML解析到script标签的时候,会暂停构建DOM树,完成后才会从暂停的地方重新开始。
解析HTML标签,构建DOM树
在这个阶段,引擎开始解析html,解析出来的结果会成为一棵dom树(包含全节点,包括隐藏的节点和<head>
标签)
当解析器开始解析script
标签时,会发生:
- html解析器停止解析
- 如果是外部脚本,就从外部网络获取脚本代码
- 将控制权交给JS引擎,执行JS代码
- 恢复HTML解析器的控制权
解析CSS标签,构建CSSOM树
把DOM和CSSOM组合成渲染树
在这个阶段会让原本的DOM树和CSSOM树相结合,成为渲染树render tree。需要注意的是:render tree不会将所有原本的DOM树全部构建出来,一些不需要显示的元素则不会被构建到渲染树中。例如,不会添加head
标签元素;不会添加样式中有display: none
的元素。
在渲染树的基础上进行布局,计算每个节点的几何结构
布局(layout):定位坐标和大小,是否换行,各种position, overflow, z-index属性。当js脚本中存在修改会影响dom的布局时,会产生回流(Reflow),回流会让浏览器重新执行第四步和第五步的操作。
调用GPU绘制,合成图层,显示在屏幕上
将渲染树的各个节点绘制到屏幕上,这一步被称为绘制painting。当js脚本中存在修改会影响dom样式,但不影响布局时,会产生重绘(Repaint),重绘会让浏览器重新执行第五步的操作。
优化浏览器渲染性能
- 在合适的时机选择使用Load或者DOMContentLoaded
- Load事件触发代表页面中的DOM、CSS、JS、图片已经全部加载完成
- DOMContentLoaded事件触发代表初始的HTML被完全加载和解析,不需要等待CSS、JS、图片加载。
- 使用不同的图层渲染页面
- 一般来说,可以把普通文档流看成一个图层。特定的属性可以生成一个新的图层。不同的图层渲染互不影响,所以对于某些频繁需要渲染的建议单独生成一个新图层,提高性能。但也不能生成过多的图层,会引起反作用。
- 通过优化重绘和重排来减少相应的页面渲染时间
JS执行会阻塞DOM树的解析和渲染,CSS加载不会阻塞DOM的解析,CSS加载会阻塞DOM的渲染。
页面白屏怎么排查定位问题(客户端、浏览器端、服务器端)
- 确保网络连接通畅
- 查看网络URL地址是否输入有误。a.无效请求。当发送的请求无效时,服务器不会返回相应的内容,导致页面无法正常展示,最终以空白页的形式展示。b.错误路径。服务器无法返回正常的请求资源,最终导致页面无法正常显示。
- 查看控制台是否有报错信息。a.JS报错。b.资源加载顺序。当网速慢较慢,下载相关资源很慢,就会出现短暂白屏。
- 查看接口访问是否有请求。a.服务器异常报502错误的时候会出现空白页。b.DNS无法解析,会导致浏览器白屏。
window.requestAnimationFrame
requestAnimationFrame的功能与setTimeout类似。不同之处在于,setTimeout必须指定多长时间再执行,而requestAnimationFrame则是推迟到浏览器下一次重绘时就执行回调。重绘通常是16ms一次,因为大多数屏幕渲染的时间间隔是每秒60帧。如果某个函数会改变网页布局,一般就放在window.requestAnimationFrame()里面执行,这样可以节省系统资源。
实例
- 用JS实现一个无限循环动画
1 | <!--使用html实现--> |
1 | <!--使用requestAnimationFrame实现--> |
浏览器事件循环
事件循环的概念
在程序中设置两个线程:一个负责程序本身的运行,称为主线程;另一个负责主线程与其他进程的通信,称为消息线程。
事件循环可以简单描述为:
- 函数入栈,当栈中执行到异步任务的时候,就把他丢给webAPIs,接着继续执行同步任务,直到栈为空;
- 在此期间webAPIs完成这个事件,把回调函数放入回调队列中等待;
- 当执行栈为空的时候,事件循环就把回调队列中的任务放入执行栈中,回到步骤一执行。
上述步骤中的webAPIs可能是DOM、AJAX、Timeout等。
浏览器中常驻的线程
- JS引擎线程
- GUI渲染线程
- 事件触发线程
window事件
onbeforeunload:当浏览器窗口关闭或者刷新时触发