关于web.dev的一篇非常有趣的文章是关于模块worker的https://web.dev/module-workers/的,我们可以将worker的模块加载为预加载的模块,这意味着可以对其进行预加载甚至预解析并预取其依赖项(https://web.dev/module-workers/#preload-workers-with-modulepreload)。
如果我是对的,不仅Web-Workers可以作为预加载模块加载,这适用于任何js脚本,字体,css等。
<link rel="preload" href="fonts/cicle_fina-webfont.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="style.css" as="style">
<link rel="preload" href="main.js" as="script">
本文中有一个语词,这让我很烦恼:这是否意味着模块加载也缓存了已解析的代码,这意味着如果我们在顶部使用import语句将其包含在主线程和工作线程中,则不会再次对其进行解析?
但是,这不会发生,只要我们在任何 Realm (主线程,工作线程)上导入模块,它们就独立地执行其导入,然后在以后的将来,它们将在自己的 Realm 中引用其解析的缓存实例。
我真的很困惑,作者到底想解释什么。以及我们如何实现它。
相关文章:https://developers.google.com/web/updates/2017/12/modulepreload#does_preloading_modules_help_performance
最佳答案
我不确定本文从何处得到这个想法,但在阅读规范时,我看不到任何证据表明
如果我们检查规格,fetch and process the linked resource algorithm for modulepreload
links算法在步骤5进行
然后,在步骤11中将此设置对象传递给fetch a modulepreload module script graph算法,该算法本身将使用相同的设置对象调用fetch a single module script和fetch the descendants of and link(最终还将调用获取单个模块脚本)。
在此settings object中可以找到module map,并且此模块映射将在fetch a single module script中使用,以避免多次请求相同的模块(缓存)。
应该注意的是,虽然此算法为creates a module script,但尚未执行。
因此,从那里我们可以看到modulepreload
链接不仅将获取链接的资源,还将获取所有子资源,甚至为这些资源中的每一个准备模块脚本,这与本文中的其他说法非常一致。
但是,这不足以得出有关有问题的报价的任何结论。
我们必须检查有关dedicated Workers constructor的规范,它将调用run a worker算法,将传递给我们的modulepreload
链接使用的相同文档的对象设置,这次称为“外部设置”。
在此run a worker算法的步骤8中,它要求
并且此set up a worker environment settings object算法将仅使用文档的外部设置来设置inherited origin
内部值和新设置对象的top-level origin
属性。
这个新的设置对象的模块映射为the one of its global scope,它“最初是空的”。
工作人员的环境设置对象不会从外部设置继承其模块映射。
因此,当工作人员将自己作为fetch a single module script的一部分调用这些fetch the descendants of and link和fetch a module worker script graph算法时,它将检查的一个模块映射是其自身在设置的模块映射中,在处,它将找不到我们modulepreload
链接创建的模块脚本。
因此,通过阅读规范,我会说modulepreload
链接仅对模块Workers有帮助,因为HTTP缓存已经下载了图中的所有文件。如果只打算在Worker中使用这些模块,那么让它在文档侧准备模块脚本实际上会适得其反,并且简单的prefetch
链接可能会更好,但您必须创建一个这样的链接每个子资源。