css 预先加载部分样式文件打包策略

发布于:2024-05-15 ⋅ 阅读:(153) ⋅ 点赞:(0)

背景

  • 在实际应用中,比如想让骨架屏等样式资源优先加载等场景下使用

webpack loader设置匹配规则

  • 可以通过文件名包含 preload 或者在文件路径添加 ? prelaod 查询参数进行区分
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        oneOf: [
          // 这里是预加载的样式文件
          {
            resourceQuery: /preload/, // file.css?preload
            use: [
              MiniCssExtractPlugin.loader,
              'css-loader',
            ],
          },
          // 这里是其他样式文件
          {
            use: [
              MiniCssExtractPlugin.loader,
              'css-loader',
            ],
          },
        ],
      },
    ],
  }
};

webpack plugin 提取不同文件

  • MiniCssExtractPlugin 提取 css 打包进不同的文件

  new MiniCssExtractPlugin({
    filename: (chunkData) => {
      return chunkData.chunk.name.includes('preload') ? '[name].preload.css' : '[name].css';
    },
  }),
  • HtmlWebpackPlugin 写入不同优先级的文件

new HtmlWebpackPlugin({
  template: './src/index.html',
  // 通过设置 inject 为 false,我们可以在模板中手动添加 CSS 链接
  inject: false,
}),
<!DOCTYPE html>
<html>
  <head>
    <!-- 预加载样式文件 -->
    <% htmlWebpackPlugin.files.css.forEach(function(file) { %>
      <% if(file.includes('preload')) { %>
        <link rel="preload" href="<%= file %>" as="style" onload="this.οnlοad=null;this.rel='stylesheet'">
        <noscript><link rel="stylesheet" href="<%= file %>"></noscript>
      <% } %>
    <% }); %>
  </head>
  <body>
    <!-- 应用的主入口 -->
    <div id="app"></div>

    <!-- 正常加载主样式文件 -->
    <% htmlWebpackPlugin.files.css.forEach(function(file) { %>
      <% if(!file.includes('preload')) { %>
        <link rel="stylesheet" href="<%= file %>">
      <% } %>
    <% }); %>
  </body>
</html>
  • 先设置 preload 再通过 js 设置 rel 属性原因

  • 将 <link> 元素的rel属性设置为 “preload”,这样CSS文件会被异步加载,也就是说,文件的加载过程不会阻塞页面的渲染
  • 预加载的 css 文件并不会被浏览器应用到页面上,除非将 <link> 元素的 rel 属性改为 “stylesheet”
  • 再通过 js 将 <link> 元素的 rel 属性从 “preload” 改为 “stylesheet”,这样就可以在 css 文件加载完毕后将其应用到页面上,而不会阻塞页面的初次渲染
 <link rel="preload" href="<%= file %>" as="style" onload="this.οnlοad=null;this.rel='stylesheet'">
 // 兜底:禁用 js 的情况下直接加载
 <noscript><link rel="stylesheet" href="<%= file %>"></noscript>

网站公告

今日签到

点亮在社区的每一天
去签到