测试A:那啥!抠图仔,线上样式怎么点着点着就出问题了。
前端:啥?线上css样式错乱了?你是不是有缓存啊!清下缓存试试。
测试A(内心戏:这抠图仔一有问题就赖缓存):清缓存后,还有啊!你看看吧!
前端:见鬼了,我本地没复现啊。
在某次迭代中,在做产品体验的时候发现从申请记录页面跳转我的订单,在切回来,发现申请记录页样式错乱了。本地调试发现没有该问题。
为什么会出现这种场景?为什么该问题测试环境会出现,本地环境未复现?
调试发现 .ant-card可以从多个chunk文件引入,切换到network面板发现,2966....chunk.css文件是在我们跳转到我的订单页面才引入的。也就是我的订单页面按需加载组件打包出来的样式文件。
到这其实就定位到问题所在了,相同组件在不同页面按需加载的时候css文件被重复打包了。
开发环境不会,是因为我们导入组件是直接导入的node_modules的es模块的文件,如图:
dynamicImport: {
loading: '@/Loading',
},
umi开启dynamicImport时,会启动按route分包,实现页面级别的按需加载,这种分包模式明显在处理antd的样式模块复用上出现了一些问题。
所以推荐项目开启该模式时,antd应该使用下面的方案二进行处理antd的样式,防止出现偶现的线上问题。
之前代码中会出现很多莫名其妙的!important去提高样式的权重,当然也有在页面级引入antd.css的,可能也是因为遇到了antd样式覆盖的问题。
// ...
optimization: {
splitChunks: {
chunks: 'all',
minSize: 30000,
minChunks: 2,
automaticNameDelimiter: '.',
cacheGroups: {
antd: {
name: 'antdesigns',
test: /[\/]node_modules[\/](antd|antd-mobile|@ant-design)[\/]/,
priority: 20,
},
vendors: {
name: 'vendors',
test({ resource }: any) {
return /[\/]node_modules[\/]/.test(resource);
},
priority: 10,
},
},
},
},
// ...
优化后如图所示,申请记录页面跳转到我的订单页面再跳回来,.ant-card并没有多产生一个css文件引入。整个dist文件包体积从116.5M到108.4M,降低了8.1M。
webpack.docschina.org/plugins/spl…
警告
选择了默认配置为了符合 Web 性能最佳实践,但是项目的最佳策略可能有所不同。如果要更改配置,则应评估所做更改的影响,以确保有真正的收益,所以我们做上述分包策略时,需要根据实际项目情况来处理。
// 下面这个配置对象代表 SplitChunksPlugin 的默认行为。
module.exports={//...
optimization: {
splitChunks: {
// 有效值为 all,async 和 initial
chunks: 'async',
// 生成 chunk 的最小体积(以 bytes 为单位)。
minSize: 20000,
// 通过确保拆分后剩余的最小 chunk 体积超过限制来避免大小为零的模块。
minRemainingSize: 0,
// 拆分前必须共享模块的最小 chunks 数。
minChunks: 1,
// 按需加载时的最大并行请求数。
maxAsyncRequests: 30,
// 入口点的最大并行请求数。
maxInitialRequests: 30,
// 强制执行拆分的体积阈值和其他限制(minRemainingSize,maxAsyncRequests,maxInitialRequests)将被忽略。
enforceSizeThreshold: 50000,
/**
* 缓存组可以继承和/或覆盖来自 splitChunks.* 的任何选项。
* 但是 test、priority 和 reuseExistingChunk 只能在缓存组级别上进行配置。
* 将它们设置为 false以禁用任何默认缓存组。
*/
cacheGroups: {
defaultVendors: {
/**
* 控制此缓存组选择的模块。省略它会选择所有模块。
* 注:使用/是因为要同时适配unix和windows系统
*/
test: /[\/]node_modules[\/]/,
// 优先级,默认值0
priority: -10,
// 如果当前 chunk 包含已从主 bundle 中拆分出的模块,则它将被重用,而不是生成新的模块。这可能会影响 chunk 的结果文件名。
reuseExistingChunk: true,
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
},
},
},
},
};
线上和本地运行结果不一致,一直是一件让前端开发者头痛的问题。造成这种情况的原因之一呢?是因为场景不一样,webpack提供了两种模式。
我们要杜绝发生线上和本地运行结果不一致的这种情况,需要我们深入了解项目中会用到的webpack,vite,rollup等前端工程化工具的内部打包机制。
作者:城主北宁
链接:https://juejin.cn/post/7346884660443988019
mg{border:none} 解决IE浏览器有边框问题, 而W3C浏览器无边框问题
选择器的兼容性问题
1 儿子选择器>
IE7开始兼容, IE6不兼容。
div>p{
color:red;
}
div的儿子p。和div的后代p的截然不同。
能够选择:
<div>
<p>我是div的儿子</p>
</div>
不能选择:
<div>
<ul>
<li>
<p>我是div的重孙子</p>
</li>
</ul>
</div>
2 序选择器
IE8开始兼容;IE6、7都不兼容
选择第1个li:
<style type="text/css">
ul li:first-child{
color:red;
}
</style>
选择最后一个1i:
ul li:last-child{
color:blue;
}
由于浏览器的更新需要过程,所以现在如果公司还要求兼容IE6、7, 那么就要自己写类名:
<ul>
<li class="first">项目</li>
<li>项目</li>
<li>项目</li>
<li>项目</li>
<li>项目</li>
<li>项目</li>
<li>项目</li>
<li>项目</li>
<li>项目</li>
<li class="last">项目</li>
</ul>
用类选择器来选择第一个或者最后一个:
ul li.first{
color:red;
}
ul li.last{
color:blue;
}
3 下一个兄弟选择器
IE7开始兼容, IE6不兼容。
+表示选择下一个兄弟
<style type="text/css">
h3+p{
color:red;
}
</style>
选择上的是h3元素后面紧挨着的第一个兄弟。
<h3>我是一个标题</h3>
<p>我是一个段落</p>
<p>我是一个段落</p>
<p>我是一个段落</p>
<h3>我是一个标题</h3>
<p>我是一个段落</p>
<p>我是一个段落</p>
<p>我是一个段落</p>
<h3>我是一个标题</h3>
<p>我是一个段落</p>
<p>我是一个段落</p>
<p>我是一个段落</p>
<h3>我是一个标题</h3>
选择器:
说IE6层面兼容的: 标签选择器、id选择器、类选择器、后代、交集选择器、并集选择器、通配符。
p
#box
.spec
div p
div.spec
div,p
*
IE7能够兼容的:儿子选择器、下一个兄弟选择器
div>p
h3+p
IE8能够兼容的:序选择器
ul li:first-child
ul li:last-child
border-style兼容性问题
比如, border:10px ridge red; 在chrome和firefox、IE中有细微差别:
如果公司里面的设计师, 处女座的, 追求极高的页面还原度, 那么不能使用css来制作边框。
就要用到图片, 就要切图了。所以, 比较稳定的就几个:solid、dashed、dotted, 其他的边框样式尽量不要用。
何神奇呢?先来简单介绍一下背景,接下来再说一下这个现象如何神奇。
出问题的是一个即时聊天工具插件,被嵌入到客户的第三方程序中。
工程师说,我们自己的例子程序是没问题的,而且也不是所有的客户端都有问题。
他还提到一点,在客户的内网中没有问题,但是通过VPN映射到其他局域网中就有问题。
工程师还做了一个测试,将正在运行中的插件程序地址带参数拷贝出来,再粘贴到浏览器中浏览也没有问题。
工程师还说,第三方程序是运行在自己的浏览器中的。
我心想,这么牛!自己开发的浏览器?
应该说,这个工程师还是比较负责的,该做的测试都做了,最终没有办法,才找到开发。
工程师把远程环境弄好后,我连接上去看,又把工程师做过的验证都复现了一遍,现象的确如他所说。
这个时候,我也感觉有点蒙圈,为什么我们Demo可以,浏览器也可以,就第三方程序中不行呢?
有两个可能的原因。
要么第三方程序和我们的程序有冲突。
要么第三方开发的浏览器有问题。
首先排查第一个原因。
但是,我怎么调试呢?第三方浏览器不能按F12呀!
这个时候,工程师出马了,说,点右键,然后,有个“调试”菜单。
我试了一下,还真的可以,这不就是那个熟悉的F12调试界面吗?
还是工程师牛,现场各种操作比程序员玩的溜。
这调试界面看起来怎么这么熟悉呢?原来是chrome浏览器呀!
为了确认到底是什么浏览器,我在控制台输入window.navigator,回车,打印出来的的确和chrome浏览器一模一样。
我就说做浏览器哪儿那么简单,不就是chrome包壳吗?
管他啥浏览器,解决问题才是正道。
先看看控制台有没有报错,没有,只看到第三方打的调试信息一直在跑,应该是在轮询什么。
然后再看看我们的页面元素还在不在,是在的。
为什么要看这个呢?
因为的确出现过第三方把我们的HTML元素直接删了的情况。
接下来再看看页面参数,看起来也没有问题,在控制台location.href连接到我们插件的地址,有问题,再复制到其他浏览器打开又是正常的。
整个过程并没有出现代码报错,说明应该不是和第三方程序冲突造成的异常,那么剩下来就只有浏览器的原因了。
我看了一下调试工具的application菜单,打开本地存储看了看,没有什么,再看了看cookie,有一个我们的cookie。
在控制台再次调用了一下我们的页面,cookie好像没有更新,感觉这个现象不对,应该要更新呀!
删了吧!
再次在控制台调用了一下我们的页面。
结果居然正常了!
马上回复工程师,说解决了!
工程师连忙问,怎么操作的,我说,进调试界面,application,cookie,然后把和我们对应的cookie删除就可以了。
工程师回了一句,这都能想到,太神奇了,谢谢君哥。
这个问题就算解决了,我在内部管理系统的任务上将任务状态设置成“完成”。
刚点了“完成”,建任务的同事就给我发消息问道,是什么原因。
我说,是第三方浏览器有问题,不更新cookie。
同事回复说,还有这种事呀,太神奇了!
我说,一切皆有可能!
*请认真填写需求信息,我们会在24小时内与您取得联系。