什么是prefetch?
这种“资源提示” 告诉浏览器这是一个在未来可能使用到的资源。
浏览器通常会在空闲状态取得这些资源,在取得资源之后搁在http缓存以便于实现将来的请求。如果有多个‘预请求提示’则会在浏览器空闲时排队执行。当浏览器离开空闲状态时正好在‘预请求’资源,那么浏览器会取消任何正在进行中的请求(同时会将部分响应数据放置在缓存中,而在header中继续使用content-range字段 )并停止处理‘预请求’队列。
总之:在闲置时获取资源
什么是preload?
这种“资源提示” 告诉浏览器这是一种在这次导航中必须的资源,只是会在之后才会被使用, chrome甚至会在资源加载后3秒没有被使用时打印一个警告
浏览器通常以中等优先级(非布局阻塞)获取此资源。
总之:正常获取,及早发现
为什么prefetch/preload有用?
preload用于更早地发现资源并避免发起类似瀑布一样的请求。 它可以将页面加载降低到2次往返(1. html,2。所有其他资源)。 使用它不会花费额外的带宽。
prefetch用于使用浏览器的空闲时间来加速将来的导航。 当用户未执行预期的未来导航时,使用它可能会花费额外的带宽。
代码分割
我们假设您使用webpack构建庞大的应用程序,并通过import()来使用按需加载仅加载用户当前所需的部分。
例如,我们有一个homepage,其中包含一个loginbutton,这个按钮用于打开一个登录模态框(loginmodal)。 登录之后会跳转到dashboardpage——可能包含其他按钮,但这些按钮不太常见。
为了获得更好的用户体验,你在loginbutton那里使用import("loginmodal") 来保持主页的体积达到最小。与之类似的,loginmodal包含import("dashboardpage")
现在,这个示例程序被拆分为至少3块:home-chunk,login-chunk,dashboard-chunk。 在初始加载时,只需要加载home-chunk,这会产生很好的用户体验。 但是当用户单击loginbutton时,在loginmodal打开之前会有一段延迟,因为需要加载应用程序的这一部分。 dashboardpage与之类似。
在webpack中使用预请求
新的prefetch功能可以改善这个工作流程。 并且这非常容易。
在loginbutton处,把import("loginmodal") 改成 import(/ webpackprefetch: true / "loginmodal")
同样的把 import("dashboardpage") 改成import(/ webpackprefetch: true / "dashboardpage")
这将告诉webpack在父块完成加载时预取(在浏览器空闲时间内)这个按需加载的模块。 在这个例子中:当home-chunk完成加载时,将login-chunk添加到预取队列。 当login-chunk完成加载(实际加载,而不是预取)时,将dashboard-chunk添加到预取队列。
假设home-chunk是一个入口,那么它将会被添加到html文件里。 login-chunk是一个按需加载模块,因此一旦login-chunk加载完成,webpack运行时将负责注入。
用这种方式将会提升用户体验:
当用户访问homepage时。 这时的用户体验和性能与以前一样。一旦homepage完成加载,浏览器就会进入空闲状态并开始在后台获取login-chunk。而用户并不会注意到这一点。 假设用户需要一些时间来查找loginbutton,那么预请求将在用户单击按钮之前完成。 当用户单击该按钮时,login-chunk已经位于http缓存中,浏览器仅会花费最少的时间来命中缓存中的数据,那么用户将立即看到loginmodal。 同时,webpack运行时将dashboard-chunk添加到预取队列,因此登录后加载dashboard-chunk也不需要额外的时间。
请注意,用户可能并不总是具有这种即时loginmodal体验。 对loginbutton来说,有许多因素会使chunk重新加载以至于延迟:慢速网络,用户快速点击,在带宽有限的设备上禁用预取,没有预取浏览器支持,块的执行速度非常慢,......
在webpack中使用preload
与import(/ webpackprefetch:true /“...”)类似,也可以使用import(/ webpackpreload:true /“...”)。 与预取相比,这有很多不同之处:
preload的块与父块并行加载。prefetch的块在父块完成之后开始加载。
preload的块具有中等优先级并立即下载。prefetch的块在浏览器空闲时间下载。
preload的块会被父块立即请求。 prefetch的块可能会在将来的任何时间请求
浏览器支持是不同的。
preload这种特性的用例很少见。 如果模块总是立即import()某些内容,则可以使用它。 如果一个组件依赖一个单独块中的大型库,那么这是有意义的。 示例:chartcomponent使用大的chartinglibrary。 它在使用时显示一个loadingindicator并立即导入(/ webpackpreload:true /“chartinglibrary”)。 当请求使用chartcomponent的页面时,也会通过请求图表库块。 假设页面块较小并且完成得更快,则将使用loadingindicator显示页面,直到已经请求的图表库块完成为止。 这将提供一点加载时间,因为它只需要一次往返而不是两次。 特别是在高延迟环境中。
如果使用webpackpreload不当实际上会损害性能,因此要小心使用它。
在考虑预加载与预请求时,您可能需要预请。 但是要注意:此声明与webpack import()有关。 在html页面中,您可能需要预加载。
多个prefetch的块
您可以将webpackprefetch标志添加到任意数量的import(),但请注意所有prefetch的块都会争夺带宽。 它们实际上是排队的,当用户请求它时,真正使用的块可能不会被预取。
当所有块被请求的可能性相同时,这不是一个大问题。 但是当某些块比其他块被访问的可能性更大时,您可能想要控制prefetch的顺序。
幸运的是,我们可以让你满意。 (注意这是一个高级用例。)
您可以传递数字作为值,而不是使用webpackprefetch:true。 webpack将按您指定的顺序预取块。比如:webpackprefetch:42将在webpackprefetch:1之前被预取,它将在webpackprefetch:true之前被预取,它将在webpackprefetch:-99999(如z-order)之前被预取。 实际上,true等价于为0。
webpackpreload与之类似,但我不认为您会需要它
常见问题
如果多个import()请求相同的块并且其中一些被预取/预加载怎么办?预加载胜过预取。 在同一类别中,更高优先级获胜。
如果浏览器不支持预取/预加载怎么办?它会被浏览器忽略。 webpack不会尝试做任何后备。 不管怎样这都是一个暗示,所以即使是支持它的浏览器也可能会忽略它,如果他们感觉如此。
prefetch/preload在入口点中不起作用。 有什么问题?webpack运行时只负责按需加载的块的prefetch/preload。 当在entry chunk中使用预取/预加载时,html会添加标记到html。 stats.json在entrypoints[].childassets中提供了信息
为什么不在每个import()上使用prefetch / preload?你浪费了很多带宽。 有选择地将它用于很可能被访问的import()也更有益。 不要浪费带宽。
我不需要/想要这个功能。 不使用它的成本是多少?只有在您的一个按需加载的块中使用此功能时,才会添加运行时代码。 因此,当不使用它时,您不必支付任何开销。
我已经在import()上有一个comment了。 我可以添加多个吗?是的,要么用单独的comment分开,要么在单独的评论中:
import( /* webpackchunkname: "test", webpackprefetch: true */ "loginmodal")// orimport( /* webpackchunkname: "test" */ /* webpackprefetch: true */ "loginmodal")// spacing optional
我使用rollup构建我的库,并使用import(), 我的库中使用webpack的用户可以从prefetch中获益吗?是的,您可以将webpack魔术注释添加到import()中,rollup将保留注释。 当使用webpack构建它的结果时,它将使用注释。 如果没有使用webpack构建,评论将被minimizers删除。
我不确定是否为特定import()添加预取可以提高性能。 我应该加吗?最好的衡量标准。 a / b测试。 这里没有一般建议。 它取决于用户访问此应用程序路径的概率。
我已经有一个service worker,可以在加载时缓存整个应用程序。 使用预取对我有意义吗?这取决于您的应用程序。 通常,这种service worker无顺序加载应用程序的所有资产,而预取允许指定顺序并依赖于用户在应用程序中的实际位置。 预取也可以提高带宽效率,并且只能在浏览器空闲时下载。 与第一次用户导航发生时相比,测量在低带宽环境中下载整个应用程序所需的时间。 在大型应用程序中,使用预取代替是有意义的。
我想将初始页面加载拆分为关键资源和非关键资源,并按此顺序加载它们。 预加载有帮助吗?是的,您可以将关键资源放入入口点,将非关键资源放在import(/webpackpreload:true/)之后。 注意不要忘记为entry chunk 添加(在子标记之前)。
南京奥体健身步道变身来袭如何选择邢台微信小程序开发公司?做好微商营销推广只需五步SEO培训机构常见陷阱做网站优化时要注意不要过度经久不衰的SEO到底有多牛?网站建设用户体验是什么?云存储:企业需要在两个方面控制云存储成本