1 效果图对比
preload.js就是我们预加载的资源
1.1什么情况下使用预加载
比如:是用户点击按钮时才加载这个资源的,如果资源体积很大,那么用户会感觉到明显卡顿效果 要优化这种情况,可以使用preload和prefetch技术
1.2
2.什么是preload和prefetch
Preload和Prefetch是两种优化前端性能的技术,它们可以让浏览器在某些条件下提前加载一些资源,从而加快应用程序的加载速度。
Preload指的是在页面加载时预加载一些关键资源,这些资源在接下来的页面操作中会立即用到。Preload可以使用rel="preload"属性来实现,比如:
<link rel="preload" href="path/to/resource" as="type"/>
其中,
href 表示需要预加载的资源路径
as属性 指定预加载资源的类型有“script’ /‘style’/ "font"
相比之下,Prefetch是在页面加载后不紧急需要但将来可能需要使用的资源进行预加载。Prefetch的实现方式是通过添加rel="prefetch"属性来实现,例如:
<link rel="prefetch" href="path/to/resource"/>
下面是一个Preload的例子,假设我们有一个应用程序需要用到moment.js
库,我们可以将moment.js
资源进行预加载:
这里我们是手动注入方式
<head>
<link rel="preload" href="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js" as="script" />
</head>
3.webpack的方式配置预加载
下载:
npm install --save-dev preload-webpack-plugin
webpack配置:
const PreloadWebpackPlugin = require('preload-webpack-plugin');
module.exports = {
entry: {app: './src/main.js',
preload: './src/test.js' //定义需要预加载的文件
},
plugins: [
// ... 其他插件
new PreloadWebpackPlugin({
rel: 'preload',
include: ['preload'] // 可以是 'initial', 'async', 'all', 或者指定 chunk 名称的数组
}),
],
// ... 其他webpack配置
};
PreloadWebpackPlugin 还提供了其他配置选项,如 fileBlacklist
和 fileWhitelist
,priority用于控制哪些文件会被添加到 preload 标签中,以及哪些文件会被排除
new PreloadWebpackPlugin({
rel: 'preload',
include: 'allChunks',
fileWhitelist: [/\.css$/, /\.js$/],
priority: 'low' // 可以是 'low', 'medium', 'high' 或者一个正整数值
})
//我们将优先级设置为 "low",这意味着被预加载的资源将被赋予较低的优先级。你也可以将优先级设置为 "medium" 或 "high",以指定更高的优先级
开始打包 npm run build 打包成功后查看index,html文件已自动添加到index.html中
3.深入理解如何优雅的控制网页请求的优先级
对于一个网页的性能和体验来讲,控制好请求发起的优先级是非常重要的,网络带宽是有限的,优先去加载重要的资源,让次要的资源延后,就可以让我们的网站体验提升一个台阶。
浏览器本身非常擅长确定网页资源请求的优先级,而且大多数情况下也做的挺好的。但我们肯定还是会遇到一些特殊的优先级控制需求,Priority Hints可以轻松的帮助我们主动控制网站请求加载的优先级。
3.1浏览器默认预加载资源的优先级
现代浏览器有一种受到光房支持的方式来提前获取当前页面最终需要的资源:<link rel="preload" ... />。当我们将它放置在 HTML 的 <head>中时,浏览器将被指示以 “高” 优先级尽快开始下载它。
浏览器中的预加载扫描器已经非常擅长此类事情了,所以,预加载通常最适合用于后来发现的资源 - 任何未由 HTML直接加载的资源,例如通过内联样式属性加载的背景图像。但它对于浏览器可能没有按照你想要的优先顺序排列的任何其他内容也很有用。
举个例子:默认情况下,Chrome会加载具有非常高优先级的字体,但如果某个用户的网络连接速度较慢,它会使用后备字体并降低优先级。
我们通过 CSS @font-face规则加载的字体:
@font-face{
font-family: "Inter Variable";
src: url("./font.woff2") format("woff2");
}
加载时,由于网速较慢,这个字体的下载优先级最低,尽管它对于页面的视觉体验非常重要。
我们使用预加载来优先加载字体文件
<head>
<!-- Other stuff... -->
<linkrel="preload"href="/font.woff2"as="font">
</head>
3.2请求的优先级我们可以通过代码做控制
3.3 img 资源的优先级
在默认情况下,无需我们做任何特殊的事情,浏览器就会自动确定页面上最重要的图像。
比如我们来看下面的例子,有三个垂直排列的图片,并且距离非常远:
<img src="./c.jpg" />
<div style="height: 1700px"></div>
<img src="./y.jpg" />
<div style="height: 1700px"> </div>
<img src="./t.png" />
当刚开始下载时,所有三个都是 “Medium” 优先级:
再次刷新页面可以看到c.jpg的优化级提高成High说明浏览器已经知道c.jpg会最新出现在我们的视口范围中,
做为开发人员我们肯定知道那一张图片会首先出现,为了提高性能我们主动提高优先级使用 fetchpriority="high"
顺便说一下,这个功能与图像的懒加载机制非常匹配,目前得到了很好支持
<img src="./c.jpg" fetchpriority="high" />
<div style="height: 1700px"></div>
<img src="./y.jpg" fetchpriority="low" loading="lazy" />
<div style="height: 1700px"> </div>
<img src="./t.png" fetchpriority="low" />
3.4脚本的优先级
页面上任何带有 src属性的普通 < />都会拥有比较高的优先级,但有一个需要权衡的事情:它们会阻止对页面其余部分的解析,直到加载并执行完成为止。
因此,我们可能会使用到 async属性,它会在后台以低优先级请求脚本,并在准备就绪后立即执行。我们来看下面的例子:
async脚本会降低优先级:控制台确认,在异步脚本加载的过程中,允许后续脚本解析和执行。
<script src="data.js" async="console.log('async')"></script>
<script src="test1.js" async="console.log('sync')"></script>
<script src="moment.js" async="console.log('inline')"></script>
场景:
但是,如果我们又希望脚本异步下载,也希望脚本拥有 “High” 优先级呢。
一个可能的场景是将一个小型 SPA嵌入到一个落地页的主要内容中。为了保持页面的 Core Web Vitals,特别是 LCP(最大内容绘制时间)和 FID(首次输入延迟),你需要将该脚本设置为高优先级(毕竟,它负责构建和驱动你的应用程序)。但与此同时,你不希望它阻碍页面的其余部分进行解析。
所以,让我们给它一个 fetchpriority:
<script src="data.js" async="console.log('async')" fetchpriority="high"></script>
<script src="test1.js" async="console.log('sync')"></script>
<script src="moment.js" async="console.log('inline')"></script>
3.4.总结
fetchpriority也千万不要过度使用,因为加的多了就等于什么都没加,甚至会导致网页的性能下降。
把 fetchpriority添加到那些浏览器推断的不好,并且你有明确优先级要求的元素上,对网页的加载体验还是会很大的!
预加载会影响 Largest Contentful Paint(最大内容绘制) 和 Cumulative Layout Shift(累积布局偏移)。在某些情况下,影响可能是负面的。我们建议使用预加载请求进行试验,但一定要前后仔细测试