性能优化

尚未完成,请稍等

http

  • 使用更高的http版本
  • 合理使用http缓存

资源加载

  • 减少文件传输的体积
  • rollup对打包进行分割成多个包
  • 资源预加载
  • DNS预解析
  • CDN
  • 路由懒加载
  • 组件懒加载
  • 图片懒加载
  • css和字体库代替图片

渲染

  • 文档解析,渲染需要大量时间,为了让用户先看到界面,采用骨架屏能优化用户体验。
  • 假如是大量的长列表,可以采用分批或者虚拟列表方式解决。

dom树,cssom树构建

都知道,js的下载和执行会阻塞DOM树的构建,我们可以使用async进行并行的下载(下载完立即执行),defer来并行下载延迟执行(DomLoadedContent之前执行,并且有顺序)。注意哈,我们使用js创建的script标签的默认行为类似于async。

CSS和JS文件可以并行下载,但是浏览器会等待CSSOM树下载并解析完再执行JS脚本。也就是说假如在js之前碰到了style样式,可能会等待CSSOM树的构建,也就是css间接的阻塞了我们的主线程。

因此,引出了第一个优化点

  • 如何解决css阻塞js执行
  1. 重要样式内联,能够瞬间构建出CSSOM,JS就不会等待CSS过久。(因为浏览器的加载是渐进式的)
  2. 异步加载非关键css,proload和onload
  3. 减少css体积,删除空格,注释等。
  4. 延迟js的执行(defer,async)

重排 重绘

当你修改了元素的布局样式,例如width,height,那么浏览器会将当前的Layout标记为dirty,这会使得浏览器在下一帧的时候进行重排。

如果你在Layout标记为dirty的时候访问了offestTop,scrollHeight等属性,会立即暂停js,立马进行页面的重新渲染,获取正确的属性。

修改一些属性,例如color,back-color,visiblity,text-decoration只会引起一个重绘的过程,不会重排。

注意:浏览器的刷新通过类似队列和时间来达到只在渲染时进行一次的DOM操控。所以不是我们每次的DOM操作都会引起重排重绘。我们的浏览器有个flush队列,来进行DOM操作的存储,最后一次性的添加上去。 大家这时候可能会有个疑问就是,其实我的页面渲染只会一次,那何必要这个flush队列呢?我直接进行DOM的多次修改,只要最后渲染的时候能进行一次的渲染即可。其实我们的flush队列还会进行一下的工作,例如:

js 复制代码
element.style.width = '100px';  // 修改1
console.log(element.offsetHeight); // 读取布局属性 → 强制同步布局计算!
element.style.height = '200px'; // 修改2

我们的flush队列会给我们优化成以下情况

js 复制代码
element.style.width = '100px';  // 修改1
element.style.height = '200px'; // 修改2
console.log(element.offsetHeight); // 读取属性 → 处理队列中的修改1+修改2,触发一次回流

所以我们便有了以下的性能方案

  • 读写操作分离,因为Layout为dirty的时候访问会触发立即强制同步布局,所以读写分离能很好的一次回流。因为只会触发第一次回流,接着我们的布局就不为脏了,不会触发多次回流。
  • display为none脱离渲染树。能够阻止强制重绘重排。因为我们的display为none属性不会标记当前的layou为dirty,读取他的布局属性不会引起强制回流,而是直接返回为你0或者缓存值。
  • 文档碎片,会造成跟上面一样的不会引起强制回流,返回值同样为0。并且能够减少不断沟通DOM的开销。其实我们的文档碎片要尽量避免一个强制渲染的操作,其实他的获取是不准确的。
  • 减少读写交错造成的强制同步,可以用js缓存布局信息。
  • transform 代替 位置调整。transform不会引起重排,只会有一个GPU对位图的一个移动后合成的过程。

分层

分层后层单独由GPU进行一系列操作。并不会引起主页面层的一个重绘重排的过程,只需要GPU单独对位图进行一个缩放等效果,最后进行一个合成的过程即可。

requestFrameAnimation 和 requestIdleCallback

我们使用定时器时,他是宏任务,当宏任务队列有其他的任务时,我们可能执行不到定时器内的更新任务,这就会导致页面没有及时的渲染。 而使用raf,他会在我们的渲染执行前开始执行。虽然我们浏览器的渲染也不是固定时间的,但是我们的vsync同步是精确的,也就能保证我们用户感知到稳定的帧率。所以得出下面结论。

  • 使用raf来进行动画效果

执行到我们的RIC,会将RIC的回调放入我们的等待队列中,等待我们的帧空闲时间执行。RIC接收两个参数,第一个是一个回调,第二个是一个Timeout。保证我们的函数在timeout后,在某个时间执行一次。

事件委托

webWorker

webWorker是我们的

首屏 白屏 交互 具体指标

相关推荐
在繁华处2 分钟前
从零搭建轻灵(四):工具系统与 Pipeline
前端·chrome
小则又沐风a6 分钟前
进一步了解进程---第四章 进程管理
java·服务器·前端
放下华子我只抽RuiKe56 分钟前
FastAPI 全栈后端(一):为什么选择 FastAPI
前端·javascript·深度学习·react.js·机器学习·前端框架·fastapi
ZC跨境爬虫8 分钟前
跟着 MDN 学CSS day_11:(深入理解CSS值与单位的完整体系)
前端·css·ui·html·tensorflow
青云计划10 分钟前
SSE流式响应:从Reactor Flux到生产级AI聊天的工程实践——5分钟超时、线程隔离、背压处理全解析
前端·人工智能·firefox
codefan※27 分钟前
7 个Prompt 框架汇总:从 Chain of Thought 到 ReAct + PoT
前端·react.js·ai·llm·prompt·prompt工程·思维链
迁旭29 分钟前
Claude Code /status 功能技术文档
前端·javascript·人工智能·react.js·机器学习·gpt-3·文心一言
GISer_Jing33 分钟前
前端全流程求职Skill 攻略
前端·学习·前端框架
Bigger44 分钟前
架构解密:mini-cc 的核心设计思路
前端·agent·ai编程