styled-components 虽然 可能 能提升了开发体验,但是它运行时(runtime)的机制却对性能有损耗,可能对用户体验造成负面影响(这里用可能是因为我并没有量化地去比较,感觉这也很难量化)
css 痛点
1 .不想上下翻找代码了
2 .css 没有变量,函数,没有模块机制。现在的模版生成的base.css 不算专门的
3 .选择器及其容易出现重复,不利于维护和复用,多出来的css不敢删除。会有费代码
4 .全局污染。css选择器的作用域是全局的,如果两个一样,就会爆炸。
5 .postCss ,启动时编译样式,充分使用编译期能力,把css在编译期确定下来,充分享受浏览器内核间的优化。
css module 方案
0 .CSS Modules 通过工程化的方法,可以将类名编译为哈希字符串,从而使得每个类名都是独一无二的,不会与其他的选择器重名,由此可以产生局部作用域.依靠插件实现 css-loader
1 .加入局部作用于和模块依赖
2 .局部作用域
1 .起一个独一无二的名字。从每一个组件名字做key,然后下面都是嵌套,一直往里面套
2 .css-module会把组件类名,编译成一个独一无二的名字,那这个不是css文件缓存就没有了吧
3 .全局作用域
1 .:global(.className)的语法,声明一个全局规则。凡是这样声明的class,都不会被编译成哈希字符串。
styled-components 方案
0 .通过 JS 来声明、抽象样式来提高组件的可维护性,在组件加载时动态地加载样式,并且动态地生成类名避免命名冲突和全局污染
1 .没有类名错误styled-components 为您的样式生成唯一的类名。您永远不必担心重复、重叠或拼写错误
2 .更容易删除 CSS很难知道类名是否在您的代码库中的某处使用。styled-components 让它变得显而易见,因为每一个样式都与特定的组件相关联。如果组件未使用(工具可以检测到)并被删除,则其所有样式都会随之删除
3 .简单的动态样式根据组件的 props 或全局主题调整组件的样式简单直观,无需手动管理数十个类
4 .轻松维护您永远不必在不同的文件中寻找影响组件的样式,因此无论您的代码库有多大,维护都是小菜一碟。
/*
创建一个Title组件,
将render一个带有样式的h1标签
*/
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: palevioletred;
`;
/*
创建一个Wrapper组件,
将render一个带有样式的section标签
*/
const Wrapper = styled.section`
padding: 4em;
background: papayawhip;
`;
// 使用 Title and Wrapper 得到下面效果图
render(
<Wrapper>
<Title>
Hello World!
</Title>
</Wrapper>
);
5 .基本思想是通过删除样式和组件之间的映射来强制执行最佳实践,同时还拆分了容器组件和展示组件,确保开发人员只能构建小型且集中的组件。
6 .优点
及时响应和代码拆分
styled-components 持续跟踪页面上渲染的组件,并自动注入样式。结合使用代码拆分, 可以实现仅加载所需的最少代码
避免命名冲突
styled-components 为样式生成唯一的 class name,开发者不必再担心 class name 重复、覆盖以及拼写的问题
删除代码
使用 styled-components 可以很轻松地知道代码中某个 class 在哪儿用到,因为每个样式都有其关联的组件。如果检测到某个组件未使用并且被删除,则其所有的样式也都被删除。
简单动态样式,之前是根据classes来管理或者动态style管理
可以很简单直观的实现根据组件的 props 或者全局主题适配样式,无需手动管理多个 classes。(这一点很赞
import React, {
ButtonHTMLAttributes
} from 'react';
import styled from 'styled-components';
interface IScButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
primary?: boolean;
}
const ScWrapper = styled.div`
margin-top: 12px;
`;
const ScButton = styled.button<IScButtonProps> `
background: ${props => props.primary ? "blue" : "white"};
color: ${props => props.primary ? "white" : "blue"};
border: 2px solid palevioletred;
border-radius: 3px;
padding: 0.25em 1em;
`;
export default () => {
return (
<ScWrapper>
<ScButton>Normal</ScButton>
<ScButton primary>Primary</ScButton>
</ScWrapper>
);
};
无痛维护
1 .无需搜索不同的文件来查找影响组件的样式,无论代码多庞大,维护起来都是小菜一碟。
实现原理
1 .styled-components 做的只是在 runtime 把 CSS 附加到对应的 HTML 元素或者组件上,它完美地支持所有 CSS。 媒体查询、伪选择器,甚至嵌套都可以工作
写法
import React from 'react';
import styled from 'styled-components';
const ScH1 = styled.h1`
color: red;
background-color: blue;
text-align: center;
padding: 10px;
`;
export default () => {
return (
<ScH1>
Hello World
</ScH1>
);
};
结论
1 .代码更丑了
// styled-componnets
<TicketName></TicketName>
// CSS Modules
<div className={styles.ticketName}></div>
2 .虽然 styled-components 解决了全局命名空间和样式冲突, 但是 CSS Modules、Shadow DOM 和命名约定很久以前在社区中就解决了这个问题
3 .styled-components 是运行时的方案,这会对前端性能产生不利影响
网友评论