prefetch 和 preload 及 webpack 的相关处理
使用预取和预加载是网站性能和用户体验提升的一个很好的途径,本文介绍了使用 prefetch 和 prefetch 进行预取和预加载的方法,并使用 webpack 进行实现
Link 的链接类型
<link>
标签的 rel
属性可以定义链接类型,prefetch
是其中的一种,与 href
配合使用可以预取或预加载对应资源
<link rel="prefetch" herf="URL">
preload
是另外一种类型,同样用 href 定义资源地址,但其处理预取外,还会对资源进行解析,所以还要增加属性 as,说明资源的类型
<link rel="preload" href="URL" as="MIME_TYPE">
预取资源
prefetch
表示用户在接下来的浏览中(例如在下一个页面),有可能用到对应资源,提示浏览器要在闲时获取对应资源
先新建文件夹 prefetch-preload-demo(本文所有代码将在此创建),安装相关依赖,并新建文件夹 static
mkdir prefetch-preload-demo
cd prefetch-preload-demo
npm init -y
npm i -D http-server
mkdir static
在 static 中创建 prefetch.html
, main.js
和 script.js
prefetch.html
定义了一个 rel
为 prefetch
的链接
<html>
<head>
<title>Prefetch</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="prefetch" href="script.js">
</head>
<body>
<script src="main.js"></script>
</body>
</html>
main.js
创建了一个按钮,并绑定了点击事件
let button = document.createElement('button');
button.innerHTML = 'Add Script';
button.addEventListener('click', e => {
let script = document.createElement("script");
script.src = "script.js";
document.head.appendChild(script);
});
document.body.appendChild(button);
script.js
只是简单的打印了一下
console.log('script run');
运行服务器(也可在 package.json
中增加 server
脚本)
npx http-server
访问 http://localhost:8080 并导航至 static
中,点击 prefetch.html,或者直接访问线上页面,初始状态下,查看控制台的网络选项卡下的内容如下(不要勾选 Disable Cache
,点击右侧齿轮,勾选 Use large request rows
)
script.js
被 fetch 下来,size 列的两个数字,275 B 表示下载的字节大小,0 B 表示解析的字节大小(即目前并没有解析)- 控制台是空的,即脚本没有运行
点击页面上的 Add Script
,会在页面增加地址为 script.js
的 <script>
标签,此时网络选项卡会增加以下内容
- 下载字节量为
(prefetch cache)
,即直接从预取缓存获取资源,下面的解析后的字节不再为 0 - 控制台打印出脚本中的调试内容,即这时脚本才被解析并运行
预加载资源
preload
表示用户在当前的浏览中(往往是在当前页面),极有可以可能用到对应资源,提示浏览器要优先获取对应资源
将 prefetch.html 的 link 标签的 prefetch 改为 preload
,并增加资源类型 as
为 script
,即得 preload.html
<link rel="preload" href="script.js" as="script">
访问本地服务器对应的 prefetch.html
,或者直接访问线上页面,初始状态下,查看控制台的网络选项卡下的内容如下
script.js
被优先下载, size 列的解压字节不再为 0,即preload
除了把脚本下载了下来,还进行了解析- 控制台目前仍为空,即脚本虽然被解析,但并没有运行
点击 Add Script
,网络选项卡并没有增加任何记录,但是控制台输出了脚本的打印内容
- 因为脚本已经解析完成,所以连从缓存获取都不需要了,直接运行即可
- 如果没有在 3 秒内点击
Add Script
,控制台会进行警告,因为没有及时使用应该优先加载的资源
The resource https://chanvinxiao.com/demo/html/script.js was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate
as
value and it is preloaded intentionally.
webpack 的相关处理
运行以下命令安装相关依赖,并新建文件夹 src
npm i -D webpack webpack-cli html-webpack-plugin preload-webpack-plugin@3.0.0-beta.4
mkdir src
- PreloadWebpackPlugin 的当前版本 2.x 与 webpack 当前版本 4.x 不兼容,所以需要指定版本号为最新的 3.x beta
将 main.js
与 script.js
复制到 src 中,并将 main.js
的点击事件处理更新为
button.addEventListener('click', e => {
import(/* webpackChunkName: "script" */ './script.js');
});
- import() 为动态加载脚本,webpack 会生成类似以上动态创建
script
标签的代码 - import 里的注释为特殊含义的魔法注释,如果不设置 webpackChunkName,加载的脚本将被按数字次序命名
增加 webpack.config.js
如下
const HtmlWebpackPlugin = require('html-webpack-plugin');
const PreloadWebpackPlugin = require('preload-webpack-plugin');
module.exports = {
entry: './src/main.js',
plugins: [
new HtmlWebpackPlugin({
filename: 'preload.html'
}),
new PreloadWebpackPlugin()
]
}
- HtmlWebpackPlugin 将自动生成相应的 html 文件,默认为 index.html,这里通过设置
filename
选项更改 - PreloadWebpackPlugin 为 HtmlWebpackPlugin 的插件,默认为其动态加载资源增加链接类型为
preload
的link
标签,其as
的值可根据后缀自动判断
PreloadWebpackPlugin 也支持 prefetch,需要增加 rel
选项为 prefetch
new HtmlWebpackPlugin({
filename: 'prefetch.html'
}),
new PreloadWebpackPlugin({
rel: 'prefetch'
})
不过要同时生成 preload.html 和 prefetch.html,需要在对应的 PreloadWebpackPlugin 中设置 excludeHtmlNames
排除对方,否则会同时产生 preload 和 prefetch 的 link 标签
new HtmlWebpackPlugin({
filename: 'preload.html'
}),
new HtmlWebpackPlugin({
filename: 'prefetch.html'
}),
new PreloadWebpackPlugin({
excludeHtmlNames: ['prefetch.html']
}),
new PreloadWebpackPlugin({
rel: 'prefetch',
excludeHtmlNames: ['preload.html']
})
构建文件(也可在 package.json
中增加 build
脚本)
npx webpack
dist
文件夹中将生成 prefetch.html 和 preload.html,访问本地服务器对应地址,即可得到与以上静态页面同样的效果
总结
此文使用静态页面和 webpack 打包两种方式演示了预取和预加载的实现,完整代码见 GitHub,主要技术点如下:
- ELEMENT.appendChild 动态创建脚本
- import() 动态加载脚本并设置魔法注释
- html-webpack-plugin 及其插件的配置
prefetch 和 preload 及 webpack 的相关处理的更多相关文章
- prefetch vs preload vs prerender vs preconnect All In One
prefetch vs preload vs prerender vs preconnect All In One 前端性能优化 prefetch 预获取 https://developer.mozi ...
- Webpack 4教程 - 第八部分 使用prefetch和preload进行动态加载
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者.原文出处:https://wanago.io/2018/08/13/webpack-4-course-part ...
- webpack优化相关操作
1.缩小文件搜索的范围 • 优化loader配置 尽量精确使用 include 只命中需要的文件. module.exports = { module: { rules: ...
- webpack 配置文件相关解说
博客地址:https://ainyi.com/10 webpack - 什么是webpack: WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它 ...
- prefetch和preload
前面的话 基于VUE的前端小站改造成SSR服务器端渲染后,HTML文档会自动使用preload和prefetch来预加载所需资源,本文将详细介绍preload和prefetch的使用 资源优先级 在介 ...
- webpack配置相关的页面异常
原文:https://www.cnblogs.com/Hsong/p/9023341.html 前言 在团队协作开发中,为了统一代码风格,避免一些低级错误,应该设有团队成员统一遵守的编码规范.很多语言 ...
- 如何配置 webpack 支持 preload, prefetch, dns-prefetch
如何配置 webpack 支持 preload, prefetch, dns-prefetch webpack , preload, prefetch https://webpack.js.org/p ...
- Preload,Prefetch 和它们在 Chrome 之中的优先级
前言 上周五到的时候,想起之前在手游平台上有处理dns-prefetch的优化,那这篇分享的就更仔细了.今日早读文章由@gy134340翻译并授权分享. 正文从这开始- 今天我们来深入研究一下 Chr ...
- Web 性能优化:Preload与Prefetch的使用及在 Chrome 中的优先级
摘要: 理解Preload与Prefetch. 原文:Web 性能优化:Preload,Prefetch的使用及在 Chrome 中的优先级 作者:前端小智 Fundebug经授权转载,版权归原作者所 ...
随机推荐
- ios shell打包脚本 xcodebuild
#! /bin/bash project_path=$() project_config=Release output_path=~/Desktop build_scheme=YKTicketsApp ...
- hive的基本操作与应用
通过hadoop上的hive完成WordCount 启动hadoop Hdfs上创建文件夹 创建文件夹 上传文件至hdfs 启动Hive 创建原始文档表 导入文件内容到表docs并查看 用HQL进行词 ...
- Sql练习201908131742
orderdt_jimmy表结构: sql查询: then amount end) t1, then amount end) t2, then amount end) t3 from orderdt_ ...
- 求组合数m_n
下面为求取组合数的代码: #include <stdio.h> #define MAX 10009 ]; void print(int *v, int length) { ; for (; ...
- webpack4.x 从零开始配置vue 项目(三)
目标 babel 转换ES6 语法 postCss 增强css功能,如自动增加前缀 vue-loader 解析vue 文件 实现基本的vue项目开发环境,打包等 Babel 由于浏览器对es6语法兼容 ...
- Fiddler插件---将Mapi请求自动转为HTTPRunner测试用例(YAML格式)
背景 继之前鼓捣出了Mapi解密插件之后,在团队内已经使用了三年之久,一跃成为团队最爱欢迎的测试工具之一(加个之一,低调谦虚一点). 随着团队推行HttpRunner搞接口自动化:编写和维护Case带 ...
- 记录一次简单的springboot发送邮件功能
场景:经常在我们系统中有通过邮件功能找回密码,或者发送生日祝福等功能,今天记录下springboot发送邮件的简单功能 1.引入maven <!-- 邮件开发--><dependen ...
- ssh配置文件最佳实践(伪)
时间:2019-09-11 说明:以下配置是基于常用安全设置,并增加阿里云要求的安全参数而成 版本:第一版 # 1.监听相关 ## 指定ssh端口 Port 1314 ## 只监听网络协议 Addre ...
- vue技术栈进阶(02.路由详解—基础)
路由详解(一)--基础: 1)router-link和router-view组件 2)路由配置 3)JS操作路由
- PHP中嵌入正则表达式常用的函数
PHP中嵌入正则表达式常用的函数有四个: 1.preg_match() :preg_match() 函数用于进行正则表达式匹配,成功返回 1 ,否则返回 0 . 语法:int preg_match( ...