本文参考:html+CSS+js解析全过程。
主流程
从浏览器请求html文件,到屏幕上出现渲染的实际像素等,可以分为以下部分:
解析HTML文件的细节
DOMContentLoaded 与 load 事件
关于阻塞/非阻塞
其他注意事项
<!-- 设定页面使用的字符集 -->
<meta charset="utf-8">
<meta
http-equiv="Content-Type"
content="text/html; charset=UTF-8"
>
<!-- 优先使用 IE 最新版本和 Chrome -->
<meta
http-equiv="X-UA-Compatible"
content="IE=edge,chrome=1"
>
<!-- 国产360浏览器默认采用高速模式渲染页面 -->
<meta name="renderer" content="webkit">
<meta
name="viewport"
content="
width=device-width,
initial-scale=1,
user-scalable=no
"
>
<!-- 禁止设备检测手机号和邮箱 -->
<meta
name="format-detection"
content="telephone=no,email=no"
>
<!-- QQ强制全屏 -->
<meta name="x5-fullscreen" content="true">
<!-- UC强制全屏 -->
<meta name="full-screen" content="yes">
<!-- uc强制竖屏 -->
<meta name="screen-orientation" content="portrait">
<!-- QQ强制竖屏 -->
<meta name="x5-orientation" content="portrait">
<!-- UC应用模式 -->
<meta name="browsermode" content="application">
<!-- QQ应用模式 -->
<meta name="x5-page-mode" content="app">
<!-- windows phone 点击无高光 -->
<meta name="msapplication-tap-highlight" content="no">
<!--
针对手持设备优化,主要是针对一些老的不识别viewport的浏览器,
比如黑莓
-->
<meta name="HandheldFriendly" content="true">
<!-- 设置 web 应用在 iOS 设备中是否启用全屏模式 -->
<meta name="apple-mobile-web-app-capable" content="yes">
<!--
设置 iOS 设备中 web 应用的状态栏样式。
只在用 `apple-apple-mobile-web-app-capable`
+ 开启全局模式后生效
-->
<meta
name="apple-mobile-web-app-status-bar-style"
content="black"
>
<!-- 启用/禁用 iOS Safari 浏览器中自动检测手机号的功能 -->
<meta name="format-detection" content="telephone=no">
<!--
用于设定禁止浏览器从本机的缓存中读取页面内容。
设定后一旦离开网页就无法从缓冲中再读取
-->
<meta http-equiv="pragma" content="no-cache">
<!-- 禁用缓存(再次访问需重新下载页面) -->
<meta http-equiv="cache-control" content="no-cache">
<!--
可以用于设定网页的到期时间。
一旦网页过期,必须到服务器上重新传输
-->
<meta http-equiv="expires" content="0">
<!-- 停留 2 秒钟后自动刷新到 URL 网址 -->
<meta
http-equiv="Refresh"
content="2;URL=http://www.example.com/"
>
<!-- 用于 SEO,其中 description 的内容应不超过 150 个字符 -->
<meta
http-equiv="keywords"
content="keyword1,keyword2,keyword3"
>
<meta
http-equiv="description"
content="This is my page"
>
<!--
强制页面在当前窗口以独立页面显示,
用来防止别人在 iframe 里调用自己的页面
-->
<meta http-equiv="Window-target" content="_top">
本文参考资料如下:
script 标签用于嵌入可执行脚本或数据,一般用于嵌入一段 JavaScript 脚本,或者指向一个 JavaScript 文件。script 标签也可用于其他语言,比如 WebGL 的 GLSL shader 编程语言脚本,或者 JSON 数据等。
用 script 标签载入数据
注意,如果用 script 标签来载入数据(而非脚本):
src
、async
、nomodule
、defer
、crossorigin
、integrity
、referrerpolicy
、fetchpriority
。比如这样是可以的:
<script id="data" type="application/json">
{"a": "123"}
</script>
<script>
const jsonData = JSON.stringify(
document.querySelector('#data').textContent
)
</script>
但是下面这样是不可以的:
<!-- 这样直接通过 src 属性去指向一个数据文件的方式是不可以的 -->
<script
id="data"
type="application/json"
src="https://bla.bla.com/blabla.json">
</script>
模板语言
script 标签有个特点是其中的内容不会直接展现在页面上,所以有很多前端模板语言会使用 script 标签来存放 html 模板。我们可以自己写个简单的,像下面这样:
<div class="userInfo"></div>
<script id="template" type="text/template">
<div>
<div class="name">{{ userName }}</div>
<div class="address">{{ userAddress }}</div>
</div>
</script>
<script type="application/javascript">
const templateContent = document
.querySelector('#template')
.textContent
const templateData = {
userName: 'name',
address: 'address'
}
// 一般模版语言的渲染函数实际干的内容类似下面这样
document
.querySelector('.userInfo')
.innerHTML = templateContent
.replace(/\{\{ userName \}\}/m, templateData.userName)
.replate(/\{\{ address \}\}/m, templateData.address)
</script>
<script defer>、<script async> 脚本的下载、解析动作与 HTML 解析的时序关系
从下图可以看书,除了 <script> 会暂停 HTML 的解析,其他比如 <script defer>、<script async>、<script type="module"> 脚本的下载与 HTML 的解析都是并行不会暂停 HTML 的解析的。
<script async>:
<script defer>: