前端静态资源部署

前几天厂里的网突然渣掉了,某些网页变得极度卡顿,但是划水网站依旧流畅;我觉得很有趣就打开 DevTools 对比了一下,结果看到某卡顿网页的 Network 状况如下,我大概猜到了一些缘由。这期就借机讲讲前端部署里的一些小技巧吧。

Network

原始前端

OK,这期讨论的原始前端当然也没那么“原始”,我无意追述到 JSP,thymeleaf 这类传统后端渲染的技术。只是说“原始前端”开发比较简单,只需要一页文本编辑器,一份 html 模版和一款打包工具(webpack);部署更简单,webpack 构建并打包出 html、css、js,然后一股脑丢到服务器上就行。当请求到来时,服务器返回 index.html, 然后再把它的相关引用(js、css)返回给客户端即可。

Server

但是这里有个问题是,引用文件名——onion.js——是固定的:一旦部署更新后,就得防止客户端缓存旧文件,所以一般会设置Cache-Control: no-cache。这就是文章开头提到的一个问题,每次打开页面都得重新加载一遍引用文件,一旦网络渣渣了,首页渲染就会十分缓慢。

版本管理

看样子缓存策略还是需要保留的,可如何兼顾更新呢?有人就想到了给引用路劲加个版本号:

Version

p.s. index.html 始终是 no-cache

新版本上线后,浏览器请求 html,发现资源路劲更改了,便主动放弃相关缓存,重新加载引用文件。这个小小的改变很实用,兼顾了缓存策略和新旧版本文件冲突。至于这个版本号怎么添加,各色打包工具都能实现,最简单的策略就是在 index.html 模版里加个时间戳。

摘要算法

当然,随着业务增长,js 和 css 文件会变得愈发巨大,仅仅加载单个文件就可能需要数秒。遇到问题就解决问题,把大文件拆成小份就行了!利用浏览器异步加载多个文件的机制,拆分 JS 能迅速提速。(当然,浏览器并发加载数有限,拆太细会适得其反)。

multi-link

这时候有聪明人就发现了:每次更新时,某些 js 文件并没有被修改,为什么也要增加版本号呢?让客户无端加载一个一模一样的 js 文件,不是很浪费吗?

反正版本号就是一个 unique 值——防冲突用的,不如换成别的数值吧?比如,经典的MD5(消息摘要)算法生成的content hash值,该哈希值与文件内容一一对应的,这就有了精确到单个文件的版本控制信息了。

Content Hash

我自己开发时,会利用 webpack 的 splitChunks 功能,把 Vue 全家桶打包成单个 js 文件、UI 框架也打包成单个 js;这种文件体积不小,但基本不会变动,cache-control/max-age可以写大一些,客户端除了首次访问会慢一点,其他时候基本就disk cache了。

CDN

上面提到服务器存放静态资源文件,但这种形式在性能上也有缺陷:

  • 受地理环境影响,离服务器越远资源加载越慢
  • 频繁请求资源对服务器压力较大

为了进一步提升性能,大家开始把动态网页(index.html)和静态资源(js、css、image...)分开部署。静态资源被放置于 CDN 上。

CDN

但是 CDN 也有缓存策略:新的静态资源发布后,需要一定的时间去覆盖各个边缘站点的旧资源。若某客户端获得了新的动态网页,但是附近的 CDN 节点尚未更新最近发布的静态资源,客户端即便放弃本地缓存,它加载的依旧是位于 CDN 上的“脏数据”。怎么办呢?干脆把文件名也给改了——让摘要信息成为文件名的一部分!具体实现还是可以仰仗 webpack,将 output.filename 设为 [name].[contenthash].js,输出文件和 html 模版都会帮你更改好。

Hash Name

用摘要信息重命名后的资源文件,与旧资源就不同名了,不再需要以覆盖旧文件的形式主动更新各个地区的边缘站点。新版本发布后,浏览器首次请求资源,若 CDN 不存在该资源,便会向就近的边缘站点加载该文件,同时更新 CDN 缓存;这就彻底避免了 CDN 脏数据的问题。

Build

关于构建,我自己所在项目组的做法是前端单独部署:git 接收 MR 后触发 AWS 的 code pipeline 和 code build;Webpack 自动打包生成dist文件夹(里面包含 html、js、css 等资源),html 部署到服务器上,其他静态资源发布到 CDN 上。这一套下来也不贵:一个月十几刀,每次部署也就几分钟。但是,但是!我后来看到有些厂的做法,觉得实在是太“抠”了——成本控制得真好!

他们的做法是这样的:build 在开发环境就完成了,然后把打包生成的dist文件夹也 push 到 git 上。好处很明显:

  • 节省了一套 code pipeline + code build 的花费:大公司就不是一个月十几刀的事了
  • 大大缩短 build 时间:构建环境是不包含node_modules的,大型项目光npm install就要很久,build 时间更是感人

而开发人员本地 build,可以很完美地绕开上面两个缺点。配置上写个 hook,在git commit时多加如下三个 changes 即可:

modified: dist/index.html
delete:   dist/garlic.6b58.js
new file: dist/garlic.e5i1.js

最后的牺牲只是 git repo 上包含了一个 dist 文件夹而已,真的是很“抠门”啊。

小结

这期内容很简单,讲了讲静态资源文件名的那些事,算是螺蛳壳里做道场吧。一直在想一件事,我们追求新技术的本质是什么?我觉得是降低成本!软件本质上还是属于“工业产品”。新闻上能看到一些重工业单位通过调整工艺大大降低成本的案例;我们做软件的也应该不断调整工艺,降低成本、减少设备消耗,从而帮助公司赚取更多的利润。我曾看过有人形容软件开发就是一种缓慢地破坏+重建的过程,这种观点还是挺有道理的,分享给大家。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容