资讯专栏INFORMATION COLUMN

优化关键渲染路径

Integ / 2602人阅读

摘要:三种渲染流程实际场景下,大概会有三种常见的渲染流程注意和步骤是可避免的优化浏览器会在和加载完开始渲染页面。优化避免阻塞解析器通过以上两种方式引入均会阻塞,因而会阻塞出现在脚本后面的标记的渲染。

浏览器渲染原理


浏览器渲染流程

JavaScript

JavaScript实现动画效果,DOM元素操作等。

CSSOM

确定每个DOM元素应该应用什么CSS规则。

注意: CSS选择器越详细,匹配工作越多,匹配节点越慢。

RenderTree(渲染树)

RenderTree包含了渲染网页所需的节点, 无需渲染的节点不会被添加到RenderTree中。 如:,display: none的节点

注意:因为设置了visibility:hidden的元素虽不可见,但仍然占有空间,仍会被添加到RenderTree。

Layout(布局)

计算每个DOM元素在最终屏幕上显示的大小和位置。由于web页面的元素布局是相对的,所以其中任意一个元素的位置发生变化,都会联动的引起其他元素发生变化,这个过程叫reflow。

注意:影响web性能的一个重要的问题就是repaint和reflow。

触发Layout

屏幕旋转

浏览器视窗改变

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

Paint(绘制)

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

Composite(渲染层合并)

按照合理的顺序合并图层然后显示到屏幕上。

三种渲染流程

实际场景下,大概会有三种常见的渲染流程:

JavaScript -> CSS -> Layout -> Paint -> Composite

JavaScript -> CSS -> Paint -> Composite

JavaScript -> CSS -> Composite

注意:Layout和Paint步骤是可避免的

优化CSS

浏览器会在DOM和CSSOM加载完开始渲染页面。

避免CSS阻塞初次渲染

通过以上两种方式定义的CSS,均会阻塞初次渲染。浏览器会在解析完CSS后,再进行渲染。这是为了防止样式突变带来的抖动。通过link标签引入的CSS阻塞的时间可能更长,因为加载它需要一个网络来回时间

media query

此样式表仍会加载。当浏览器环境不匹配媒体查询条件时,该样式表不会阻塞渲染。我们可针对不同媒体环境拆分CSS文件,并为link标签添加媒体查询,避免为了加载非关键CSS资源,而阻塞初次渲染

通过DOM API添加link
var style = document.createElement("link");
style.rel = "stylesheet";
style.href = "index.css";
document.head.appendChild(style);

该方法不会阻塞初次渲染。

preload

rel不是stylesheet,因此不会阻塞渲染。preload是resoure hint规范中定义的一个功能,resource hint通过告知浏览器提前建立连接或加载资源,以提高资源加载的速度。浏览器遇到遇到标记为preload的link时,会开始加载,当onload事件发生时,将rel改为stylesheet,即可应用此样式。

总结
引入CSS资源的方法 是否阻塞初次渲染
通过document.write写入以上标签
通过DOM API插入HTMLLinkElement对象
使用preload方式载入CSS
为link添加media query 当媒体查询不匹配时,不会阻塞
减少需要执行样式计算的元素个数

由于浏览器的优化,现代浏览器的样式计算直接对目标元素执行,而不是对整个页面执行,所以我们应该尽可能减少需要执行样式计算的元素的个数。

JavaScript优化 避免Javascript阻塞HTML Parser(解析器)
<-- inline js -->


<-- external js -->

通过以上两种方式引入js均会阻塞HTML parser,因而会阻塞出现在脚本后面的HTML标记的渲染。而外部script阻塞的时间一般更长,因为可能包含了一个网络来回时间。

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

CSS阻塞JS
<-- inline js -->


<-- external js -->

通过以上两种方式引入的JS均会被CSS阻塞,由于这些Javascript可能会读取或修改CSSOM,因此需等待CSSOM构造完成后,它们才能执行

将资源放到文档底部,延迟js执行

  
  
    

世界上最美丽的语言是什么?

使用defer延迟脚本执行

  
    
    
    
    
  
  
    

世界上最美丽的语言是什么?

当script标签拥有defer属性时,该脚本会被推迟到整个HTML文档解析完后,再开始执行。被defer的脚本,在执行时会严格按照在HTML文档中出现的顺序执行

注意: 使用defer时,浏览器会保证脚本按照在文档中出现的顺序执行

使用async异步加载脚本

  
    
    
    
    
  
  
    

Hello World

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

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

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

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

总结
引入JS资源的方法 是否阻塞文档内容初次渲染
在head中引入外部脚本或内联脚本
将脚本放到body底部
为脚本添加defer属性
为脚本添加async属性
用requestAnimationFrame代替setTimeout或setInterval

setTimeout(callback)和setInterval(callback)无法保证callback函数的执行时机,很可能在帧结束的时候执行,从而导致丢帧。requestAnimationFrame(callback)可以保证callback函数在每帧动画开始的时候执行。

帧丢失

用Web Worker去处理耗时的JS代码

JavaScript代码运行在浏览器的主线程上,与此同时,浏览器的主线程还负责样式计算、布局、绘制的工作,如果JavaScript代码运行时间过长,就会阻塞其他渲染工作,很可能会导致丢帧。

每帧的渲染应该在16ms内完成,但在动画过程中,由于已经被占用了不少时间,所以JavaScript代码运行耗时应该控制在3-4毫秒。
如果真的有特别耗时且不操作DOM元素的纯计算工作,可以考虑放到Web Workers中执行。

var dataSortWorker = new Worker("sort-worker.js");

dataSortWorker.postMesssage(dataToSort);

// 主线程不受Web Workers线程干扰
dataSortWorker.addEventListener("message", function(evt) {
    var sortedData = e.data;

    // Web Workers线程执行结束
    // ...
});
用多个frame去处理DOM元素的更新

由于Web Workers不能操作DOM元素的限制,所以只能做一些纯计算的工作,对于很多需要操作DOM元素的逻辑,可以考虑分步处理,把任务分为若干个小任务,每个任务都放到requestAnimationFrame中回调执行。

var taskList = breakBigTaskIntoMicroTasks(monsterTaskList);

requestAnimationFrame(processTaskList);

function processTaskList(taskStartTime) {
    var nextTask = taskList.pop();

    // 执行小任务
    processTask(nextTask);

    if (taskList.length > 0) {
        requestAnimationFrame(processTaskList);
    }
}
Layout优化 避免触发布局

当修改了元素的属性之后,浏览器将会检查为了使这个修改生效是否需要重新计算布局以及更新渲染树,对于DOM元素的“几何属性”修改,比如width/height/left/top等,都需要重新计算布局。

使用flexbox替代老的布局模型

老的布局模型以相对/绝对/浮动的方式将元素定位到屏幕上。Floxbox布局模型用流式布局的方式将元素定位到屏幕上。
通过一个小实验可以看出两种布局模型的性能差距,同样对1300个元素布局,浮动布局耗时14.3ms,Flexbox布局耗时3.5ms

其他优化 Font Font阻塞内容渲染

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

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

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/83820.html

相关文章

  • 简说 优化关键渲染路径

    摘要:当解析被阻止时,这里,和会同时下载,所以关键路径长度仍为如何缩短关键呈现路径长度浏览器会有并行加载资源数的限制,如果网页很大,会需要来回多次获取资源。所以要根据情况合理控制文件资源大小参考优达的网站性能优化 回顾 关键渲染路径 showImg(https://segmentfault.com/img/bVKDWG?w=319&h=599); 简说浏览器渲染--关键渲染路径 渲染性能优化...

    ShevaKuilin 评论0 收藏0
  • 简说 优化关键渲染路径

    摘要:当解析被阻止时,这里,和会同时下载,所以关键路径长度仍为如何缩短关键呈现路径长度浏览器会有并行加载资源数的限制,如果网页很大,会需要来回多次获取资源。所以要根据情况合理控制文件资源大小参考优达的网站性能优化 回顾 关键渲染路径 showImg(https://segmentfault.com/img/bVKDWG?w=319&h=599); 简说浏览器渲染--关键渲染路径 渲染性能优化...

    fjcgreat 评论0 收藏0
  • 简说 优化关键渲染路径

    摘要:当解析被阻止时,这里,和会同时下载,所以关键路径长度仍为如何缩短关键呈现路径长度浏览器会有并行加载资源数的限制,如果网页很大,会需要来回多次获取资源。所以要根据情况合理控制文件资源大小参考优达的网站性能优化 回顾 关键渲染路径 showImg(https://segmentfault.com/img/bVKDWG?w=319&h=599); 简说浏览器渲染--关键渲染路径 渲染性能优化...

    BenCHou 评论0 收藏0
  • 前端性能优化之--页面渲染优化全面解析

    摘要:下面我们撇开网络方面的优化,只分析静态资源方面的优化。不过,也会阻止的构建和延缓网页渲染。未优化正常加载优化后异步加载根据上面的分析,我们可以清楚的认识到,非必要优先加载的,选择异步加载是最优选择。 为什么做优化 经典问题:白屏时间过长,用户体验差产生的原因:网络问题、关键渲染路径(CRP)问题 怎么做优化 如何做好优化呢,网上随便一搜,就有很多优化总结,无非就是网络优化、静态资源(h...

    MadPecker 评论0 收藏0
  • 前端性能优化之--页面渲染优化全面解析

    摘要:下面我们撇开网络方面的优化,只分析静态资源方面的优化。不过,也会阻止的构建和延缓网页渲染。未优化正常加载优化后异步加载根据上面的分析,我们可以清楚的认识到,非必要优先加载的,选择异步加载是最优选择。 为什么做优化 经典问题:白屏时间过长,用户体验差产生的原因:网络问题、关键渲染路径(CRP)问题 怎么做优化 如何做好优化呢,网上随便一搜,就有很多优化总结,无非就是网络优化、静态资源(h...

    gghyoo 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<