性能优化

FP

全称:First Paint ,代表首次渲染的时间点 ,即视觉手册发生变化的时间点。白屏时间就是用户访问网页到FP这个时间点。所以FP是一个比较重要的性能指标,优化FP能够大大减少用户流失的概率,换句话说,FP就是网站的第一印象

FCP

全称:First Contentful Paint 代表首次Dom内容渲染的时间点,Dom内容 可以是 文本(背景)图像svg或非白色的canvas等等

FP和FCP的区别

从上面描述来说,FP是指非DOM的视觉变化(例如css样式),FCP侧重于DOM内容变化。

例子:

<div id="app"></div>
<div id="content"></div>

<style>
  #app {
    height: 100px;
    width: 100px;
    background-color: #409eff;
  }
</style>

<script>
  let data = [];
  const observerInstance = new PerformanceObserver((list) => {
    list.getEntries().forEach(item => data.push(item));
  });
  observerInstance.observe({
    entryTypes: ['paint']
  });
</script>

<script>
  setTimeout(() => {
    const el = document.getElementById("app");
    el.innerText = "hello world";
    const res = data.map(item => `${item.name}: ${item.startTime}`).join('\n');
  }, 2000);
  setTimeout(() => {
    const el2 = document.getElementById("content");
    el2.innerText = data.map(item => `${item.name}: ${item.startTime}`).join('\n');
  }, 3000);
</script>

分析下过程:

  • 在页面被打开时,一个方形div被渲染为蓝色(css生效),此时只发生了视觉变化,并没有发生DOM变动,改时间点即为FP

  • 在两秒后,hello word单词被插入 此时 发生DOM改动 该时间点为FCP

  • 从右侧输出的FP,FCP来看相差了差不多两秒

LCP

全称:Largest Contentful Paint ,根据页面首次加载的时间点(即 first started loading ,可以通过 performace.timeOrigin得到)来报告可视区域内可见的最大图像或文本块完成渲染的相对时间,其考量的元素有:

  • image元素

  • 内嵌在 svg 元素内的 image元素

  • video元素(使用封面图像)

  • 通过 URL 函数(而不是使用渐变)加载的带有背景图像的元素

  • 包含文本节点 或其他行内级文本元素子元素的块级元素

提示:

  • LCP一定在onload之后吗? 不一定,虽然大部分情况是,但是 一开始最大元素并没有发生变化 LCP的时机完全可以在页面完全加载之前出现

  • 一个长度和一个宽度很大的div 没有内容但是有背景色,可能会触发LCP吗

    不可能,LCP的捕获范围是可视区域内可见的最大图像或文本块,对于div应该是看内容的多少来判断是否触发LCP

优化策略

对于FP、FCP侧重首次渲染,那我们不难想到如下问题:什么情况下会阻塞渲染?我们有下面的结论

  • script 会阻塞DOM渲染

  • 外部script 标签会触发一次渲染

    所以我们可以尝试下面的优化策略

    • 如非必要 不要往 里面添加script,而应该放在DOM的底部

    • 尽量不要使用内联的script标签,因为外部scipt标签会触发一次渲染,让页面尽可能早点的出现

    • 合理使用script的defer async 属性

    • 另外我们还可以对关键资源进行预加载,preload提供 了一种声明式的命令,让浏览器提前加载资源(加载资源不执行),在需要执行的时候执行:

      <!-- 使用 link 标签静态标记需要预加载的资源 -->
      <link rel="preload" href="/path/to/style.css" as="style">
      <!-- 或使用脚本动态创建一个 link 标签后插入到 head 头部 -->
      <script>
       const link = document.createElement('link');
       link.rel = 'preload';
       link.as = 'style';
       link.href = '/path/to/style.css';
       document.head.appendChild(link);
      </script>

最后更新于

这有帮助吗?