随着互联网开发和迭代速度越来越快,网站也变得越来越庞大,存在大量静态资源,我们原有管理静态资源的方式变得越来越不适用,就如同封面图一样,静态资源之间的关系错综复杂,给工程师带来了很多麻烦:
成都创新互联专注于企业营销型网站建设、网站重做改版、从江网站定制设计、自适应品牌网站建设、H5开发、商城网站建设、集团公司官网建设、外贸网站建设、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为从江等各大城市提供网站开发制作服务。
每天工程师都会提交大量的 new feature/bug fixes,每次项目发布和迭代都面临着以上的问题,是否可以有一套系统帮助我们管理/调度静态资源来减少人工管理静态资源成本和风险,来达到更快、更可靠、低成本的自动化项目交付。在实际项目开发中,我们进行了大量探索和试验,实现了一套 “静态资源管理系统”,对静态资源进行全流程的管理和调度:
下面本文将会介绍我们是如何通过静态资源系统来高效管理静态资源的。
静态资源管理系统主要包含Compile、Sourcemap、Backend-Framework、Frontend-Loader几个核心模块:
静态资源管理系统通过自动化工具对静态资源进行预处理并产出 Sourcemap,SourceMap 中记录着静态资源的调度信息,这样框架在运行时会根据 SourceMap 中提供的调度信息自动为用户进行静态资源调度,不仅可以做到送达不同资源给不同用户,还可以自适应优化静态资源合并和加载。
静态资源管理系统为工程师提供了声明依赖关系的语法和规则,在 compile 阶段系统会扫描静态资源,建立一张静态资源关系表,记录每个静态资源的部署路径以及依赖关系等信息。
在项目的 index.html 里使用注释声明依赖关系:
在 SourceMap 中则可看到:
- {
- "res" : {
- "demo.css" : {
- "uri" : "/static/css/demo_7defa41.css",
- "type" : "css"
- },
- "demo.js" : {
- "uri" : "/static/js/demo_33c5143.js",
- "type" : "js",
- "deps" : [ "demo.css" ]
- },
- "index.html" : {
- "uri" : "/index.html",
- "type" : "html",
- "deps" : [ "demo.js", "demo.css" ]
- }
- },
- "pkg" : {}
- }
支持识别 js 文件中的 require 函数,或者 注释中的 @require 字段 标记的依赖关系,这些分析处理对 html 的 script 标签内容 同样有效。
- //demo.js
- /**
- * @require demo.css
- * @require list.js
- */
- var $ = require('jquery');
在SourceMap中则可看到:
- {
- "res" : {
- ...
- "demo.js" : {
- "uri" : "/static/js/demo_33c5143.js",
- "type" : "js",
- "deps" : [ "demo.css", "list.js", "jquery" ]
- },
- ...
- },
- "pkg" : {}
- }
支持识别 css 文件 注释中的 @require 字段 标记的依赖关系,这些分析处理对 html 的 style 标签内容 同样有效。
- //demo.js
- /**
- * @require demo.css
- * @require list.js
- */
- var $ = require('jquery');
在SourceMap中则可看到:
- {
- "res" : {
- ...
- "demo.js" : {
- "uri" : "/static/js/demo_33c5143.js",
- "type" : "js",
- "deps" : [ "demo.css", "list.js", "jquery" ]
- },
- ...
- },
- "pkg" : {}
- }
#p#
在静态资源管理系统接管了项目中的静态资源后,可以知道静态资源的运行情况以及依赖关系,然后可以做到自动为页面按需加载静态资源,下面通过一个例子来详细讲解:
sidebar.tpl 中的内容如下,
对项目编译后,自动化工具会分析依赖关系,并生成 sourcemap,如下
- "common:widget/sidebar/sidebar.tpl": {
- "uri": "common/widget/sidebsr/sidebar.tpl",
- "type": "tpl",
- "extras": {
- "async": [
- "common:ui/dialog/dialog.async.js"
- ]
- },
- "deps": [
- "common:ui/dialog/dialog.js",
- "common:ui/dialog/dialog.css"
- ]
- }
在 sidebar 模块被调用后,静态资源管理系统通过查询 sourcemap 可以得知,当前 sidebar 模块同步依赖 sidebar.js、sidebar.css,异步依赖 sdebar.async.js,在要输出的 html 前面,生成静态资源外链,我们得到最终的 html
如上可见,后端模块化框架将同步模块的 script url 统一生成到页面底部,将 css url 统一生成在 head 中,对于异步模块(require.async)注册 resourceMap 代码,框架会通过 {script} 标签收集到页面所有 script,统一管理并按顺序输出 script 到相应位置。
当我们想对模块进行打包,只需要使用一个 pack 配置项,对网站的静态资源进行打包,这样在 SourceMap 中,所有被打包的资源会有一个 pkg 属性指向该表中的资源,而这个资源,正是我们配置的打包策略。这样静态资源系统可以根据对应信息找到某个资源最终被合并后的 package 的 url,最后把这个 url 返回给页面。
静态资源管理系统可以根据产品线上静态资源使用的数据,自动完成静态资源合并工作,对工程师完全透明,解决手工维护的未及时排除废弃资源、不可持续、成本大等问题。
详情请见 静态资源自动合并;
静态资源管理系统采用基于文件内容的 hash 值来控制静态资源的版本更新,如下所示:
其中”_82244e91 ”这串字符是根据 a.js 的文件内容进行 hash 运算得到的,只有文件内容发生变化了才会有更改。这样做的好处有:
静态资源管理系统会在 compile 阶段识别文件中的定位标记(url),计算对应文件的 hash,并自动替换为 '文件名 + hash',无需工程师手动修改。
静态资源管理系统可以对静态资源做进一步控制(Controlling Access to Features)以达到分级发布的效果,主要包括以下两块核心功能,
通过以上的控制我们可以轻松做到发布一个新功能,让这个功能只对部分用户可访问,当功能完善后对所有用户开放,如果功能出现问题直接一键回滚即可。
在项目中的类似代码如下:
- {if $config.some eq 'Fred'}
- do something new and amazing here.
- {elseif $config.some eq 'Wilma'}
- do the current boring stuff.
- {else}
- whatever you are.
静态资源管理系统会根据配置在运行时对 $config.some 进行干预.实现对静态资源的访问权控制,通过运行时的配置(feature flag)来控制静态资源,还可以支持“主干开发”的方式,来达到更快的迭代速度。
我们还可以实现国际化的需求,原理同分级发布,在运行时的做一些更细致的差异化处理
- {if $lang == 'zh-CN'}
- zh-CN
- {/if}
静态资源管理系统的核心是对静态资源进行调度,可以很灵活的适应各种性能优化和差异化处理的场景,来达到更快、更可靠、低成本的自动化项目交付。但是同时这个系统十分复杂,承载着各种职责,这个系统本身会成为整个网站的关键节点和瓶颈。
作者:walter (http://weibo.com/u/1916384703) - F.I.S
分享文章:如何高效地管理网站静态资源
当前路径:http://www.mswzjz.cn/qtweb/news18/118118.html
攀枝花网站建设、攀枝花网站运维推广公司-贝锐智能,是专注品牌与效果的网络营销公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 贝锐智能