You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
timeoutFn(()=>{// Find all links & Connect them to IO if allowed(options.el||document).querySelectorAll('a').forEach(link=>{// If the anchor matches a permitted origin// ~> A `[]` or `true` means everything is allowedif(!allowed.length||allowed.includes(link.hostname)){// If there are any filters, the link must not match any of themisIgnored(link,ignores)||observer.observe(link);}});},{timeout: options.timeout||2000,});
预加载的好与不好
预加载意味着会发更多的请求,并且很可能用户最终也不会使用,这些流量会造成更大的服务器压力,换句话就是你会为此花更多钱。
好处就是用户体验会好点,对于网速很快的用户来说提升只是一点点,对于网速稍慢的用户来说提升会更明显。
参考资料
关于 React.lazy 和动态 import 的一些测试
参考 Lazy loading (and preloading) components in React 16.6 | by Rodrigo Pombo | HackerNoon.com | Medium 做了一些测试。
不做动态 import
加上动态 import
加上动态 import 并提前下载文件
加上动态 import 并在鼠标 hover 时下载文件
封装一下,方便应用到其它组件
如果动态 import 的组件 A 里面还动态 import 了其它的组件 B
这种情况的话,是会在需要展示组件 B 的时候才去下载组件 B 的代码,因为你在鼠标移上去的时候只预加载了组件 A 。
直接使用 loadable-components 库来做预加载
react-router 推荐的 code splitting 库是 loadable-components ,这个库是支持 预加载 功能的。
按路由代码后能做预加载
上面说的都是页面中某个次要内容的代码分割和预加载,下面来进入正题,按路由切割代码后,能在当前路由预加载其它路由的代码吗?
自己封装一下 Link
我们可以把 react-router-dom 库的 Link 组件再封装一层来实现预加载。
把路径以及对应的组件定义为数组,方便我们封装的 LinkWithPreload 去遍历数组找到组件,然后去执行组件的 preload 就好了。
在需要使用 Link 的地方就
<LinkWithPreload to='/xxx'>
查看</LinkWithPreload>
就可以了。这里是鼠标移上去的时候预加载,如果你想,也可以改为使用 Intersection Observer ,判断 Link 组件进入可见区域时就预加载。
在什么时候进行预加载也是一种权衡,尽早预加载可以保证跳转页面的时候资源已经加载好了,但是会不可避免造成一些不必要的加载,因为你不知道用户会访问哪些页面。(当然如果你想你可以结合统计工具的数据,只对用户经常访问的页面做预加载来增加命中率 hhh)
直接使用 quicklink 库
https://github.com/GoogleChromeLabs/quicklink
它是监听的 Link 进入可视区域就进行预加载。
在 create-react-app 中使用:https://github.com/GoogleChromeLabs/quicklink/blob/master/demos/spa/README.md
使用这个库会需要配置 webpack-route-manifest 插件,这个插件会生成下面这个东西,然后就可以根据路由去预加载了。
![image](https://user-images.githubusercontent.com/22369504/223307199-fe935062-8a90-4728-9edd-9ffbf92c6989.png)
quicklink 的相关实现见 https://github.com/GoogleChromeLabs/quicklink/blob/master/src/react-chunks.js#L61 和 https://github.com/GoogleChromeLabs/quicklink/blob/master/src/index.mjs#L60 。
它是等路由组件进入可视区域后,然后拿到路由组件中所有 a 标签,然后再对应去做预加载。
总结
为了减少加载一个页面时需要下载的代码,我们可以:
按路由切割代码,并预加载其它路由代码(Link hover 时或者进入可视区域时),这样跳转时下个页面加载会更快;
对弹窗、Tab 等当前不需要展示或者低优先级内容做代码切割,并预加载。
代码切割是为了减少必要代码的体积,预加载是为了低优先级组件代码在需要时也能尽快展示。
preload、prefetch、动态 import 区别
preload 和 prefetch 是 HTML link 标签的一个用法,用于提示浏览器去提前下载资源。preload 是希望提前下载当前页面的资源。prefetch 是希望提前下载其它页面的资源。
动态 import 是 JS 的一个语法,Webpack 打包时会把动态 import 的部分打包为单独的文件。可以用于实现按路由切割代码,或者把弹窗等低优先级界面代码从主界面代码切割出去,这样来加快主界面的加载速度。
当你希望预加载资源时,是使用 link 的 prefetch 还是说动态 import ,其实结果都是一样的,可以结合项目用的库来看怎么实现简单怎么来。
The text was updated successfully, but these errors were encountered: