您的位置:首页 > 其它

奇舞-关键渲染路径性能优化-笔记

2018-03-06 18:24 176 查看
内容

浏览器渲染原理

资源对渲染的影响

优化关键渲染路径

浏览器渲染原理



DOM



Timeline



录制时需注意

禁用缓存,以便测试首次浏览性能



关闭Chrome 扩展 或使用隐身模式

模式真实网络情况



Chrome Canary

总结TImeline

1:控制条

开始记录, 停止记录

配置记录期间捕获的信息

2: 总揽

页面性能高级汇总

3:火焰图

CPU 堆叠追踪的可视化

4:详情

每个CPU 任务的详细报告



增量构建

浏览器无需等待html 加载完毕,便可开始解析DOM

自己动手

使用 performance 工具 分析自己常逛的网站。找到主线程中构建DOM所在的步骤

总结

描述浏览器是如何构建DOM的

CSSOM







RenderTree

RenderTree 包含了渲染网页所需要的节点

无需渲染的节点不会被添加到RenderTree中。

思考Lvisitilty:hidden 的节点,是否会被添加到RenderTree?

Recalculate Style : 构建 RenderTree



Layout :计算渲染书节点的位置和大小

Viewport

device-width 为浏览器的理想视口

在移动端 ,如果不设置viewpost 宽度为理想视口,viewport宽度通常为,980px,这会导致文字很小,我们需要手动放大阅读

思考 :

哪些操作会触发Layout

屏幕旋转

浏览器视口改变

与大小位置相关的css属性改变

https://csstriggers.com/

总结

试着画出浏览器渲染过程

并描述每一步执行的工作

构建DOM

构建过程

cha
102d0
racter token node DOM

增量构建

构建CSSOM

构建过程

charactor token node CSSOM

选择器越复杂,匹配用的时间越多

构建RenderTree

RenderTree 包含所有需要呈现在页面上的节点信息

display:none 的元素不会被添加到RenderTree 汇总,因为不需要本渲染

visibility:hidden 的元素会被添加到RenderTree中,因为它虽然不可见,但是会占有位子

Layout

计算需要渲染的节点的大小和位置

节点位置和大小是给予viewport计算的

在移动端通常将viewport设为浏览器推荐的理想适口,以保证字体显示大小易于阅读

旋转屏幕,修改浏览器大小,修改位置大小相关的css属性都有可能触发Layout

Paint

根基background,border, box-shadow等样式,将Layout生成区域填充为最终将显示在屏幕上的像素

资源对渲染的影响

资源

css

js

font

img

思考

浏览器会在何时渲染页面

加载完DOM立即开始渲染

加载完DOM和CSSOM

css阻塞初次渲染(有待测试)

‘index.css’>

- 通过以上两种方式定义css,均会阻塞初次渲染

- 浏览器会在解析完css后,再进行渲染,这是为了防止样式突变带来饿抖动

- 不管css 出现文档中的那个位置,都会阻塞整个文档的初次渲染

- 通过link 标签引入的css阻塞的时间可能更长,因为加载它需要一个网络来回时间

dedia query

<link rel='sty;esheet' href='index_print.css' media='print'>


此样式表仍会加载

当浏览器环境不匹配媒体查询时,改样式表不会阻塞渲染

我们可针对不同媒体环境拆分css文件,并为link标签添加媒体查询,避免为了加载非关键css资源,而阻塞初次渲染。

通过documnt.write 添加link

<script>
document.write('<link ref='stylesheet' href='inex.css' />')
</script>


通过DOM API 添加link

var style = document.createElement(‘link’)

style.rel = ‘stylesheet’;

style.href = ‘index.css’;

document.head.appendChild(style)

不会阻塞初次渲染

preload

<link / rel='preloa' href='index_print.css' as=style onloa='this.rel=stylesheet'>


fel 不是stylesheet,因此不会阻塞渲染

preloa 是resoure hint 规范中定义中一个功能

resource hint 通过告知浏览器提前 建立链接或加载资源,以提高资源加载的速度

浏览器遇到标记为preloa的link 时,会开始加载它

当onload 时间发生时,将rel改为stylesheet 即可应用此样式

loadCSS.js

CSS preload polyfill

让我们可以使用preloa 语法异步加载css

原理是通过DOM API 插入样式资源



思考

<body>
<p>hello</p>
// 这个脚本会加载10秒左右
<script src='slowscript.js'></script>
<p>world</p>
</body>
//显示情况是 立即显示hello 10秒后显示world


javascript 阻塞HTML parser

// inline js
<script> </script>
// external js
<script src='somescript'></script>


通过以上两种方式引入js脚本均会阻塞html parser,因而会阻塞出现在脚本后面的HTML 标记的渲染

外部script 阻塞时间一般更长,以为可能包含了一个网络来回时间

javascript 可以通过document.write 修改HTML 文档流,因此在执行js时, 浏览器会暂停解析DOM的工作

<html>
<head>
//p {color: green}
<link rel='stylesheet' href = 'index.css'>
</head>
<body>
<p>hello wrold</p>
<script>
let p = document.querySelector('p');
let color = window.getComputedStyle(p).color
console.log(color)
</script>
</body>
</html>

//如果HTML Parse 解析到<script></script> 标签时,样式仍未加载完成,会发生什么? 最后打印的颜色是多少?


CSS阻塞JS

//inline js
<script> //app logics here <script>

//external js

<script src='somescript.js'></script>


通过以上两种方式引入的JS均会被CSS 阻塞

由于这些javascript 可能会读取或修改CSSOM,因此需要等待CSSOM 构造完成后,它们才会执行

<html>
<head>
<script src='index.js'></script>
<script> src='tongji.js' </script>
</head>
<body>
</body>
</html>
//这两个js文件浏览器会同时加载


Preloa

当HTML parse 被脚本阻塞时,Parser 虽然停止构建DOM,但仍会识别该脚本后面的资源,并提前加载。

注意:这里是指的浏览器资源加载策略,而非前文提到的resource hint 标准中的preload

使用defer延迟脚本执行

<script src=='index.css' defer><script>


当script 标签拥有defer 属性时,该脚本会被退到整个HTML文档解析完成后,再开始执行。

被defer 脚本, 在执行时会严格按照HTML文档中出现的顺序位置

延迟脚本方法对比

使用的的方法,可提早脚本资源加载

由于HTML Parser 是增量解析 HTML文档的,因此将脚本放在head中,可以提早浏览器对脚本文件的加载。

使用async 异步加载脚本

当script 标签拥有async 属性时,该脚本不会再阻塞html parser 且不会被css 阻塞

脚本只要加载完成,便可开始执行

被async 的脚本,在执行时会 不会按照在html文档中出现的顺序文档执行

async 适用于无依赖的独立资源





<link href='https://fints.googleapis.com/css...'>
<style type='text/css' media='screen. print'>
h1 {
font-family:'Roboto'
}
//加载完HTML 文档后, 浏览器会如何工作?
// 等字体文件加载完成后显示内容
</style>


font 阻塞内容渲染

浏览器为了避免FOUT(Flash Of Unstyled Text) 会尽量等字体加载完成后, 再显示应用了该字体的内容

只有当字体超过一段时间仍未加载成功时, 浏览器才会降级使用系统字体,每个浏览器都规定了自己的超时时间

但这也带来了FOIT(falst Of invisible Text) 问题, 内容无法尽快被展示,导致空白。

异步加载字体

通过异步加载css 。即可避免字体阻塞渲染

<body>
<img src='smile.png'>
<p>hello world</p>
</body>

//图片资源是否会阻塞首次渲染  答案是不会


优化关键渲染路径

优化目标

将一下指标压缩到最低

关键资源数

关键资源体积

关键资源网络来回数





勿盲目内敛资源

若启用HTTP2 ,则无需内联资源

若资源被多个页面共享,则无法充分利用缓存, 导致重复下载

结合内联与缓存

<html>
<head>
<style></style>
<link rel='prefetch' href = 'index.css'></link>
</head>

<body>
<p> hello world</p>
</body>
</html>


当用户首次访问时,返回内联资源,并通过prefetch,请求并缓存资源;

在用户首次访问时, 通过cookie 表示用户已加载缓存

当下次访问时, 若cookie 标示已经缓存过,则只返回外部资源标记

缓存策略可灵活选择

减少内容大小

避免返回无用内容

针对特定语言的源码压缩

通过文本压缩

图片压缩



关键呈现路径优化思路

延迟或异步加载资源, 从而减少关键资源数量

减少资源大小

针对关键资源, 减少网络请求时间

学习资源

关键资源呈现路径, by Chrome Developer

使用Chrome Devtool 检查性能

性能优化相关资源汇总
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: