`
limu
  • 浏览: 322847 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

CSSLoader实现思路以及与JSLoader的异同

阅读更多
童鞋们新年好,2012年只发了两篇水文,就这么过去了,实在汗颜。话说大家都转移阵地去微博和github讨论问题了,谁让iteye还不支持markdown呢

今天说说我不熟悉的领域CSS,因为手里的项目实在需要,所以最近花了不少精力在我有限的CSS知识范围内寻找解决方案,也经过和很多同事讨论碰撞,不如记录一下。

CSS也需要模块化
CSS也需要模块化,这个其实不需要说太多,大家也都是这么做的。在开发阶段css伴随这个各个模块存在。隐约记得还有不少关于面向对象CSS的讨论,也有Less和SASS这种加强CSS结构化的工具。

而在上线前往往需要将各处散落的CSS文件统一合并,或更智能的实时combo。所以今天讨论的CSSLoader是开发时使用。

CSS模块间存在依赖关系,但用JS模块管理方式一并管理不够恰当
CSS模块间存在依赖关系,常见的情况是所有css都依赖框架的reset.css,然后可能各个css也都依赖项目通用css如project.css。

但是用js模块管理方式来管理css模块是不够合适的,有以下一些问题:
1. 当前的JSLoader,往往只支持,一个js模块依赖若干css模块,并非真正的支持css间的依赖。
2. css文件内,不支持js语法,所以无法描述它的依赖。内置的@import有它的问题,稍后讲讲。

在讨论中,我们发现还是从CSS的特点出发,为它量身定制Loader解决方案为佳。


CSS特点是有层次,那么理想的项目CSS规划怎样
CSS的全称是层叠样式表,这其实说明了CSS的特点是有层次的,而这一点在JS中表现的并不明显,特别大家通过模块化屏蔽了全局变量相互覆盖带来的影响之后。

CSS的层次的特点是,下层的CSS规则,可以覆盖上层的CSS规则,所以我觉得网页理想的CSS规划是每一个CSS模块都能明确其所属层次。

这样的网页CSS层次如下图所示,这也是我们当前项目中的结构:



1. reset.css : 底层类库提供的通用
2. project.css :项目内通用的css,在我们的项目中可能存在其他项目的project.css,因为我希望不同项目中间的组件可以共享
3. widget.css :组件的通用css
4. widgetInstance.css :组件实例特有的css

可以看出在css分层次规划的背景下,css文件的依赖次序是固定的,4 -> 3 -> 2 -> 1 。 回过头来css的加载顺序应该是1、2、3、4,必须串行。

我们看到这样的规划下css模块是一棵树,如果projcet2.css依赖widget1-1.css显然是不合理的。而js的模块依赖是一张没有闭环即可的图(闭环==循环引用)。

简单总结下理想的CSS规划策略

1. 为网页的css划分层次,让每个css模块有明确的层次属性
2. 同一层次内的不同css模块,相互间不应该存在冲突的定义
3. 下层css模块只可以覆盖其所依赖的上层css模块中的部分规则


CSSLoader的要点

精确的的onload事件
我们必须保证上层css加载进来、规则完全应用好之后才能加载下层css。这样我们就需要一个精确的onload事件,在早期的getScript方法加载css文件时,只要把请求发了就立即触发onload,以草草达到和js模块一致的回调。而最近这方面的研究已经比较完善,kissy1.2以及seajs的很早的版本就支持真正的css文件onload回调。推荐seajs的做法,因为404时同样会触发回调。代码在这里https://github.com/seajs/seajs/blob/master/src/util-fetch.js#L82,测试用例在这里http://seajs.org/tests/issues/load-css/test.html,感谢玉伯。

我们注意到这里的css加载实现是动态构建link节点,但是在IE下有效的link节点有个数限制,所以方案并不完美。那么其实其他所有为页面引入css的方法都可以用,但前提是需要有靠谱的回调。甚至可以研究下,让css文件也能将载入和规则应用分离开的高级样式引入方式。

并发处理
一定存在同时初始化多个widget的情况,那么并发加载inst1-1-1和inst1-1-2时,要确保其共同的上层,如projcet1.css最先加载并且不能重复加载。在这一点上可以,参照JSLoader的实现模式,将已经载入的模块记录在案。这一点也引出了@import的问题,如果两个inst里边都写了@import project1.css,那么可能会出现inst1-1-1覆盖projcet1的规则又被覆盖回去的情况。

更进一步,当一个加载任务队列正在进行时,又开启了另一个加载任务队列,如果我们能按照css模块的层次顺序,将两个队列merge成一个队列再继续执行,看起来会更好些。

API示意
简单构想了一下扩展后的API,一串CSS加载任务发起还是由JS模块承担。

基于Kissy的话,需要add方法,为js模块增加cssRequires配置项,区别于requires,cssRequires数组内的文件需要按顺序串行加载,能够标识css模块的层次更好。

KISSY.add('mywidget',function(){
	//...
},{
	requires:['mod-a','mod-b'],
	cssRequires:['reset.css:1','projcet.css:2','widget.css:3','instance.css:4']
});


在KISSY.use的时候原有逻辑负责js的加载,同时丢一个任务给新实现的cssLoader,去按层次加载css。

脆弱的方案
这绝对不是一个完美的解决方案,当前的实现方案基于“理想的CSS规划策略”,需要分层、同层次不冲突、仅向依赖的上层覆盖,这三点完全做到,而这里最大的挑战似乎是如何技术化的保障同一层次的css不会出现冲突。

在天然的浏览器环境没有很好的提供我们需要的feature时,等待它进化还是不现实的,很多时候就是靠我们能掌控全局这一优势,在不同环节各退一步,达成一个可以勉强运转体系。

好在这个方案是在开发时运转,而且明确的css规划也为真正线上产品的css打包或自动combo提供了便利。

简单发散一下

让层次描述更灵活
约定4个层次,还是太死板了,我们可以参照zIndex的设计,让层次数值之间存在大量空隙供扩展。

其他实现方案
可能有把css写在js里的方案,有基于less、sass扩展的方案,有开发时跑一个本地服务的方案(类似grunt)。这些都好,但对于如今我们手上的项目来说不够敏捷。其实没准有人已经实现过,欢迎知道的同学推荐。


最后
真的不太会CSS,如果有误请帮忙指出,如果有好的方案或者相关的研究都推荐过来吧,谢谢~
  • 大小: 98.9 KB
分享到:
评论
2 楼 gxll1314 2013-01-10  
关于CSS的加载问题,大家都喜欢构造link节点来加载CSS,对于这个方案我觉得唯一的不好就是对于load加载的精准性。其实可以将CSS看作文本节点,使用ajax作为text获取CSS,将CSS以style的形式append到页面,这样可以很方便的控制加载。
1 楼 Hafeyang 2013-01-10  
我用php写的一个模块加载器 https://github.com/hafeyang/smartcomb

相关推荐

    flex——cssLoader

    下面将详细阐述CSSLoader在Flex中的工作原理、使用方法以及它带来的优势。 1. **工作原理**: Flex CSSLoader是通过ActionScript 3.0的类`mx.styles.CSS`来实现的。这个类提供了加载和解析CSS文件的功能。当你在...

    前端项目-css-loader.zip

    本项目名为"前端项目-css-loader",其核心是利用CSS Loader实现一个只使用一个DIV和纯CSS的Web应用程序的简单加载程序。 首先,我们要理解什么是webpack。Webpack是一个现代JavaScript应用程序的静态模块打包工具。...

    CSS设计大师设计思路与实践

    在深入探讨《CSS设计大师设计思路与实践》这一主题之前,我们先理解一下CSS(Cascading Style Sheets)的核心概念。CSS是一种样式表语言,用于描述HTML或XML(包括如SVG、MathML等各种XML方言)文档的呈现。它允许...

    react-在ReactWebpack中用来配合cssloader模块中的modules使用

    首先,`css-loader`允许我们在JavaScript中导入CSS文件,并将CSS转换为JavaScript对象,这样可以实现CSS的模块化。当`modules`选项启用时,CSS的类名会被哈希化,生成独一无二的本地化类名,防止全局冲突。这在大型...

    CssLoader:受 Google Drive 启发的 Css 加载器

    【CssLoader:Google Drive 启发的Css加载器】 在网页开发中,用户界面的响应性和用户体验至关重要。当页面内容正在加载时,加载指示器(loader)能够提供视觉反馈,让用户知道页面并未卡死,而是在处理数据。`Css...

    vue2.0安装style/css loader的方法

    在这个过程中,`style-loader`和`css-loader`扮演了关键角色。下面是关于如何在Vue 2.0项目中正确安装和配置这两个加载器的详细步骤。 首先,我们需要通过npm(Node Package Manager)来安装`style-loader`。虽然`...

    css3实现loader加载指示器特效.zip

    本项目"css3实现loader加载指示器特效.zip"正是一个专注于利用CSS3来制作Loader特效的资源包,包含了使用CSS3、JavaScript、jQuery以及HTML5等技术的实例。 首先,我们来深入理解CSS3的一些关键特性在Loader特效中...

    css3实现加载loading特效小动画效果

    总结来说,CSS3加载loading特效小动画效果是通过结合关键帧动画、变换(transform)、过渡(transition)以及颜色和背景的动态变化来实现的。这些技术的运用让网页加载不再枯燥,而是成为了一种视觉享受。在实际开发...

    css js loader

    总的来说,"css js loader"是一个旨在优化网页性能的工具,通过智能管理CSS和JS的加载,它可以提高页面加载速度,提升用户体验,特别是在与"Fast and Easy Checkout"这样的关键插件配合时,它的优势更为明显。...

    zencart css_js_loader插件

    而"zencart css_js_loader插件"是专为ZenCart设计的一个重要组件,它与"Fast and Easy Checkout for Zen Cart"这个插件密切相关。在安装和优化ZenCart的结账流程时,css_js_loader扮演了关键角色。 首先,我们来...

    Webpack中css-loader和less-loader的使用教程

    通过`require`或`import`语句,你可以将CSS文件与JavaScript代码链接起来。首先,确保已安装`css-loader`和`style-loader`: ```bash npm install css-loader style-loader --save-dev ``` 在`main.js`中引入CSS...

    12种纯CSS3 Loader加载指示器动画特效.zip

    loaderskit是一款效果非常炫酷的纯CSS3 Loader加载指示器动画特效。该Loader加载指示器动画特效共12种效果,动画效果全部使用CSS3来完成,没有使用任何图片。 使用方法 在页面中引入loaderskit.css文件。

    css-loader:CSS加载器

    CSS加载器css-loader像import/require()一样解释@import和url()并将解析它们。入门首先,您需要安装css-loader : npm install --save-dev css-loader 然后将插件添加到您的webpack配置中。 例如: file.js import ...

    CSSLoader:RequireJS 插件,用于可靠地加载和等待 css 文件

    CssLoader (css!) - RequireJs 插件 RequireJs 插件,用于可靠地加载和等待 css 文件。 ##Inspiration 需要一个经过良好测试且可靠的插件来使用 RequireJs 加载 css 资源。 加载和等待 css 文件的主要问题实际上...

    新思路 纯css圆角实现方法

    本附件内包含一个html文件,提供了一种简单实用的css实现页面圆角地方法,供大家学习使用

    前端开源库-css-loader-bbq

    **前端开源库-CSS-...了解和掌握 CSS-Loader-BBQ 的工作原理以及如何在实际项目中配置使用,对于前端开发者来说是非常必要的技能。同时,理解 Loader 和 Webpack 的整体架构,有助于我们更好地构建高效的前端项目。

    基于html5+css3实现的精美聊天界面demo

    标签"css3-chart-window"可能指的是界面中包含了一个图表窗口,CSS3可以用于定制图表的样式,如数据点的形状、颜色,以及图表轴的样式。使用`linear-gradient`或`radial-gradient`可以创建独特的背景效果,增强图表...

    css-loader-deep-remove.zip

    在`css-loader-deep-remove.zip`这个压缩包中,很可能是包含了一个示例项目或者一个自定义配置,用于演示如何结合使用`css-loader`与某种深度选择器清理策略。文件列表只给出了`css-loader-deep-remove`,这意味着...

    纯CSS3实现8款超好看的Loading加载动画特效

    纯CSS3实现8款Loading加载动画特效,可以比拟gif动画效果的8个创新绿色Loading加载特效,动画效果非常漂亮。 这是一款非常不错的导航菜单,鼠标悬停导航上面文章内容遮罩变暗,鼠标离开文章高亮显示。

    HTML5+CSS3实现的图片左右切换弹性动画特效源码

    `css`文件夹则包含样式表文件,其中包含了实现弹性动画效果的所有CSS3规则。 在实际应用中,为了实现响应式设计,可能会使用CSS3的媒体查询(`media queries`)来确保在不同设备和屏幕尺寸上的显示效果。同时,为了...

Global site tag (gtag.js) - Google Analytics