浏览器中的页面
Chrome 开发者工具
名称 | 描述 |
---|---|
Elements | 可以查看DOM结构、编辑CSS样式,用于测试页面布局和设计页面。 |
Console | 可以看成是 javascript Shell,能执行 Javascript脚本。通过 Console还能和页面中的 javascript对象交互。 |
Source | 1. 查看Wcb应用加载的所有文件 2. 编辑CSS和 Javascript文件内容 3. 将打乱的CSS文件或者 Javascript文件格式化; 4. 支持 Javascript的调试功能 5. 设置工作区,将更改的文件保存到本地文件夹中。 |
NetWork | 展示了页面中所有的请求内容列表、能查看每项请求的请求行、请求头、请求体、时间线以及网络请求瀑布图等信息。 |
Performance | 记录和查看Wcb应用生命周期内的各种事件,并用来分析在执行过程中一些影响性能的要点。 |
Memory | 用来查看运行过程中的 Javascript 占用堆内存情况,追踪是否存在内存泄的情况等。 |
Application | 查看Wcb应用的数据存储情况 PWA的基础数据; Indexeddb; Web SQL;本地和会话存储: Cookie;应用程序缓存;图像;字体和样式表等。 |
Security | 显示当前页面一些基础的安全信息。 |
Audits | 会对当前网页进行网络利用情况、网页性能方面的诊断,并给出一些优化建议。 |
Layers | 展示一些渲染过程中分层的基础信息。 |
NetWork
DOM 树
在渲染引擎内部,有一个叫HTML解析器(HTMLParser)的模块,负责将HTML字节流转换为DOM结构。
HTML 文档边加载边解析。
碰到 script 标签时,会先去执行 js ,js 文件下载也会阻塞 DOM 的解析。
script async
下载完后会立即执行,defer
会在文档解析后,DOMContentLoaded
前执行,所以会阻塞 DOMContentLoaded
样式文件会阻塞 css 文件。
<html>
<body>
<div>1</div>
<script>
let div1 = document.getElementsByTagName('div')[0]
div1.innerText = 'time.geekbang'
let div2 = document.getElementsByTagName('div')[1]
div2.innerText = 'time.geekbang.com'
</script>
<div>test</div>
</body>
</html>
渲染流水线
通常情况下的瓶颈主要体现在下载CSS文件、下载JavaScript文件和执行JavaScript
优化策略
- 通过内联JavaScript、内联CSS来移除这两种类型的文件下载,这样获取到HTML文件之后就可以直接开始渲染流程了。
- 但并不是所有的场合都适合内联,那么还可以尽量减少文件大小,比如通过webpack等工具移除一些不必要的注释,并压缩JavaScript文件。
- 还可以将一些不需要在解析HTML阶段使用的JavaScript标记上async或者defer。
- 对于大的CSS文件,可以通过媒体查询属性,将其拆分为多个不同用途的CSS文件,这样只有在特定的场景下才会加载特定的CSS文件。
分层和合成机制
页面性能
加载阶段
总的优化原则就是减少关键资源个数,降低关键资源大小,降低关键资源的RTT次数。
交互阶段
减少 JS 执行时间
避免强制同步布局
由于要获取到offsetHeight,但是此时的offsetHeight还是老的数据,所以需要立即执行布局操作
function foo() {
let main_div, new_node // 省略........
document.getElementById("mian_div").appendChild(new_node);
console.log(main_div.offsetHeight)
}改成如下
function foo() {
let main_div // 省略........
console.log(main_div.offsetHeight)
let new_node // 省略........
document.getElementById("mian_div").appendChild(new_node);
}避免布局抖动
指在一次JavaScript执行过程中,多次执行强制布局和抖动操作
合理利用 CSS 合成动画,能让 css 处理动画尽量让 css 处理
避免频繁的垃圾回收
虚拟 DOM
DOM 的缺陷
利用类似 document.body.appendChild(node)
会触发重排。
不当的 DOM 操作还会引起强制同步布局和布局抖动。
虚拟 DOM
双缓存
将计算的中间结果放到一个缓冲区,等全部计算完后一次性复制到显示缓冲区
MVC 模式
渐进式网页应用 PWA
Progressive Web App, 字面意思就是“渐进式 + web应用”
渐进式增强Web的优势,并通过技术手段渐进式缩短和本地应用或者小程序的距离
web 应用 vs 本地应用
- web 应用缺少离线使用能力,离线或弱网几乎无法使用
- web 应用缺少消息推送能力
- web 应用缺少一级入口
PWA 提供了两种解决方案
- 引入 service worker 解决离线和推送问题
- 引入 mainfest.json 解决一级入口问题
Service Worker
主要思想是在页面和网络之间增加一个拦截器,用来缓存和拦截请求
- 架构:Service Worker是运行在浏览器进程中的
- 消息推送:也是基于Service Worker来实现的
- 安全:要使站点支持Service Worker,首先必要的一步就是要将站点升级到HTTPS
WebComponent
WebComponent是一套技术的组合,具体涉及到了Custom elements(自定义元素)、Shadow DOM(影子DOM)**和**HTML templates(HTML模板)
- 查找模板内容;
- 创建影子DOM;
- 再将模板添加到影子DOM上。