Preload与Prefetch的区别以及webpack项目中如何优化

摘要:
预加载和预取之间的区别在于预加载是一种声明性获取,它可以强制浏览器请求资源,而不会阻止文档的加载事件。对于预加载,一旦页面关闭,它将立即停止预加载以获取资源。对于预取资源,即使页面关闭,预取启动的请求也将不间断地继续。预加载和预取的优先级,预加载使用“as”或“type”属性来指示其资源请求的优先级。使用预加载或预取可能会浪费用户的带宽,特别是在没有缓存的情况下。未使用的预加载资源将在Chrome控制台中的onload事件后3秒发出警告。

preload 与prefetch 的区别

  • preload 是一个声明式 fetch,可以强制浏览器在不阻塞 document 的 onload 事件的情况下请求资源

    preload 顾名思义就是一种预加载的方式,它通过声明向浏览器声明一个需要提交加载的资源,当资源真正被使用的时候立即执行,就无需等待网络的消耗。

  • prefetch 告诉浏览器这个资源将来可能需要,但是什么时间加载这个资源是由浏览器来决定的。

    若能预测到用户的行为,比如懒加载,点击到其它页面等则相当于提前预加载了需要的资源。

使用方法:

通过 Link 标签进行创建:

<link rel="preload" href="http://t.zoukankan.com/path/to/style.css" as="style">

在 HTTP 响应头中加上 preload 字段:

Link: <https://example.com/other/styles.css>; rel=preload; as=style

这种方式比通过 Link 方式加载资源方式更快,请求在返回还没到解析页面的时候就已经开始预加载资源了

prefetch 预判加载与preload 使用方法是一样的

和的缓存行为

当资源被 preload 或者 prefetch 后,会从网络堆栈传输到 HTTP 缓存并进入渲染器的内存缓存。 如果资源可以被缓存(例如,存在有效的 cache-control 和 max-age),它将存储在 HTTP 缓存中,可用于当前和未来的会话。 如果资源不可缓存,则不会将其存储在 HTTP 缓存中。 相反,它会被缓存到内存缓存中并保持不变直到它被使用。

副作用

正确使用 preload/prefetch 不会造成二次下载,也就说:当页面上使用到这个资源时候 preload 资源还没下载完,这时候不会造成二次下载,会等待第一次下载并执行脚本。

对于 preload 来说,一旦页面关闭了,它就会立即停止 preload 获取资源,而对于 prefetch 资源,即使页面关闭,prefetch 发起的请求仍会进行不会中断

preload 和 prefetch 的优先级、

preload 用 “as” 或者用 “type” 属性来表示他们请求资源的优先级(比如说 preload 使用 as=”style” 属性将获得最高的优先级)。没有 “as” 属性的将被看作异步请求,“Early”意味着在所有未被预加载的图片请求之前被请求(“late”意味着之后)

例如,preload as =“style”将获得最高优先级,而as =“script”将获得低优先级或中优先级。 这些资源也遵循相同的CSP策略(例如脚本受 script-src 约束)。

下面是在 Blink 内核的 Chrome 46 及更高版本中不同资源的加载优先级情况著作权归作者所有。

2019-0411-06.png

从图中可以看出:(以 Blink 为例)

  1. HTML/CSS 资源,其优先级是最高的

  2. font 字体资源,优先级分别为 Highest/High

  3. 图片资源,如果出现在视口中,则优先级为 High,否则为 Low

而 script 脚本资源就比较特殊,优先级不一,脚本根据它们在文件中的位置是否异步、延迟或阻塞获得不同的优先级:

  1. 网络在第一个图片资源之前阻塞的脚本在网络优先级中是 High

  2. 网络在第一个图片资源之后阻塞的脚本在网络优先级中是 Medium

  3. 异步/延迟/插入的脚本(无论在什么位置)在网络优先级中是 Low

当页面 preload 已经在 Service Worker 缓存及 HTTP 缓存中的资源时会发生什么?

这各情况来说是比较少的,但通常来说,会是比较好的情况 —— 如果资源没有超出 HTTP 缓存时间或者 Service Worker 没有主动重新发起请求,那么浏览器就不会再去请求这个资源了。

如果资源在 HTTP 缓存中(在SW缓存和网络之间),那么 preload 会从相同的资源中获得缓存命中。

使用 preload 或 prefetch,可能会浪费用户的带宽,特别是在资源没有缓存的情况下

没有用到的 preload 资源在 Chrome 的 console 里会在 onload 事件 3s 后发生警告。

webpack优化之preload和prefetch

单页面应用由于页面过多,可能会导致代码体积过大,从而使得首页打开速度过慢。所以切分代码,优化首屏打开速度尤为重要

但是所有的技术手段都不是完美的。当我们切割代码后,首屏的js文件体积减少了好多。但是也有一个突出的问题:

那就是当跳转其他页面的时候,需要下载相应页面的js文件,这就导致体验极其不好,每一次点击访问新页面都要等待js文件下载,然后再去请求接口获取数据。频繁出现loading动画的体验真的不好

所以如果我们在进入首页后,在浏览器的空闲时间提前下好用户可能会点击页面的js文件,这样首屏的js文件大小得到了控制,而且再点击新页面的时候,相关的js文件已经下载好了,就不再会出现loading动画。

动态引入js文件,实现code-splitting,减少首屏打开时间

按引入情况加载,只需添加注释即可

  • 代码分割注释:/*webpackChunkName: 'mp-supports'*/

  • prefetch注释:/* webpackPrefetch: true */

更多的,可以查看 webpack 注释黑魔法:https://webpack.js.org/api/module-methods/#magic-comments

使用案例

const { default: lodash } = await import(/* webpackChunkName: "lodash" */ /* webpackPrefetch: true */ 'lodash');
// Multiple possible targets
import(
  /* webpackInclude: /.json$/ */
  /* webpackExclude: /.noimport.json$/ */
  /* webpackChunkName: "my-chunk-name" */
  /* webpackMode: "lazy" */
  /* webpackPrefetch: true */
  /* webpackPreload: true */
  `./locale/${language}`
);

原来还可以叠罗汉的

react项目

// 代码分割后的react组件
const Demo = asyncComponent(() => import(
 /*webpackChunkName: 'mp-supports'*/
  './views/Brand'
))

// 路由引入
<Route path="/" component={App}>
    <Route path="/brand" component={Demo} />
 </Route>

首页组件的生命周期:

/ 在接口取的数据后,进行prefetch
componentDidUpdate({ topics }) {
  if( topics.length === 0 && this.props.topics.length > 0 ) {
   // 实行prefetch,注意只有webpack 4版本才支持prefetch功能。
    import(
        /* webpackPrefetch: true */
        /*webpackChunkName: 'topic'*/
        "../topic"
      )
  }
}

参考文章:

3 Code Splitting Patterns For VueJS and Webpack https://medium.com/js-dojo/3-code-splitting-patterns-for-vuejs-and-webpack-b8fff1ea0ba4

使用 Proload/Prefetch 优化你的应用 https://github.com/happylindz/blog/issues/17

Web 性能优化:Preload,Prefetch的使用及在 Chrome 中的优先级 https://segmentfault.com/a/1190000018828048

webpack 中,webpackPrefetch、webpackPreload 和 webpackChunkName 的区别是什么? https://www.cnblogs.com/skychx/p/webpack-webpackChunkName-webpackPreload-webpackPreload.html

转载本站文章《Preload与Prefetch的区别以及webpack项目中如何优化》,
请注明出处:https://www.zhoulujun.cn/html/webfront/SGML/html5/2020_0702_8505.html

免责声明:文章转载自《Preload与Prefetch的区别以及webpack项目中如何优化》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇连通性CSS技巧:文本换行及溢出隐藏下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

如何查看网页缓存的密码

原理其实很简单:input的text与password 1.把鼠标停放在 密码区,单机右键”查看原素“得到的代码 <input name="pwd" type="password" size="15"> 与文本区块进行切换就可以查看出密码了 <input name="pwd" type="text" size="15">...

“快准狠”找到Linux系统内存的问题

内存性能指标 最容易想到的是系统内存使用情况,比如已用内存、剩余内存、共享内存、可用内存、缓存和缓冲区的用量等。 已用内存和剩余内存很容易理解,就是已经使用和还未使用的内存。 共享内存是通过 tmpfs 实现的,所以它的大小也就是 tmpfs 使用的内存大小。tmpfs 其实也是一种特殊的缓存。 可用内存是新进程可以使用的最大内存,它包括剩余内存和可回收缓...

C#系统缓存全解析

系统缓存有什么好处呢?举个简单的例子,你想通过网页查询某些数据,而这些数据并非实时变化,或者变化的时间是有期限的。例如查询一些历史数据。那么每个用户每次查的数据都是一样的。如果不设置缓存,ASP.NET也会根据每个用户的请求重复查询n次,这就增加了不必要的开销。所以,可能的情况下尽量使用缓存,从内存中返回数据的速度始终比去数据库查的速度快,因而可以大大提供...

如何修改phpstorm的缓存目录

相信使用phpstorm的人们都被缓存目录的大小困扰过。怎么修改到其它地方呢? 1. 找到idea.properties 文件,配置信息都在此文件中,F:Program FilesJetBrainsPhpStorm 2018.1.6in 按照自己的安装目录修改就可以。 2. 3. 图中红框的位置,默认时没有下面黑色代码的,拷贝出来,修改为要保存的地址重启p...

Spring3.1 Cache注解

@Cacheable 支持如下几个参数: value:缓存位置名称,不能为空,如果使用EHCache,就是ehcache.xml中声明的cache的name key:缓存的key,默认为空,既表示使用方法的参数类型及参数值作为key,支持SpEL condition:触发条件,只有满足条件的情况才会加入缓存,默认为空,既表示全部都加入缓存,支持SpEL 例...

mysql 禁用查询缓存 query cache

os:centos 6.8 mysql: 5.5.49 MySQL Query Cache 会缓存select 查询,但是在调优sql查询及测试数据库的性能时需要禁用该功能。 查看变量、状态 mysql> show global variables like '%cache%'; +------------------------------+--...