网站首页 > 技术文章 正文
随着互联网的发展,我们的业务也日渐显得愈发复杂且多元化上去,后端工程师也不再只是做简单的页面开发如此简单,我们须要面对的极其复杂的系统性问题,比如,业务愈来愈复杂,我们要怎么清晰地梳理;团队人员愈来愈多,我们要怎样更好地进行团队协作;功能愈来愈多,我们要怎样保证页面的性能不至于增长,等等。所有的那些都可以归结为怎样提高开发体验和性能问题。
提高开发体验
我们主要从以下三个方面来提高我们的开发体验。
规范化
当团队人员不断扩展时,我们须要制订统一的规范来对平常的开发工作作出一定约束和指导。统一的规范包括后端的代码规范,按照规范定义好一套代码检测的规则,在代码递交的时侯进行检测,让开发人员晓得自己的代码情况。
同时,按照往年的开发经验,我们制订了统一的项目框架,依照业务功能不同,将一个项目(app)拆分成不同的业务模块(module),而每一个模块都包含自身的页面(page)以及构成页面所须要的组件(widget),每一个项目涉及到app、module、page、widget那些早已约定好的概念,这样让项目结构愈发清晰,并且让团队内不同业务的人员之间切换无障碍。
组件化
在项目中引入组件化的概念,这儿的组件对应上文提到的widget,每一个组件就会包含组件自身的模板、css、js、图片以及说明文件,我们使用组件来拼装页面,像搭积木一样来拼装我们的页面,同时一个组件内可以调用另一个组件。
在领到设计稿后,我们首先须要确定什么须要弄成公共组件,这些是要弄成独立组件,以及组件间怎样进行通讯。在页面中调用这种组件后,会手动加载组件的模板以及组件的静态资源,而当组件不再须要时,只要移除掉组件引用,这么相应的模板和静态资源也会不再加载。
组件化的益处主要有如此几点
手动化编译
在后端开发中,我们总是会去使用好多工具、手段来优化代码、提升开发效率,比如,我们会使用sass、less等CSS预处理工具来编撰更好维护的款式代码,我们也会使用CSSLint、eslint等代码检测工具来检测代码的句型错误,使用文件合并压缩等手段来降低资源大小,除此之外我们都会去做雪碧图合并、多倍图处理、字体压缩处理、代码发布等等。
以前有前辈说过,超过90s的工作都应当手动化掉。而以上所有的这种工作,贯串我们整个开发流程,并且不同工具的切换不但变得零乱,并且影响开发效率。在手动化、工程编译的思想已经深入人心的当下,我们其实也要紧随时尚,所以我们考虑通过手动化手段来提高我们的效率,让所有操作可以一键式开速执行完。
我们将通过定义好一系列的编译任务,根据一定次序依次对我们的项目手动进行编译操作,最后形成出可上线的代码。
提高性能
我们主要从以下四个方面来做好性能优化。
首屏优化
页面的打开速率仍然是你们十分关心的一个指标,一个页面打开太慢会让让用户丧失等待的耐心,为了让用户更快地看见页面,我们考虑将页面中部份静态资源代码直接嵌入页面中,我们通过工具处理,在工程编译阶段,将指定的静态资源代码内嵌入页面中,这样可以降低HTTP恳求,提高首屏加载速率,同时减少页面裸奔风险。
按需加载
同时,我们考虑通过尽量减少页面容积来提高页面打开速率,在业务上我们将页面界定为一个个楼层组件,以易迅美妆馆为例,页面中从上而下分为首焦、至IN尖货、今日特价、潮流前沿、口碑榜单那么几个楼层组件,虽然这个页面还有很长,内容十分多且复杂。
之前我们的做法是整个页面直出,这样一次性加载的内容会特别多,为了提高打开速率,我们考虑通过按需加载的方法来优化页面的加载。我们在页面中只放每一个楼层的框架性代码,楼层的模板和数据都通过异步的方法去拉取,来实现楼层组件的按需加载,同时我们可以对模板以及数据进行缓存,借此来降低恳求,做更极至的优化。在开发中我们以正常组件的形式去开发整个页面,此后通过编译工具,在代码编译阶段手动将楼层的模板抽离成一个独立的JS文件,并给楼层容器打上标记位,通过页面加载逻辑去按需拉取模板,再进行渲染。
通过给楼层容器和模板分别加上标记位o2-out-tpl-wrappero2-out-tpl
在编译时手动将指定的模板代码抽离成独立js文件
但是给楼层容器打上标记
同时在逻辑脚本适当位置手动加入模板的版本
通过上述步骤,实现按需加载的手动化生成,在提高性能的同时,挺好地解放我们生产力。
基于资源表加载
按照页面组件化,通过工具剖析,我们将获得页面与组件的依赖关系表,同时也能确认页面所引用资源的依赖关系,比如,我们在页面hello中同步引用组件topbar,这么依赖关系表上将会记录同步引用关系hello引用topbar.tpl、topbar.css、topbar.js,这么页面hello将会手动加载组件topbar的CSS与JS,同时依赖表会记录异步引用的关系,如果我们在组件C中通过API异步引用了组件D的js,这么会在依赖表中记录C异步引用D.js这一个依赖关系,这样D.js这个资源将会在用到的时侯被异步调用。
同步引用的资源通过生成combo方式链接,在服务端进行文件合并,这样在页面加载的时侯,页面只会加载自己须要的同步资源,异步的资源将会在用到的时侯再加载,有效防止资源冗余。同时删掉、增加组件也十分便捷,只需改动模板中对组件调用,通过编译工具会手动重新生成模板以及combo链接。
我们可以将资源加载的操作抽离下来,产生一套统一的资源加载框架设计,这样我们使用的模板可以显得愈发灵活,无论是纯html模板,还是PHP或Java之类的前端模板都能有效支持。编译工具扫描代码后只生成资源依赖表,我们通过实现各语言平台的资源加载框架,让不同语言的模板都能基于同一个资源依赖表进行资源加载。
同时,对资源进行MD5重命名处理,文件md5重命名也是一种提高性能的有效手段,使用文件md5后开启服务器强缓存,可以提高缓存的借助率并防止毋须要的缓存判定处理。但文件md5重命名后会出现开发时引用的文件名对不上的问题,这就须要在资源表中记录原文件名与md5重命名后之间的对应关系,当我们引用一个资源时,都会通过查表获取重命名后的资源名,之后借助代码中引用资源定位的能力来进行资源名手动替换。
静态资源预加载
所谓静态资源预加载,就是当用户在进行浏览页面的时侯,我们可以在当前页面沉静加载下一个页面的静态资源,这样当用户步入到下一个页面时能够快速打开页面,因而在不知不觉中提高页面的打开速率。
我们会在静态资源预加载平台上配置每一个页面id对应须要预加载页面资源的id,之后系统通过读取资源依赖表获取到所须要预加载的静态资源,生成预加载资源列表文件,再将文件推送到线上服务器,通过页面挂载js恳求获取预加载资源列表,此后沉静加载资源。在有了资源依赖表后,我们可以确切地剖析到每一个页面引用资源的恳求,就可以挺好地实现静态资源预加载的功能。
Athena
工欲善其事,必现利其器。为了实现我们对提高开发效率和产品性能的诉求,我们提出了比较完整的工程化解决方案以及对应的工具Athena。
Athena是由易迅【凹凸实验室】(aotu.io)推出的一套项目流程工具,通过Athena,我们可以很流程地跑完整个开发流程。Athena分为两部份,一是本地手动化编译工具,二是资源管理平台,其构架如下
本地手动化工具
Athena本地编译工具是一个基于NodeJs的命令行工具,通过执行命令的形式来优化我们的开发流程,目前Athena的主要功能有
创建项目结构
在执行创建命令时,Athena会从管理平台下载自定义好的项目模板,可以依照模板创建项目、模块、页面、和组件。Athena有四个创建命令:
通过执行$athappdemo命令就可以生成定义好目录结构的项目。
此后可以通过$athmodulehome来创建一个业务模块;
通过$athpageindex来创建页面;
通过$athwidgetwidgetName来创建组件。
开发使用组件化
Athena中实现组件化主要是分为两种,一是针对纯HTML模板,通过扩充模板引擎方式实现,提供了组件化APIwidget.load,它可以方式接收三个参数,第一个参数是widget的名称,前面两个参数是可选参数,第二个是向widget传递的一些参数,第三个是widget所属的模块,倘若是本模块,可以不传诸如
1
2
3
4
5
6
7
<%= widget.load('user') %>
<%=
widget.load('user', {
param: 'test'
})
%>
<%= widget.load('user', null, 'gb') %>
通过模板引擎编译,执行widget.load方式,可以实现加载模板,记录依赖关系的目的。
二是针对不同语言的前端模板,通过实现各自的组件化框架来进行组件的加载,比如PHP下使用来进行组件加载,再通过代码扫描得出组件依赖关系。
Athena中的API
Athena针对模板提供了一系列的API来扩充丰富的功能,比如上面提及的来实现组件化。
同时Athena中还提供了其他API:
、用来引用CSS/JS文件,传入文件名和模块名;
提供了资源定位功能,可以在模板中标记资源,编译过程中会进行替换,并且在JS中也有资源定位API__uri();
提供了内联资源的功能,传入文件名和模块名,可以在模板中内联任意资源,比如图片以及JS脚本;并且inline也可以内联一段网路资源,比如线上的JS文件,同样的在JS中也有内联资源API__inline();
雪碧图标识?__sprite,在CSS中引用图片最后加上标识?__sprite可以手动生成自定义名称雪碧图,同时支持自定义生成多张雪碧图,只须要要标示前面带上一个文件名,就可以生成一张以这个文件名来命名的雪碧图,比如?__sprite=icons,这样所有带同样标示的图片都会生成一张以icons为文件名的雪碧图。
编译预览编译任务
在编写完项目,就可以通过命令来对项目进行编译了,执行编译命令$athbuild,会针对指定模块执行早已定义好的编译任务,按照项目需求,目前编译都是基于业务模块去编译,编译任务的最小执行单位是页面,每次编译就会执行以下编译列表
本地预览
执行预览命令$athserve会执行精简版编译任务来编译项目,编译完项目后会生成一份站点地图,随即打开一个本地服务器来预览项目,使用这个命令可以很便捷地进行开发,在预览时会同时watch目录和文件的改动,但是提供了livereload功能,我们可以在预览时任意更改文件,都将实时地反映到页面中,同时可以新建另一个窗口执行新增组件和页面的操作,让整个开发过程十分顺畅,我们只需关注开发本身就好,不须要再关注其他事。
执行完编译任务后,默认手动打开浏览器,预览站点地图
Mockserver
在进行项目预览的同时,Athena同时提供了mockdata的服务,我们可以配置相应的路由,以及路由插口对应的假数据,所有的插口恳求会发送到mockserver上,在mockserver中可以选择将恳求代理到假数据平台还是代理到线上插口,这样就可以脱离前端进行开发联调了,借此实现数据的前后端分离。
项目布署
在开发预览完后,通过命令$athpublish就可以将项目发布到配置好的测试机上,发布同时支持ftp、sftp以及http方式。
组件维护
我们通过组件化的手段早已将我们的项目进行组件化了,这样我们经过业务迭代积累,产出好多业务公共组件,但在往年的项目开发中,公共组件的更新与维护仍然很受限制,并且有什么公共组件、公共组件长哪些样子,只能借助口口相传或则手工维护的文档。所以在Athena中我们加入了组件平台,在组件平台上统一展示各个业务的公共组件,而得益于本地工具,组件平台不须要人工干预维护,我们可以在本地通过命令$athwidget-publish[widgetName]命令来发布一个组件到组件平台,这样其他人就可以立刻在组件平台进行组件的预览,而其他人若果使用该组件时,在本地通过命令athwidget-load[widgetId]就可以下载该组件到自己的模块目录下了。
这样组件的维护愈发手动化,公共组件的使用也愈加便捷了。
组件发布
组件下载
自身优化
为了提高开发效率,Athena做了一些优化操作
精简项目预览时的任务
在开发时进行项目预览时,会执行精简版的编译任务,剔除了类似文件压缩、雪碧图生成、模板抽离处理等历时的操作,只保留核心、必须的编译任务,这样可以极大地降低编译时间,提高开发的效率。
预览时窃听细化
在开发进行预览时,会对所有文件的改动进行窃听,而针对每一类文件都有特别细化的操作,当文件改动时只会执行改文件所须要的编译任务,而不会进行整体编译,这样可以挺好地提高开发效率。诸如改动某一组件的CSS文件,则只会针对该文件执行一些相关的CSS操作。
同时得益于所有文件依赖关系的记录,在窃听时会依照依赖关系进行文件编译,比如某sass文件中引入了另一个sass库文件,更改这个sass库文件的时侯,会依照引用关系表同时更新到所有引用到这个sass文件的文件,这样项目文件更新及时,让开发流程愈发流畅。
编译缓存
在图片压缩和sass编译时,开启文件缓存,将早已编译过且没有改动的文件过滤掉,不再编译,急剧提高编译速率。
发布缓存
设置发布过滤,依照文件md5过滤掉早已发布过的文件,提高发布速率。
技术选型
Athena本地工具初期技术选型是Yeoman+Gulp的方法,但后来因为安装、更新十分麻烦,命令太长很难打的缘由,我们改成了自己开发一个全局安装包的形式,编译核心使用的还是Gulp的vinyl-fs来实现文件流处理,通过ES6Promise来进行编译流程控制,最小以页面为单位,经过一系列编译任务,最后产出编译好的文件。
管理平台
性能优化仍然是后端工程师探求的课题,好多时侯就是资源的分配问题,也就是资源管理。为了更好地配合本地建立工具来管理资源,我们搭建了管理平台。我们来看下,结合本地建立工具和管理平台,工作流程弄成了如何?
工作流程
在管理平台上创建项目,输入项目名称和预览机,以及选择相应的模板等;
在终端执行athapp指令,工具会优先拉取远程服务器的项目信息来初始化项目,假如没有获取到相关信息,还会在本地生成项目,并将项目信息上报给服务器;
项目初始化后,就可以创建模块、页面、组件了;
在编码过程中,可通过athserver预览页面;
在本地通过后,可执行athpublish将代码发布到开发机或则预览机。
在前面的publish指令中,工具会扫描所有文件,执行代码检测,扫描页面文件,获取组件依赖关系,依据组件依赖关系进行文件合并,之后会进行式样处理、js处理以及图片的处理,按照配置是否进行md5重命名文件,组装html,插入款式、js和图片,最后将编译好的文件发布到相应的机器。在整个过程上面,会生成资源关系依赖表,最终会将资源关系表及编译后的文件上传至管理平台。
除此之外,每位指令的操作就会上报给管理平台。管理平台收到数据后,会对数据进行处理,最终可以在平台上看见项目相关的信息。
整体工作流程图如下:
从前面的工作流程中,我们可以见到,管理平台须要有数据统计、资源管理以及项目管理的功能。整体构架图如下:
数据统计
数据统计包含项目操作日志,主要是用于统计团队每位成员具体的操作,便捷项目成员查看项目代码变更;另一部分是统计款式表、脚本以及图片的压缩数据,用于显示工具给我们项目带来的提高。
以下是操作日志统计:
资源管理
资源管理是管理平台的核心,主要分为4个部份:模块展示、依赖关系、组件预览和权限控制。这部份功能主要通过本地建立工具提供的资源关系表来完成。
模块展示
模块展示,用于记录项目具体包含什么模块以及模块具体的信息。在平时开发中,我们的项目会分为许多模块,不同的模块有不同的人来开发和维护。当项目越大的时侯,可以通过管理平台清晰地看见模块具体的信息。
依赖关系
依赖关系,主要是html、css、js和图片互相之间的关系。通过剖析资源关系依赖表,可以获取到各个资源被引用的情况以及线上版本的情况。当线带环境采用md5来做资源管理时,我们不是很清晰地晓得静态资源对应线上那个版本的资源,而有了这个依赖关系表,当出现问题时,我们可以更快地定位到具体的资源。
组件管理
我们采用组件来堆砌页面,当项目越大时,组件越多,这么怎样管理组件成为了一个棘手的问题。例如说,有一些比较老的冗余组件,我们不确定是否为其他页面所引用,这么就不能愉快地删掉它。有了组件管理,可以清晰地晓得组件的被调用情况,就可以对组件做相应的操作。
组件管理,结合组件平台来使用,在管理平台上引用组件地址预览组件,同时可以获取到组件被引用以及引用资源(如css、js、图片)的相关情况。
我们的组件分为两种,一类是通过athw手动创建的,通过athpu递交到管理平台的,在管理平台上进行组件的相关剖析和编译,得到组件的信息,这类组件主要是跟业务绑定的;另一类是通过athwidget-publish递交到组件平台的,由组件平台进行相关处理,这类组件是通用组件,与业务无关,用于展示给开发以及相关业务方看的。
在组件平台上可以预览与编辑相关的组件,通过与设计师约定相关的设计规范来促进组件达到尽可能地复用,从而降低设计师的工作量,提高我们的工作效率。
组件递交到组件平台
通过athwidget-publish指令将组件递交到组件平台,组件平台会对组件源码进行编译,将组件名称md5、组件归类以及组件版本记录等等。
从组件平台上下载组件
通过athwidget-load指令将组件下载到本地,当本地建立工具向组件平台发起恳求时,会带上组件名称,组件平台会将源码进行编译,将组件名称重命名,但是相应地替换源码中的组件名称,同时记录组件的被引用记录。
权限控制
权限控制,项目中存在公共组件模块,公共组件比较稳定,例如说轮播组件、选项卡组件等等,这部份代码通常比较少变动,可由少部份人来更新和维护,所以加入了权限控制机制,保证公共组件的稳定性。
项目管理
我们在使用本地建立工具时,须要配置多个参数,例如主机信息、选择模版等,在命令行环境下有些不直观。为了简化这个操作,管理平台提供了项目创建的功能,同时提供了模版创建的功能。
在项目信息、模块信息以及组件信息发生变更的时侯,为了第一时间才能通知项目成员更新,加入了消息通知的功能,目前通过发送短信的形式,后期可以加入陌陌提醒的功能。
技术选型
管理平台后端采用React+Redux的方法,前端采用Express+MongoDB,整体技术选型如下:
假数据服务存在的问题
在平时的开发中,常常须要前后端联调,而且在项目开始之初,好多插口并没有提供,在原先的开发模式下,须要等待前端提供插口或则自己先定义插口,后端开发的进度可能会受影响。
Mock数据平台
为了不影响后端开发的进度,我们搭建了Mock数据平台,通过与前端协商数据格式,自定义数据插口,这样子就可以做到前后端分离,让后端独立于前端进行开发。
Mock数据平台基于mockjs搭建而成,通过简单的mock句型来生成数据。
Mock数据平台目前有如下功能:
创建模拟数据,使之符合各类场景;
生成json数据插口,支持CORS以及jsonp。
写在最后
本次分享首先述说了我们在业务膨胀、人员不断降低的背景下遇见的项目开发上的问题,并提出了我们自己对于这种问题思索总结后得出的解决方案与思路,最后产出适宜我们团队、业务的开发工具——Athena。希望我们的方案能给你们带来一定的借鉴作用。
- 上一篇: CSS知识点-设置a标签的高度和宽度
- 下一篇: 前端-奇技淫巧-console.log的样式
猜你喜欢
- 2025-06-09 极客Web前端开发资源大荟萃#016(极客大学前端进阶训练营百度网盘)
- 2025-06-09 CSS伪类选择器大全:提升网页交互与样式的神奇工具
- 2025-06-09 必备-新媒体运营常用10种广告文案配图样式!
- 2025-06-09 样式混乱调不好?1 个样式隔离技巧
- 2024-09-29 BootStrap-常用样式--乐字节前端 乐字节crm项目
- 2024-09-29 HTML网页制作中常用的样式属性,学会就离前端开发更近一步
- 2024-09-29 Web前端入门新人必看,怎样使用CSS修改HTML的样式
- 2024-09-29 前端开发,在项目中常用的css样式整理
- 2024-09-29 前端-奇技淫巧-console.log的样式
- 2024-09-29 CSS知识点-设置a标签的高度和宽度
你 发表评论:
欢迎- 653℃几个Oracle空值处理函数 oracle处理null值的函数
- 645℃Oracle分析函数之Lag和Lead()使用
- 643℃0497-如何将Kerberos的CDH6.1从Oracle JDK 1.8迁移至OpenJDK 1.8
- 635℃Oracle数据库的单、多行函数 oracle执行多个sql语句
- 631℃Oracle 12c PDB迁移(一) oracle迁移到oceanbase
- 618℃【数据统计分析】详解Oracle分组函数之CUBE
- 616℃最佳实践 | 提效 47 倍,制造业生产 Oracle 迁移替换
- 592℃Oracle有哪些常见的函数? oracle中常用的函数
- 最近发表
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端路由 (61)
- 前端数组 (73)
- 前端js面试题 (50)
- 前端定时器 (59)
- Oracle RAC (76)
- oracle恢复 (77)
- oracle 删除表 (52)
- oracle 用户名 (80)
- oracle 工具 (55)
- oracle 内存 (55)
- oracle 导出表 (62)
- oracle约束 (54)
- oracle 中文 (51)
- oracle链接 (54)
- oracle的函数 (58)
- oracle面试 (55)
- 前端调试 (52)
本文暂时没有评论,来添加一个吧(●'◡'●)