web性能优化三

·  阅读 104

这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战

使用 PRPL 模式应用即时加载

  • 预加载关键资源
  • 尽快渲染初始路线
  • 按业务策略缓存资源
  • 延迟加载剩余的其他路由和非关键资产

字体优化

  • Avoid invisible text during font loading

字体通常是需要一段时间才能加载的大文件,而浏览器的机制是如果使用@font-face引入字体,那么会在字体文件请求回来以后才会显示文字,如果大于3s该字体文件还没有准备好,那么就会使用系统默认字体来显示文字。为了这个不闪烁的效果,我们需要一个swap属性。

@font-face {
	font-family: 'SourceHanSansCN-Bold';
	src: url('./fonts/SourceHanSansCN-Bold.otf');
	font-display: swap;
}
复制代码

Font-display支持的值:

 font-display: auto; /* or block, swap, fallback, optional */
复制代码

预加载webFont资源

可以使用<link rel="preload">将关键路径渲染的早期触发对webfont的请求,这样就无需等待cssom的创建就可以进行webFont的请求了。

chrome为我们提供了一个字体加载的api,感觉可能会用到。

var font = new FontFace("Awesome Font", "url(/fonts/awesome.woff2)", {
  style: 'normal', unicodeRange: 'U+000-5FF', weight: '400'
});

// don't wait for the render tree, initiate an immediate fetch!
font.load().then(function() {
  // apply the font (which may re-render text and cause a page reflow)
  // after the font has finished downloading
  document.fonts.add(font);
  document.body.style.fontFamily = "Awesome Font, serif";

  // OR... by default the content is hidden,
  // and it's rendered after the font is available
  var content = document.getElementById("content");
  content.style.visibility = "visible";

  // OR... apply your own render strategy here...
});
复制代码
缓存
  1. 字体资源通常是不经常更新的静态资源,非常适合使用http缓存。http缓存是字体资源的最佳实践,其他的浏览器缓存通通不适合缓存字体资源。

减少字体

  1. 服务器配置gzip压缩

---

第三方服务

  • 在选择第三方资源服务时,选择稳定,安全,性能好的第三方服务。
  • 定期审核和清除多余的第三方脚本。

什么是关键渲染路径

  • 优化渲染路径
    • 优先显示与当前用户操作有关的内容。
  • 何为关键渲染路径
    • 浏览器将html,css,js转换为实际运行的网站必须采用的一系列步骤。

JavaScript添加交互

  • 我们的script脚本在何处插入,就在何处执行,当html解析器遇一个script标签时, 它会暂停构建dom,将控制dom树的权限交由JavaScript引擎(因为JavaScript有操作dom树的权限), 等JavaScript引擎运行完毕,浏览器会从中断的地方恢复dom的构建。如果script带有src属性,那么浏览器解析到这个script标签则必须停下来,等待从磁盘,缓存或者远程服务器获取脚本,这就有可能给关键渲染路径增加不等长的延迟。
  • 并非所有的资源都对快速提供首次绘制有关键作用。 事实上,我们谈论首次首次关键渲染路径时,通常谈论的是html,css,js。图像不会阻止页面的首次渲染。

优化JavaScript执行

  1. 对于动画效果的实现,避免使用 setTimeout 或 setInterval,请使用 requestAnimationFrame。
  2. 将长时间运行的 JavaScript 从主线程移到 Web Worker。
  3. 使用微任务来执行对多个帧的 DOM 更改。
  4. 使用 Chrome DevTools 的 JavaScript 分析器来评估 JavaScript 的影响。
  5. 为了最大限度减少浏览器对网页渲染的工作量,应延迟任何非必须的脚本(即对首次渲染的可见内容无关的紧要的脚本)。
  6. 避免运行长时间的JavaScript,运行时间长的JavaScript会阻止浏览器构建dom,cssom以及渲染网页。如果需要运行较长的序列化的代码,可以考虑时间切片和任务调度(react框架)
  • 我们希望在适合浏览器执行的时间内执行你的动画工作。并且在一帧开始的时间内运行你的程序。
/**
 * If run as a requestAnimationFrame callback, this
 * will be run at the start of the frame.
 */
function updateScreen(time) {
  // Make visual updates here.
}

requestAnimationFrame(updateScreen);
复制代码

优化css

  • Coverage分析
    • 绿色:浏览器呈现的可见内容所需的内容
    • 红色: 不是立即可见的内容
  1. 确保任何非必需的css都标记为非关键的资源(例如打印和其他媒体查询, media属性区分)。
  2. 减少css的体积和数量,缩短传送时间
  3. css需要置于head标签内,以便浏览器尽早发现link标签尽早的发出css请求。
  4. 避免使用 css @import 指令从另一样式表中导入规则。它们会在关键路径中增加往返次数,只有在收到并解析完带有@import规则的css样式表之后,才会发现导入的css资源。
  5. 关键css内联到html文档中,这样做不会增加关键路径中的往返次数。如果做的合理,可以大幅减少关键路径往返次数。
    1. 内联的缺点: 如果内联了大量的css,则会延迟html文档其余部分的传输,还有就是直接缺失了浏览器缓存的功能。 html文档最好在14kb以下吧。
  6. link rel="preload" as="style" 异步请求样式表

优化css选择器

  1. 降低选择器的复杂性;使用以类为中心的方法,例如 BEM。
    1. 避免css选择器层叠过多
  2. 减少必须计算其样式的元素数量。
    1. 避免出现.box:nth-last-child(-n+1)这样的选择器。

优化布局(重排)操作

一帧渲染的步骤: JavaScript执行 =》计算样式 => 开始layout布局 => 开始进行重绘(paint) => composite合成图层

  1. 尽可能避免布局操作

    1. 当您更改样式时,浏览器会检查这个更改是否需要计算布局,以及是否需要更新渲染树。对“几何属性”(如宽度、高度、左侧或顶部)的更改都需要布局计算。

    2. 重排几乎总是作用到整个文档。 如果有大量元素,将需要很长时间来算出所有元素的位置和尺寸。

  2. 使用 flexbox 而不是较早的布局模型

优化绘制操作

  1. 坚持使用 transform 和 opacity 属性更改来实现动画。
    1. 除 transform 或 opacity 属性之外,更改任何属性始终都会触发绘制。
  2. 通过层的提升和动画的编排来减少绘制区域
  3. 创建新层的最佳方式是使用 will-change CSS 属性。此方法在 Chrome、Opera 和 Firefox 上有效,并且通过 transform 的值将创建一个新的合成器层。但需要注意的是: 不要创建太多层,因为每层都需要内存和管理开销。
  • transform 和opacity

    是性能最佳的像素管道版本会避免布局和绘制,只需要合成更改(目前只有这两个属性符合): 使用 transformopacity 时要注意的是,您更改这些属性所在的元素应处于其自身的合成器层。要做一个层,您必须提升元素。

提升到自己的层

.moving-element {
  will-change: transform;
}
复制代码
分类:
前端
分类:
前端