请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

使用prefetch优化的问题

项目描述

我用webpack+vue写的项目,一个引导页面里,只有一张大的背景图,点击下一步换另一张图片,在点切换到下一张

代码如下

<div :style="{backgroundImage: 'url(' + this.image +')'}"></div>
const  cacheImg = {}
export default {
    data () {
        image: '',
        mode: 1,
        step: 1,
        cacheImg: {}
    },
    created () {
        const result = await this.loadImg(this.mode, this.step)
        this.image = result
    },
    methods: {
        async loadImg (mode, step) {
            const result = await import(`../assets/img/feature-guide${mode}_${step}.png`)
            this.setCacheImg(`${mode}_${step}`, result.default)
            return Promise.resolve(result.default)
        },
        setCacheImg (key, value) {
            cacheImg[key] = value
            const link =  document.createElement('link')
            link.as = 'image'
            link.rel = 'prefetch'
            link.href = value
            document.head.appendChild(link)
        },
    }
}

思路是想利用prefetch做预加载,每次点击都import()当前图片的下一张图片,并将结果缓存到cacheImg对象中并动态写入link标签。当真正请求当前图片的下一张图片的时候,去cacheImg对象中去找,使图片从prefetch中的缓存拿到。


https://img1.sycdn.imooc.com//szimg/62c40e8a08a6b28410010280.jpg

有几个问题

  1. 在webpack中利用注释的prefetch,是不是只支持组件,不支持图片,所以我才手动写入link标签

   2.不知道我这么做,是否正确,但是我看确实是走的prefetch的缓存

   3.我上图红框中,显示白页图标的,打开response,显示Failed to load response data: No data found for resource with giver identifier。这是为什么,我这图片加载进来了嘛。

   4.虽然做了prefetch,但是点击下一步,切换图片的时候,仍然屏幕会闪一下,这个怎么优化



正在回答 回答被采纳积分+3

1回答

Mr_Max 2022-07-06 10:15:06

同学你好!

非常好的优化尝试!

  1. webpack的prefetch注释确实是针对组件的,更准确说是针对chunk的。

  2. 你可以自己提前请求来图片然后缓存,或者用prefetch/preload交给浏览器去做,浏览器有它自己的缓存。另外,可以一上来直接prefetch/preload后面的所有图片,引导页的图片最终都要加载吧。如果前面还有其他页面,最好在前面的页面做预加载。推荐你看下这个文章,考虑一下prefetch和preload的适用场景。https://medium.com/reloading/preload-prefetch-and-priorities-in-chrome-776165961bbf

  3. 这个看下有没跨域报错,但是图片貌似加载成功的,你截图里图1和图4都有预览。这个不是特别确实原因。

  4. 如果你是从自己的cacheImg缓存里取出图片资源,再交给浏览器去渲染,这个处理会慢一些。但我看你实际好像又是用的background-image: url(this.image). 你的this.image是图片资源路径?那实际是走浏览器的请求和缓存?prefetch不能保证一定会预加载。如果this.image是你从自己缓存取出的资源然后转成了base64再渲染,这个比较慢,肯定会闪白。

0 回复 有任何疑惑可以回复我~
  • 提问者 Mesry #1
    感谢老师的回答!
    
    我的cacheImg里,都是利用import()函数请求到的图片资源。比如一张图片的资源路径是../assets/imgs/1.png,我用import()函数拿到的是/static/img/1.3fa5027f.png。所以我的cacheImg是{1: /static/img/1.3fa5027f.png}。这个this.image其实也是/static/img/1.3fa5027f.png。我利用prefetch做的预加载,href也是/static/img/1.3fa5027f.png。这样就还是相当于每张图片动态请求了吧,没有交给浏览器自己去处理吧。但是我写href为../assets/imgs/1.png,又找不到图片。我这么做是不是还是不对?
    回复 有任何疑惑可以回复我~ 2022-07-06 11:49:27
  • Mr_Max 回复 提问者 Mesry #2
    OK, 如果你自己提前import图片进到你的缓存,用的时候从你的缓存取,就不用再让浏览器prefetch了。而如果用prefetch,就在之前的页面提前加prefetch link去获取资源,路径应该是../assets/imgs/1.png(除非你打算把图片直接放成本地资源,但是那样通常不合理)。
    回复 有任何疑惑可以回复我~ 2022-07-07 07:12:53
  • 提问者 Mesry 回复 Mr_Max #3
    好的老师,那也就是说,利用prefetch是一种方案,利用import()把所有图片加载过来放到缓存里是一种方案,但是放到缓存里的方案,每次点击下一张的时候,还是会走浏览器的请求,所以它的效果没有prefetch好。那我们import()请求过来的是图片的模块,不是图片的资源是吧,相当于还是没走网络请求?您说的把图片直接放成本地资源是什么意思呢?
    回复 有任何疑惑可以回复我~ 2022-07-07 17:16:12
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信