做网站比较好的公司有哪些,购物网站建设开发费用分析,织梦做的网站在手机上显示,最吉祥的公司名字大全美团网在2010年引爆了团购行业#xff0c;并在2012年销售额超过55亿#xff0c;实现了全面盈利。在业务规模不断增长的背后#xff0c;作为研发队伍中和用户最接近的前端团队承担着非常大的压力#xff0c;比如用户量急剧上升带来的产品多样化#xff0c;业务运营系统的界… 美团网在2010年引爆了团购行业并在2012年销售额超过55亿实现了全面盈利。在业务规模不断增长的背后作为研发队伍中和用户最接近的前端团队承担着非常大的压力比如用户量急剧上升带来的产品多样化业务运营系统的界面交互日益复杂代码膨胀造成维护成本增加等等。面对这些挑战我们持续改进前端技术架构在提升用户体验和工作效率的同时成功支撑了美团业务的快速发展这一切都得益于构建在YUI3框架之上稳定高效的前端代码。在应用YUI3的过程中我们团队积累了一些经验这里总结成篇分享给大家。 为什么选择YUI3 使用什么前端基础框架是建立前端团队最重要的技术决策之一。美团项目初期因为要加快开发进度选择了当时团队最熟悉的YUI2前框架时代杰出的类库保证美团能够更快更早地上线抢占市场先机。不久由于前端技术发展很快YUI2的缺点逐渐凸显例如开发方式落后、影响工作效率等等于是我们开始考虑基础库的迁移。 经过一段时间对主流前端库、框架的反复考量我们认为YUI3是最适合我们团队使用的基础框架。 首先国内的开源框架及其社区刚开始起步在代码质量、架构设计和理念创新上还难以跟YUI3比肩所以基本排除在外。其次国外像YUI3这样面向用户产品、文档丰富、扩展性良好的成熟框架屈指可数例如ExtJS和Dojo则更适合业务复杂的传统企业级开发。最后使用jQuery这种类库构建同YUI3一样强大的框架对创业团队来说并不可取美团快速发展、竞争多变的业务特点决定了我们必须把主要精力放在更高一层的业务开发上而不是去重复发明一个蹩脚的YUI。 YUI3成为最终选择有以下几个直接的原因 非常优秀是真正的框架真正的重型武器具有强劲的持续开发能力可以应对业务的快速发展。不管是规模不断增长的用户产品还是交互日趋复杂的业务系统美团有超过100个业务系统作全电子化的运营支撑YUI3都游刃有余。代码整齐规范容易维护适合有洁癖的工程师同时能够显著提高团队协作时的开发效率。因为人手紧缺后端工程师也需要参与前端开发一致的代码风格使前后端配合轻松简单。有出色的架构设计是很好的框架范本通过研究学习可以帮助工程师成长培养良好的工程思维。人是美团最重要的产品。随着团队成长我们最后引入了YUI3在迁移过程中遇到了很多技术上的和工程上的挑战但是我们一直在前进一直在行进中开火。从结果来看YUI3为我们团队提供了先进生产力为快速开发、快速部署、快速迭代提供了源源不断的力量。 YUI3的优秀主要表现在模块和组件框架的出色设计下面我们着重介绍这两方面的一些实践经验。 改变一切的模块 前端开发日益复杂化代码组织成为一个显著的问题。受到后端代码普遍采用的模块机制启发很多前端模块机制应运而生。目前比较著名的有CommonJS和AMD。但早在2008年8月13日YUI3 Preview Release 1中就已经给出了YUI团队的解决方案并在2009年9月29日YUI3正式版发布时定型。 以下是使用YUI3进行模块化开发的简单例子 // 定义模块
YUI.add(greeting, function (Y) {Y.sayHello function () {console.log(Hello, world!);};
});// 调用模块
YUI().use(greeting, function (Y) {Y.sayHello(); // output Hello, world!
});模块的引入使得更细粒度的按功能进行代码组织成为可能也为方便的进行扩展和分层提供了基础自底向上的彻底改变了YUI3。一套完整的模块机制还包括解决关系依赖、自动加载的Loader和提高加载效率的Combo。 面对如此彻底的改变我们需要解决很多挑战 如何将原来的功能划分为模块如何管理模块元信息如何高效的获取模块划分模块 经过两年来不断的实践和总结我们归纳了如下几条划分模块的原则 抽象与应用脱离。更通用的功能放在更低的层级应用层完全面向实际问题在解决的过程中调用抽象出来的方法。职责单一。保持每个模块的足够简单和专一方便维护和可持续开发。粒度得当。有了Combo我们可以不必担心粒度太小文件过多导致的速度问题。但是从可维护的角度来考虑粒度应该适当而不宜过小避免海底捞针的情形出现。海纳百川。我们的模块体系应该是开放的不符合YUI规范的第三方模块可以借鉴整合进来使我们的基础框架更加完善更加性感。 按照模块的层次划分美团的JS框架可以分为四个层次 最底层交给强悍的YUI3为我们提供跨浏览器兼容的API和良好的框架设计。第二层是我们二次开发的核心方法、组件Component和控件Widget。现已独立为前端核心库为美团所有系统提供前端支持。核心库的种子文件中定义了全局变量M除了对YUI3进行封装的代码以外还包含了对语言层面的扩展以及一些基础工具类。核心库有一个非常重要的组成部分就是我们功能丰富的控件集合比如常用的自动完成、排序表格、气泡提示、对话框等基础控件。除了这些核心库还包含了常用的基础组件、插件Plugin、扩展Extension以及单元测试代码。第三层包含各个系统的一些通用模块。例如www-base模块包含美团主站www的消息系统、用户行为追踪系统等通用功能。这一层更加接近应用。最上面一层应用模块。这些模块的方法都是用来解决实际业务问题。例如www-deal用来处理美团主站所有deal相关功能的交互finance-pay用来处理财务系统中付款相关的交互。一些零碎的应用方法我们放在对应系统的misc模块中避免模块碎片化。这套框架仍在不断演变以便更好的支撑业务需求。其中一个明显的方向是在第二层和第三层之间出现一个为了更好整合所有内部业务系统前端通用资源的中间层。 管理模块元信息 模块元信息主要包括模块名称、路径、依赖关系等内容。其中最为重要的是依赖关系这决定了有哪些模块需要加载。为了实现自动加载需要将所有模块的元信息提供给YUI的Loader。 最初为了更快的从YUI2迁移到YUI3模块元信息放在PHP中进行维护。随着时间的推移渐渐显示出很多弊端。首先在定义模块的js文件中已经包含模块名称、依赖关系等信息和PHP中内容重复。其次这些元信息最终直接输出到html中没有有效利用缓存。 随后我们使用NodeJS开发了一系列脚本收集所有模块元信息保存为独立js文件并实现了自动化。为了防止出错在Git Hooks和上线脚本中都加入了校验过程。工程师需要做的只是修改模块定义中的元信息。 最近一段时间我们的精力主要放在两个方面 自动生成依赖。随着模块粒度细化和模块数量的增长依赖关系日益复杂依靠人工配置经常出现过多依赖或过少依赖等问题。我们准备开发一套自动扫描模块引用API并确定依赖关系的机制。自动打包依赖模块。如果在代码发布时就已根据页面模块调用计算好所有依赖模块并进行打包可以避免引用全部模块元信息、Loader计算依赖等过程提高网站性能。Combo Combo可以一次请求多个文件能够有效解决多个模块加载带来的性能问题。Yahoo提供了Combo服务但只能提供YUI3模块而且速度在国内并不理想。为了提供更好的体验让用户访问速度更快我们最终考虑搭建自己的Combo服务并把Combo发布到CDN上。 以下是一个Combo请求的例子 http://c.meituan.net/combo/?fmt-yui-core.v3.5.1.js;fecore/mt/js/base.js为了节约时间我们最开始采用了开源的minify经过一些修改和配置就可以在生产和开发环境提供Combo服务。使用一段时间后发现minify过于复杂以至于添加一些定制功能相当困难。我们需要的只是简单的文件合并功能在明确需求和开发量后着手开发自己的Combo程序。从最初的仅支持文件合并后来陆续添加了服务器浏览器端缓存、文件集别名、调试模式、CSS图片相对路径转URI、错误日志等特性全部代码仅有300多行。经过两年时间以及每天几千万PV的考验服务一直非常稳定。 灵活健壮的组件框架 YUI3之所以成为纯粹的框架真正的原因在于提供了一套灵活、健壮的组件框架。借助这套框架可以轻松的将业务场景进行解耦、分层并持续的进行改进。通过不断的实践我们越发认为这是YUI3的精髓所在。 从YUI3定义的开发范式和源代码中可以看出YUI团队非常重视AOPAspect Oriented Programming和OOPObject Oriented Programming这一点可以在接下来的介绍中有所体会。 EventTarget、Attribute和Base 在介绍组件框架之前有必要首先了解下EventTarget。YUI3创建了一套类似DOM事件的自定义事件体系支持冒泡传播、默认行为等功能。EventTarget提供了操作自定义事件的接口可以让任意一个对象拥有定义、监听、触发、注销自定义事件的功能。YUI组件框架中的所有类以及在此框架之上开发的所有组件都继承了EventTarget。 Attribute是组件框架中最底层的类实现了数据和逻辑的完美解耦。为什么说是完美呢存储在attributeAttribute提供的数据存取接口中的数据发生变化时会触发相应的事件为相关的逻辑处理提供了便捷的接口。从下面这个简单的例子可以感受到这一点 // 在name属性变化时触发nameChange事件
this.on(nameChange, function (e) {console.log(e.newVal);
});// 修改name属性
this.set(name, meituan); // output meituan实践中发现妥善处理属性的分类非常重要。供实例进行操作的属性适合作为attribute例如表单验证组件FormChecker的fields属性方便应用层进行表单项的增删改。在类方法内部使用的一些属性可以作为私有属性例如计时器、监听器句柄。供所有类的实例使用的一些常量适合作为类的静态属性例如一些模板、样式类。 Base是组件框架的核心类。它模拟了C、Java等语言的经典继承方式和生命周期管理借助Attribute来实现数据与逻辑的分离并提供扩展、插件支持从而获得了良好的扩展性以及强大的可持续开发能力。YUI团队通过多年来对业务实践的抽象最终演化而成一种开发范式这就是一切组件的基石——Base实至名归。 依照这种范式我们开发了一系列组件例如之前提到的FormChecker以及延迟加载器LazyLoader、地图的封装Map等。最显著的体会是开发思路更为清晰代码结构更有条理维护变得简单轻松。 // 构造方法
FormChecker.prototype.initializer function () {var form this.get(form);this._handle form.on(submit, function (e) {// check fields});
};
// 析构方法
FormChecker.prototype.destructor function () {this._handle.detach();
};// 创建实例时自动执行构造方法
var checker new FormChecker({ form: Y.one(#buy-form) });
// 销毁实例时自动执行析构方法
checker.destroy();Extension和Plugin Extension扩展是为了解决多重继承以一种类似组合的方式在类上添加功能的模式它本身不能创建实例。这种设计非常像Ruby等语言中的Mixin。Plugin插件的作用是在对象上添加一些功能这些功能也可以很方便的移除。 它们有什么区别呢简单来说Extension是在类上加一些功能所有类的实例都拥有这些功能。Plugin只是在某些类的实例中添加功能。举两个典型的例子一些节点需要使用动画效果这个功能适合作为Plugin。气泡提示控件需要支持多种对齐方式所有实例都需要此功能因此使用YUI3的WidgetPositionAlign扩展。 // 传统的函数方式实现动画
Effect.fadeIn(nodeTip);// 插件方式实现动画
nodeTip.plug(NodeEffect);
nodeTip.effect.fadeIn();Extension和Plugin很好的解决了我们遇到的诸多功能重用问题。我们开发了提供全屏功能的WidgetFullScreen、自动对齐对话框的DialogAutoAlign等扩展以及进行异步查询的AsyncSearch、提供动画效果的NodeEffect等插件。将这些偏重OOP的编程思想应用在前端开发中比较深刻的体会是有更多的概念清晰、定位明确的开发模式可以选择。 Widget体系 Widget控件建立在Base之上主要增加了UI层面的功能例如renderUI、bindUI、syncUI等生命周期方法HTML_PARSER等渐进增强功能以及样式类、HTML结构和DOM事件的统一管理。Widget提供了控件开发的通用范式。 由于前端资源相对紧张我们倾向于大量使用控件尤其在业务系统这样更注重功能的场景。主要出于两点考虑 减少不必要的重复劳动提高产出。通过将交互、业务逻辑合理抽象一次解决一类问题One Shot One Kill。节约前端工程师资源。通过自动加载和初始化控件、封装简单易用的后端方法、制作Demo和使用手册等措施降低使用门槛后端工程师只需要知道参数的数据结构就可以轻松调用提高了开发效率。以下是一个自动加载控件的例子 // 页面初始化时会扫描所有带有data-widget属性的节点自动加载对应控件并根据data-params数据进行初始化
a href… data-widgetbubbleTip data-params{ tip: 全新改版支持随时退款 }下载手机版/a目前我们已经构建了一个包含近30个控件的Widget体系为所有系统提供丰富、便捷、集成的解决方案。 行进中开火 在整个YUI3的实践中我们犯过很多错误例如全局只有一个YUI实例、Combo的CSS图片依赖等等但这些并没有成为放弃的理由。从今天回过头来看YUI3带给我们团队的不只是更高的开发效率、更好的可持续开发能力还有它本身的设计思路、源码书写、辅助工具等诸多方面潜移默化的影响。这些回报的价值比起较高的使用门槛、犯过的一些错误要贵重百倍。 指导这一切的是我们始终坚持的 “行进中开火”。在互联网这个高速发展的行业里对于我们这种小规模的创业团队一天不前进就意味落后。做事不应该准备太多一定要先做起来然后发现不足并不断改进宁可十年不将军不可一日不拱卒。每天都做得更好一点日积月累我们才会在激烈的竞争中占据越来越大的优势。 YUI3并非完美存在着学习成本高、对社区不够开放等问题。我们所做的更远非完美但经过不断的尝试和经验的积累已经渐渐摸索出一条明确的路线并会坚持不懈的继续走下去。