提到 HTML 标签,前端工程师会非常熟悉,因为在开发页面时经常使用,HTML 都是最基础的内容。
但对于一些基本知识,我们不能完整的描述出来,例如:
- 浏览器是怎么处理 HTML 内容的,以及在这个过程中我们可以进行怎样的处理来提升网页的性能,从而提升用户的体验。
- 一些非常重要却容易被忽视的标签,这些标签大多数用在页面头部 head 标签内,虽然对用户不可见,但有着很好的效果。
html结构
- <html>元素是页面的根元素,它描述完整的网页;
- <head>元素包含了我们想包含在 HTML 页面中,但不希望显示在网页里的内容;
- <body>元素包含了我们访问页面时所有显示在页面上的内容,是用户最终能看到的内容。
浏览器是如何加载页面呢?
浏览器在加载页面的时候会用到 GUI 渲染线程和 JavaScript 引擎线程,其中,GUI 渲染线程负责渲染浏览器界面 HTML 元素,JavaScript 引擎线程主要负责处理 JavaScript 脚本程序。
由于 JavaScript 在执行过程中还可能会改动界面结构和样式,因此它们之间被设计为互斥的关系。也就是说,当 JavaScript 引擎执行时,GUI 线程会被挂起。
网页加载流程
- 当我们打开网页的时候,浏览器会从服务器中获取到 HTML 内容。
- 浏览器获取到 HTML 内容后,就开始从上到下解析 HTML 的元素。
- <head>元素内容会先被解析,此时浏览器还没开始渲染页面。
- 当浏览器解析到这里时(步骤 3),会暂停解析并下载 JavaScript 脚本。
- 当 JavaScript 脚本下载完成后,浏览器的控制权转交给 JavaScript 引擎。当脚本执行完成后,控制权会交回给渲染引擎,渲染引擎继续往下解析 HTML 页面。
- 此时元素内容开始被解析,浏览器开始渲染页面。
在这个过程中,我们看到<head>中放置的<script>元素会阻塞页面的渲染过程:把 JavaScript 放在<head>里,意味着必须把所有 JavaScript 代码都下载、解析和解释完成后,才能开始渲染页面。
到这里,我们就明白了:如果外部脚本加载时间很长(比如一直无法完成下载),就会造成网页长时间失去响应,浏览器就会呈现“假死”状态,用户体验会变得很糟糕。
性能优化
性能问题无外乎两方面原因:渲染速度慢、请求时间长。
script 标签:调整加载顺序提升渲染速度
由于浏览器的底层运行机制,渲染引擎在解析 HTML 时,若遇到 script 标签引用文件,则会暂停解析过程,同时通知网络线程加载文件,文件加载后会切换至 JavaScript 引擎来执行对应代码,代码执行完成之后切换至渲染引擎继续渲染页面。
为了减少这些时间损耗,可以借助 script 标签的 3 个属性来实现
- async 属性。立即请求文件,但不阻塞渲染引擎,而是文件加载完毕后阻塞渲染引擎并立即执行文件内容。
- defer 属性。立即请求文件,但不阻塞渲染引擎,等到解析完 HTML 之后再执行文件内容。
- HTML5 标准 type 属性,对应值为“module”。让浏览器按照 ECMA Script 6 标准将文件当作模块进行解析,默认阻塞效果同 defer,也可以配合 async 在请求完成后立即执行。
具体效果可以参看下图:
绿色的线表示执行解析 HTML ,蓝色的线表示请求文件,红色的线表示执行文件。
link 标签:通过预处理提升渲染速度
- dns-prefetch。当 link 标签的 rel 属性值为“dns-prefetch”时,浏览器会对某个域名预先进行 DNS 解析并缓存。这样,当浏览器在请求同域名资源的时候,能省去从域名查询 IP 的过程,从而减少时间损耗。
- preconnect。让浏览器在一个 HTTP 请求正式发给服务器前预先执行一些操作,这包括 DNS 解析、TLS 协商、TCP 握手,通过消除往返延迟来为用户节省时间。
- prefetch/preload。两个值都是让浏览器预先下载并缓存某个资源,但不同的是,prefetch 可能会在浏览器忙时被忽略,而 preload 则是一定会被预先下载。
- prerender。浏览器不仅会加载资源,还会解析执行页面,进行预渲染。
上图为浏览器获取资源文件的流程
link 标签:减少重复
有时候为了用户访问方便或者出于历史原因,对于同一个页面会有多个网址,又或者存在某些重定向页面,比如:
- https://lagou.com/a.html
- https://lagou.com/detail?id=“abcd”
那么在这些页面中可以这样设置:
<link href="https://lagou.com/a.html" rel="canonical">
这样可以让搜索引擎避免花费时间抓取重复网页。不过需要注意的是,它还有个限制条件,那就是指向的网站不允许跨域。
meta 标签:提取关键信息
通过 meta 标签可以设置页面的描述信息,从而让搜索引擎更好地展示搜索结果。
例如,在百度中搜索“拉勾”,就会发现网站的描述信息,这些描述信息就是通过 meta 标签专门为搜索引擎设置的,目的是方便用户预览搜索到的结果
对应代码如下:
<meta content="拉勾,拉勾网,拉勾招聘,拉钩, 拉钩网 ,互联网招聘,拉勾互联网招聘, 移动互联网招聘, 垂直互联网招聘, 微信招聘, 微博招聘, 拉勾官网, 拉勾百科,跳槽, 高薪职位, 互联网圈子, IT招聘, 职场招聘, 猎头招聘,O2O招聘, LBS招聘, 社交招聘, 校园招聘, 校招,社会招聘,社招" name="keywords">
总结:通过本文针对页面加载过程及加载过程的性能优化应该有一些了解,很多时候,我们对一些基础内容也都需要不定期地进行复习。一些原本认为已经固化的认知,在重新学习的过程中,或许你可以得到新的理解。