页面渲染部分的前端性能优化

1.1 重绘、重排、回流

1.1.1 重绘、重排、回流是什么

1. 重绘(Repaint):  重绘是指当元素样式的改变不影响它在文档流中的位置和大小,只涉及到外观的变化时,浏览器会重新绘制(重绘)这个元素。重绘通常发生在改变元素的颜色、背景、边框等视觉样式属性时。

2. 重排(Reflow):  重排是指当 DOM 结构发生变化,或某个元素的尺寸、位置等属性发生变化时,浏览器需要重新计算并重新布局(重排)整个页面或部分页面的过程。重排会触发一系列的计算操作,影响性能。

3. 回流(Layout):  回流是重排过程的一部分,是指浏览器对文档流中的每个可见元素的当前位置和大小进行计算的过程。当浏览器计算元素的位置和大小时,需要考虑包括视口大小、元素自身属性、相对于其他元素的布局关系等各种因素。

代码示例:

<!-- 示例代码 -->
<div id="myElement">Hello, World!</div>
// 修改元素的样式(重绘)
document.getElementById('myElement').style.color = 'red';



// 修改元素的尺寸和位置(重排)
document.getElementById('myElement').style.width = '200px';
document.getElementById('myElement').style.height = '100px';
document.getElementById('myElement').style.marginTop = '10px';


// 访问元素的布局信息(回流)
const elementWidth = document.getElementById('myElement').offsetWidth;
const elementHeight = document.getElementById('myElement').offsetHeight;

在上述示例中,修改元素的样式(颜色)触发了重绘,因为样式的改变不影响布局。而修改元素的尺寸、位置和间距等属性,需要计算元素的位置和大小,因此触发了重排。最后,通过访问元素的布局信息(宽度和高度)也将触发回流。

为了最小化重绘和重排的次数,可以使用一些优化技巧,例如使用 CSS3 的 transform 替代改变元素位置和尺寸的属性,使用 class 切换代替直接修改样式等。此外,对于需要多次进行 DOM 操作的情况,可以使用文档片段(DocumentFragment)进行离线操作,最后一次性插入文档,以减少回流和重排的次数。

1.1.2 减少重绘、重排和回流的常见策略

重绘、重排和回流是性能优化的重要目标之一。以下是一些减少重绘、重排和回流的常见策略:

1. 批量修改元素样式:  将需要修改的样式属性集中在一个代码块中,而不是多次单独修改。这样可以减少重绘和重排的次数。

// 糟糕的写法(多次修改样式)
element.style.width = '100px';

element.style.height = '100px';

element.style.color = 'red';




// 更好的写法(批量修改样式)
element.style.cssText = 'width: 100px; height: 100px; color: red;';

2. 使用 class 切换样式:  通过添加或删除 class 来修改元素样式,而不是直接操作 style 属性。这样可以避免多次重排和回流。

// 糟糕的写法(直接修改样式)
element.style.width = '100px';

element.style.height = '100px';

element.style.color = 'red';




// 更好的写法(使用 class 切换样式)
element.classList.add('custom-class'); // 添加样式
element.classList.remove('custom-class'); // 移除样式

3. 使用 transform 和 opacity 属性:  对于需要修改元素位置、大小和透明度的操作,使用 CSS 的 transform 和 opacity 属性可以避免重排和回流。

// 修改元素位置和大小(使用 transform)
element.style.transform = 'translate(100px, 100px) scale(1.5)';



// 修改元素透明度(使用 opacity)
element.style.opacity = '0.5';

4. 使用文档片段(DocumentFragment):  在需要多次进行 DOM 操作时,使用文档片段进行离线操作,最后一次性将文档片段插入文档,可以减少回流和重排的次数。

// 创建文档片段
const fragment = document.createDocumentFragment();



// 在文档片段中进行离线操作
const element1 = document.createElement('div');
element1.textContent = 'Element 1';
fragment.appendChild(element1);


const element2 = document.createElement('div');
element2.textContent = 'Element 2';
fragment.appendChild(element2);

// 一次性插入文档
document.getElementById('container').appendChild(fragment);

5. 缓存布局信息:  避免多次获取元素的布局信息,可以将布局信息缓存到变量中,以降低回流的次数。

// 糟糕的写法(多次获取布局信息)
const width = element.offsetWidth;
// 其他操作...
const height = element.offsetHeight;



// 更好的写法(缓存布局信息)
const rect = element.getBoundingClientRect();
const width = rect.width;
const height = rect.height;

除了以上策略,还应当注意减少过多的 DOM 操作、避免频繁修改布局,合理使用 CSS3 动画、转换和过渡等。性能优化是一个持续的过程,需要不断评估和测试,根据具体情况采取相应的优化措施。

以下方式也可以减少重绘、重排和回流

1、减少使用 css 属性简写,如:用border-width, border-style, border-color代替border。因为css简写把所有值初始化为initial,尽量不使用属性简写可以最小化重绘(repaint)和回流(reflow) ,(实际工作中,由于css简写带来的性能影响微乎其微,再加上css全都展开写还会增加code size,另外css简写还能解决一些样式覆盖的问题,写起来也比较简单快捷,所以实际工作个人怎么顺手怎么来就好~)

2、通过修改className批量修改元素样式;

3、复杂的动画元素定位要设置为 fixedabsoult,避免引起回流;

4、不使用table布局(table元素一旦触发回流就会导致table里所有的其它元素回流);

5、DOM 元素上下移动用用translate替代top修改

6、需要创建多个DOM节点时,使用DocumentFragment一次性创建。

7、ss3硬件加速(GPU加速),它可以让transform、opacity、filters这些动画不会引起回流重绘。对于动画的其它属性,比如background-color这些,还是会引起回流重绘的,不过它还是可以提升这些动画的性能(但是不能滥用,会导致性能问题)。

8、元素适当地定义高度或最小高度,否则元素的动态内容载入时,会出现页面元素的晃动或位置,造成回流(比如图片要定义宽高,避免页面塌陷,同时减少回流);

9、减少使用层级较深的选择器,或其他一些复杂的选择器,以提高CSS渲染效率;

10、在大量修改元素样式时,可以先用display: none将其隐藏,修改完再设置为display: block,这样只会造成两次回流;

2. 压缩字体包

在前端开发中,压缩字体包(Font Compression)可以减小字体文件的大小,提高网页加载速度。以下是一些常用的压缩字体包的方法:

1. 使用字体子集(Font Subset):  字体子集是指从完整字体文件中提取出网页所需的字符子集。通过使用字体子集,可以减小字体文件的大小,只包含网页所需的字符,而不是完整的字体文件。

  • 可以使用在线工具(如”Font Squirrel”)或命令行工具(如”pyftsubset”)来生成字体子集。
  • 在 CSS 中使用 @font-face 规则加载字体子集文件。
@font-face {
  font-family: 'MyFont';
  src: url('myfont-subset.woff2') format('woff2');
  /* 其他字体描述属性 */
}

2. 使用字体压缩工具:  有一些工具可以对字体文件进行压缩优化,去除不必要的元数据、优化字形数据等。

  • ttf2woff:将 TrueType 字体转换为 WOFF 格式,并进行优化。
  • sfnt2woff-zopfli:使用 Zopfli 压缩算法对 WOFF 字体进行进一步压缩。
  • woff2_compress:将字体文件转换为 WOFF2 格式,并进行优化压缩。

这些工具可以作为命令行工具使用,将字体文件作为输入,并生成压缩后的字体文件。

3. 合理选择字体格式:  不同的字体格式对于不同的情况有不同的压缩效果,可以根据具体情况选择合适的字体格式。

  • WOFF2(Web Open Font Format 2)是现代 Web 发布中最常用的字体格式,一般具有较好的压缩效果。
  • WOFF(Web Open Font Format)是早期的字体格式,与 WOFF2 相比具有较大的文件大小。但在一些老的浏览器上仍然需要使用 WOFF。
  • TTF(TrueType Font)格式在一些情况下可能具有较大的文件大小,可通过转换为其他格式或进行压缩优化。

注意:在进行字体压缩时,应确保不侵犯字体文件的版权和许可规定。

以上是一些常用的方法来压缩字体包,你可以根据具体的需求选择合适的方法来减小字体文件的大小。

3. 懒加载、预加载资源

懒加载和预加载是两种常用的性能优化技术,可以提升网页加载速度和用户体验。下面是它们的使用方法:

3.1 懒加载

1. 懒加载(Lazy Loading):  懒加载是指在网页加载时只加载可见区域的内容,延迟加载其他部分。这在加载大量图片或视频等资源时特别有用,可以减少初始加载时的资源请求和带宽消耗。

  • 对于图片或其他媒体文件,可以使用 loading="lazy" 属性来实现懒加载:
<img src="placeholder.jpg" data-src="image.jpg" alt="Image" loading="lazy">
  • JavaScript 库,如 Intersection Observer API,也可以用于实现更精细的懒加载控制。

3.2 预加载

2. 预加载(Preloading):  预加载是指在页面加载时提前加载将来可能需要的资源,以提升用户体验。这对于高优先级资源(如页面的核心 CSS 或 JavaScript 文件)特别有用,可以减少后续的请求延迟。

  • 对于样式表(CSS)文件,可以使用 rel="preload" 属性来实现预加载:
<link rel="preload" href="styles.css" as="style">
  • 对于 JavaScript 文件,可以使用 rel="preload" 和 as="script" 属性来实现预加载:
<link rel="preload" href="script.js" as="script">

需要注意的是,在使用懒加载和预加载时,应该权衡资源的加载优先级和用户体验。过多的预加载可能会增加初始的网络请求和带宽消耗,过多的懒加载可能会导致用户滚动到可见区域时出现内容闪现的问题。因此,根据具体场景和需求,进行合理的懒加载和预加载的配置。

4. 异步加载资源

使用异步加载资源是一种常见的性能优化技术,可以提高网页的加载速度和用户体验。异步加载资源可以并行加载,不会阻塞页面的渲染和其他资源的加载。以下是一些常用的方法来实现异步加载资源:

4.1 async 和 defer

1. 使用 async 和 defer 属性:  HTML 标签的 script 元素有 async 和 defer 两个属性,可以用来控制脚本的异步加载行为。

  • async 属性:指定该脚本的加载是异步的,不会阻塞页面的解析和渲染。脚本加载完成后,会立即执行。适用于不依赖其他脚本和 DOM 的顺序执行的脚本。
<script src="script.js" async></script>

defer属性 :指定该脚本的加载是异步的,但它会按照顺序执行,等待整个文档解析完成后再执行。适用于需要按照一定顺序执行的脚本。

<script src="script.js" defer></script>

4.2 动态创建 DOM 元素

可以使用 JavaScript 动态创建 script 或 link 元素,并将它们添加到页面中,以实现异步加载。

var script = document.createElement('script');
script.src = 'script.js';
// 可选:设置 async 或 defer 属性
document.body.appendChild(script);
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'styles.css';
// 可选:设置 media 属性
document.head.appendChild(link);

4.3 使用异步加载库

对于一些常用的 JavaScript 库和框架,它们通常提供异步加载的选项或特定的加载器来实现按需加载。

例如,RequireJS、SystemJS、LoadJS、ES modules 等都是一些流行的工具和模块加载器,可以实现异步加载和动态加载 JavaScript 代码。

// 使用 RequireJS 异步加载模块
require(['module'], function(module) {
  // 使用加载的模块
});

5. 优化缓存策略

  1. 设置适当的缓存头:通过在服务器响应中设置适当的缓存头,可以指示浏览器在一定时间内缓存静态资源。常用的缓存头有Cache-ControlExpires。例如,将资源的Cache-Control值设置为public, max-age=3600表示该资源可以被公共缓存,并在3600秒(1小时)内有效。
  2. 使用版本化的文件名:每当静态资源(如CSS、JavaScript文件)发生变化时,为其分配一个新的文件名,并在链接到资源的地方使用新的文件名。这样可以确保浏览器重新请求最新版本的文件,而不是使用缓存的旧版本。
  3. 使用缓存清单(Cache Manifest):对于离线应用程序,可以使用缓存清单来定义要缓存的资源。缓存清单是一个简单的文本文件,列出了需要缓存的文件,使得应用程序能够在离线状态下加载这些文件。
  4. 响应头的ETag和Last-Modified:服务器可以通过使用ETag和Last-Modified响应头来标识资源的版本。当浏览器请求资源时,服务器会将这些标识符包含在响应中。如果资源没有发生变化,浏览器可以使用缓存的副本,否则服务器将返回新的资源。
  5. 资源合并与减少请求数量:将多个CSS或JavaScript文件合并为一个文件,可以减少浏览器发起的请求数量。这样可以提高加载速度,并从中受益的是缓存效果。
  6. 使用CDN(内容分发网络):CDN是一种分布式网络架构,将静态资源存储在全球各地的服务器上,使用户可以从最近的服务器加载资源。使用CDN可以提供更快的下载速度,并减轻源服务器的负载。

6. 合并和压缩资源文件

  1. 合并文件:将多个资源文件(例如,CSS、JavaScript文件)合并成一个文件可以减少页面请求的数量,从而提高加载速度。可以使用构建工具(如Webpack、Grunt、Gulp等)来自动化此过程。

通过webpack配置进行文件的合并压缩
配置webpack:在webpack的配置文件中,需要使用合适的插件和配置项来实现资源文件的合并和压缩。常用的插件包括html-webpack-pluginmini-css-extract-pluginterser-webpack-plugin
合并JavaScript文件:通过使用webpack的模块化功能,将多个JavaScript文件合并成一个文件。这可以减少页面请求的数量,提高加载速度。可以使用entry配置项指定入口文件,使用output配置项指定输出路径和文件名。
压缩JavaScript文件:使用terser-webpack-plugin插件来压缩JavaScript文件。该插件能够删除空格、注释和缩小变量名,减小文件体积。可以在webpack配置文件中添加以下代码:

const TerserPlugin = require('terser-webpack-plugin');



module.exports = {

  // ...

  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          compress: {
            drop_console: true, // 移除console.log语句
          },
          output: {
            comments: false, // 移除注释
          },
        },
      }),
    ],
  },
};

合并CSS文件:使用mini-css-extract-plugin插件将多个CSS文件合并成一个文件。这样可以减少请求次数,并减小文件体积。可以在webpack配置文件中添加以下代码:

const MiniCssExtractPlugin = require('mini-css-extract-plugin');



module.exports = {

  // ...

  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].css', // 合并后的CSS文件名
    }),
  ],
  module: {
    rules: [
      {
        test: /.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
        ],
      },
    ],
  },
};

压缩CSS文件:可以使用optimize-css-assets-webpack-plugin插件压缩CSS文件。该插件会去除注释、空格和不必要的样式规则,以减小文件体积。可以在webpack配置文件中添加以下代码:

const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');



module.exports = {
  // ...
  optimization: {
    minimizer: [
      new OptimizeCssAssetsPlugin(),
    ],
  },
};

通过以上步骤配置webpack,你可以实现资源文件的合并和压缩来进行性能优化。

  1. 压缩代码:压缩CSS和JavaScript代码可以减小文件大小,减少传输时间。常见的工具有UglifyJS、YUI Compressor等。这些工具可以删除不必要的空格、注释和其他不影响功能的字符,并使用更短的变量名来代替长变量名。
  2. 图片压缩:对图片进行压缩可以减小文件大小,提高加载速度。可以使用工具如OptiPNG、JPEGtran等,或使用在线工具将图片压缩到合适的大小。
  3. 字体子集化:如果使用了自定义字体,可以使用字体子集化工具将字体文件缩减为只包含实际使用的字符,从而减少字体文件的大小。
  4. 缓存控制:通过正确设置缓存头信息可以使浏览器缓存资源文件,减少重复的网络请求。可以使用Expires头、Cache-Control头或Etag头来控制缓存行为。
  5. CDN 加速:使用内容分发网络(CDN)可以将资源文件分发到离用户更近的服务器上,从而提高加载速度。

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYgh1LHr' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片