Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug Report] 通过 Vite3 生产环境构建的产出 Toast 组件部分样式被 Popup 组件样式覆盖 #11049

Closed
jiadesen opened this issue Sep 15, 2022 · 14 comments

Comments

@jiadesen
Copy link
Contributor

jiadesen commented Sep 15, 2022

重现链接

https://codesandbox.io/s/vant-3-issue-template-forked-n4xyst?file=/src/App.vue

Vant 版本

3.6.2

描述一下你遇到的问题。

重现链接的环境并不复现该问题,代码可参考,且 vue-cli 和 vite3 的开发环境均不复现该问题!问题出在生产构建的产出,vue-cli 产出还没有时间验证,vite3 产出有问题,使用了 unplugin-vue-components 自动导包和 vite-plugin-imp 自动导入函数式组件样式,问题见下图,Toast 组件部分样式被 Popup 组件样式覆盖
infoflow 2022-09-16 00-03-09

开发环境正常展示如下:
infoflow 2022-09-16 00-51-20

重现步骤

1、vite3 项目使用 unplugin-vue-components 自动导包和 vite-plugin-imp 自动导入函数式组件样式
2、空白页面点击一个按钮展开 popup
3、popup 里放置一个按钮点击弹出一个 toast,开发环境 toast 正常!
4、重要!!使用 vite3 构建产出,并使用 vite3 预览服务查看产出,即可复现该bug

设备/浏览器

No response

@jiadesen
Copy link
Contributor Author

问题其实就是开发和构建环境 函数式组件样式载入顺序不同导致优先级不同的问题,如果不使用vite-plugin-imp自动导入函数组件样式,在项目的入口文件手动引入样式是可以解决该问题

@chenjiahan
Copy link
Member

vite 的样式打包是有 bug 的,尤其是在 dynamic import 的场景下,可以参考 #10953

vue-cli 不会出现该问题

@chenjiahan
Copy link
Member

@jiadesen
Copy link
Contributor Author

jiadesen commented Oct 22, 2022

不行,还是有存在差异的地方,全量引入样式非常省心,项目体量稍微上来以后,构建体积就一样了;
甚至老的vue-cli项目(多入口50+路由)改成全量引入以后,构建体积竟然减少了将近3MB,后来分析原因是每个页面组件引入顺序不同,几乎所有页面都重复打包了组件样式文件,样式重复十分严重,也确实导致了触发方式比较刁钻的样式问题。看来按需引入并非完美啊

@chenjiahan
Copy link
Member

甚至老的vue-cli项目(多入口50+路由)改成全量引入以后,构建体积竟然减少了将近3MB

这个不太合理,可以配置 webpack splitChunks 规则来优化试试。

不过按需引入确实不一定适合所有场景,还是得根据实际情况来使用

@jiadesen
Copy link
Contributor Author

jiadesen commented Oct 23, 2022

甚至老的vue-cli项目(多入口50+路由)改成全量引入以后,构建体积竟然减少了将近3MB

抱歉,重新分析了一下,我的错,整体构建体积优化了300KB左右,如下图,中间的方案是项目刚开始根据文档推荐使用 babel-plugin-import 的按需加载方案,当然现在已经不再推荐

构建差异

js 最终产出差异不大,Stat 分析中 babel-plugin-import 的构建表现很有意思,unplugin-vue-components 的构建最优

  • Stat 分析:

imageimageimage

  • Parsed 分析:

imageimageimage

最终构建体积的差异主要表现在样式产出上,这一点也很好理解,主要是5个入口公用了同一个 chunk-vendors.css,这意味着整个项目中 vant 的样式仅有这一份

infoflow 2022-10-23 19-38-00

分析到最后,从首次访问性能考虑,不管首次访问哪个入口,按需加载方案都提供了最优的首屏性能;从入口之间首次跳转考虑,全量引入方案借助资源缓存提供了最优跳转体验。当然,良好网络条件下,只要不是太老旧的手机,实际用户体验,几乎无差异。

@chenjiahan
Copy link
Member

嗯嗯,上面的分析基本准确。

从优化的角度考虑来说,最佳的方案是在按需引入的基础上,再将一些公共的样式抽取到 Common Chunk 中,这样兼顾了首屏性能和跳转性能。

@jiadesen
Copy link
Contributor Author

Common Chunk 非常容易被一些轻度依赖 vant 的入口(比如,某入口只用了个按钮组件)降低其价值。

@jiadesen
Copy link
Contributor Author

jiadesen commented Oct 23, 2022

全量引入样式的缺点非常明确:chunk-vendors.css 对轻度依赖 vant 的入口非常不友好。所以,我觉得按需引入还应该提供这么一种模式:从整体项目维度考虑,不论几个入口,将所有用到的 vant 组件样式,以最初设计的样式顺序构建 chunk-vendors.css,本质是对 vant/lib/index.less 进行 treeshking,这个策略虽然没有从根本上解决“不友好”,但总比什么都不做要好一些。这对那些对 vant 组件的整体依赖不超过 50% 的多入口项目非常有价值。

@chenjiahan
Copy link
Member

从整体项目维度考虑,不论几个入口,将所有用到的 vant 组件样式,以最初设计的样式顺序构建 chunk-vendors.css

这个不就是按需引入 + common chunk 的结果吗

@jiadesen
Copy link
Contributor Author

确实,vue-cli 很容易做到这一点

image

vite3 还在研究。

@jiadesen
Copy link
Contributor Author

关于样式产物,又发现了另外一个问题,项目里有很多 vue 单文件组件,这些组件复用几次,产物里对应组件样式几乎就重复几次(这个貌似是因为组件引入顺序不同导致的重复),关于这个问题,大佬能提供个解决思路么,万分感谢~

@chenjiahan
Copy link
Member

我猜是因为这些组件是在不同的异步 chunk 里引用的,所以有这个现象,这个也可以通过配置 splits chunks 规则来合并一部分

@jiadesen
Copy link
Contributor Author

这些组件是在不同的异步 chunk 里引用

确实如此,非常感谢

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants