大公司里怎样开发和部署前端代码?

前端训练营:1v1私教,终身辅导计划,帮你拿到满意的 offer 已帮助数百位同学拿到了中大厂 offer。欢迎来撩~~~~~~~~

Hello,大家好,我是 Sunday。

昨天的时候有同学问到前端部署相关的内容,正好在知乎中看到了张云龙大佬的前端部署回答

回答地址:https://www.zhihu.com/question/20790576

这个回答非常有价值,应该可以帮助到很多对部署不是很了解的同学,因此整理

问题

首先把问题给大家贴出来,如果大家也有类似的困惑,那么本文章肯定会给你带来一定的收获

大公司里怎样开发和部署前端代码?

主要有以下问题:

  • 开发时的和部署时类库的引用和存放是一致还是不同?
  • 模块放在项目中还是放在 CDN 之类服务器?
  • 渲染网页用 Nginx 还是其他动态语言的 Web 服务器?
  • 制作网页的流程,是先有设计师的稿,还是先看模块?
  • 会选择用自己写的模块还是从社区寻找模块?

其他的思考

你平时在公司中是怎么部署项目的呢?

  • 直接执行 npm run build 打包项目
  • 得到 dist 文件夹,放到服务器对应位置
  • 重新执行 nginx -s reload 完成部署

这样应该没有什么问题了。撑死再去解决下跨域的问题,一般的中小公司部署就算是完成了。

但是 部署真的有那么简单吗?那些大厂的部署也是通过以上方式完成的吗?

让我们一起来看看吧~~

正文

基础部署逻辑

当我们回归到最基本的前端开发时,就像看到了这个"可爱"的index.html页面和它的样式文件a.css,简单地用文本编辑器书写代码,不需进行编译,只要本地预览确认无误,然后将其放到服务器上等待用户访问。

前端开发就是"如此简单",很轻松嘛!门槛也是相当低嘛!轻轻松松掌握有木有!!

然后我们访问页面,看到效果,再查看一下网络请求,200!不错,太™完美了!那么,研发完成。。。。了么?

等等,这还没完呢!对于大公司来说,那些变态的访问量和性能指标,将会让前端一点也不“好玩”。

看看那个a.css的请求吧,如果每次用户访问页面都要加载,是不是很影响性能,很浪费带宽啊,我们希望最好这样:

利用304,让浏览器使用本地缓存。

但,这样也就够了吗?不成!

304叫协商缓存,这玩意还是要和服务器通信一次,我们的优化级别是变态级,所以必须彻底灭掉这个请求,变成这样:

强制浏览器使用本地缓存(cache-control/expires),不要和服务器通信。好了,请求方面的优化已经达到变态级别,那问题来了:你都不让浏览器发资源请求了,这缓存咋更新?

很好,相信有人想到了办法:通过更新页面中引用的资源路径,让浏览器主动放弃缓存,加载新资源。好像这样:

下次上线,把链接地址改成新的版本,就更新资源了不是。OK,问题解决了么?!

当然没有!大公司的变态又来了,思考这种情况:

页面引用了3个css,而某次上线只改了其中的a.css,如果所有链接都更新版本,就会导致b.css,c.css的缓存也失效,那岂不是又有浪费了?!

重新开启变态模式,我们不难发现,要解决这种问题,必须让url的修改与文件内容关联,也就是说,只有文件内容变化,才会导致相应url的变更,从而实现文件级别的精确缓存控制。

什么东西与文件内容相关呢?我们会很自然的联想到利用 数据摘要要算法 对文件求摘要信息,摘要信息与文件内容一一对应,就有了一种可以精确到单个文件粒度的缓存控制依据了。好了,我们把url改成带摘要信息的:

这回再有文件修改,就只更新那个文件对应的url了,想到这里貌似很完美了。你觉得这就够了么?大公司告诉你:图样图森破!

唉~~~~,让我喘口气

现代互联网企业,为了进一步提升网站性能,会把静态资源和动态网页分集群部署,静态资源会被部署到CDN节点上,网页中引用的资源也会变成对应的部署路径:


这次发布,同时改了页面结构和样式,也更新了静态资源对应的url地址,现在要发布代码上线,亲爱的前端研发同学,你来告诉我,咱们是先上线页面,还是先上线静态资源?

  1. 先部署页面,再部署资源:在二者部署的时间间隔内,如果有用户访问页面,就会在新的页面结构中加载旧的资源,并且把这个旧版本的资源当做新版本缓存起来,其结果就是:用户访问到了一个样式错乱的页面,除非手动刷新,否则在资源缓存过期之前,页面会一直执行错误。
  2. 先部署资源,再部署页面:在部署时间间隔之内,有旧版本资源本地缓存的用户访问网站,由于请求的页面是旧版本的,资源引用没有改变,浏览器将直接使用本地缓存,这种情况下页面展现正常;但没有本地缓存或者缓存过期的用户访问网站,就会出现旧版本页面加载新版本资源的情况,导致页面执行错误,但当页面完成部署,这部分用户再次访问页面又会恢复正常了。

好的,上面一坨分析想说的就是:先部署谁都不成!都会导致部署过程中发生页面错乱的问题。所以,访问量不大的项目,可以让研发同学苦逼一把,等到半夜偷偷上线,先上静态资源,再部署页面,看起来问题少一些。

但是,大公司超变态,没有这样的“绝对低峰期”,只有“相对低峰期”。So,为了稳定的服务,还得继续追求极致啊!

这个奇葩问题,起源于资源的 覆盖式发布,用 待发布资源 覆盖 已发布资源,就有这种问题。解决它也好办,就是实现 非覆盖式发布。

看上图,用文件的摘要信息来对资源文件进行重命名,把摘要信息放到资源文件发布路径中,这样,内容有修改的资源就变成了一个新的文件发布到线上,不会覆盖已有的资源文件。上线过程中,先全量部署静态资源,再灰度部署页面,整个问题就比较完美的解决了。

什么是灰度?

软件开发通常是逐个版本不断迭代的过程。尽管新版本在上线前经过了测试,但即使如此,也无法确保没有问题。

因此,在公司里,上线新版本代码通常通过灰度系统。灰度系统能够将流量分为多个部分,其中一部分流向新版本代码,另一部分流向旧版本代码。

而且,灰度系统可以设置流量的比例。例如,可以将走新版本代码的流量设置为 5%,确认没有问题后再逐步增加到 10%,50%,最终到达 100% 的全量。这样做可以将出现问题的影响降到最低。

否则,如果一开始就直接使用全量流量,一旦出现线上问题,就可能引发重大事故。

此外,灰度系统不仅仅用于此,例如,当产品不确定某些更改是否有效时,需要进行 A/B 实验,将流量分为两部分,一部分走 A 版本代码,另一部分走 B 版本代码。

那么这样的灰度系统是如何实现的呢?实际上,很多都是通过 nginx 实现的。

nginx 是一个反向代理的服务,用户的请求发送给它,然后由它转发给具体的应用服务器。

它的工作流程如下图所示:

首先,需要对流量进行染色,即对每个用户进行标注,让某些用户访问服务1,而其他用户访问服务2。染色的方法有很多种,可以通过cookie来实现。不同的用户携带不同的cookie。一开始所有用户都访问服务1。

然后,在用户进行第二次访问时,nginx 根据用户携带的cookie将其转发到不同的服务,从而实现灰度访问。

好了,灰度部署的介绍就到这里。回到原文提到的先全量部署静态资源,再灰度部署页面,这是什么意思呢?

当进行静态资源的部署时,不必删除原有的静态资源,而是复制新的静态资源过去。由于文件名采用了摘要算法重命名,因此不会出现重名的问题。

在灰度部署动态页面方面,部分用户访问旧页面,而另一部分用户访问新页面。对于访问旧页面的用户,其请求仍指向旧资源并直接使用缓存。对于访问新页面的用户,他们访问的是已经完成部署的新资源,避免了访问旧资源导致页面错误的情况。

最后,根据用户访问情况,通过灰度系统逐步将访问旧页面的用户过渡到新页面上。

部署方案总结

所以,大公司的静态资源优化方案,基本上要实现这么几个东西:

  • 配置超长时间的本地缓存
  • 节省带宽,提高性能采用内容摘要作为缓存更新依据
  • 精确的缓存控制静态资源CDN部署
  • 优化网络请求更资源发布路径实现非覆盖式发布
  • 平滑升级

全套做下来,就是相对比较完整的静态资源缓存控制方案了,而且,还要注意的是,静态资源的缓存控制要求在前端所有静态资源加载的位置都要做这样的处理。是的,所有!什么js、css自不必说,还要包括js、css文件中引用的资源路径,由于涉及到摘要信息,引用资源的摘要信息也会引起引用文件本身的内容改变,从而形成级联的摘要变化,大概示意图就是:

好了,目前我们快速的学习了一下前端工程中关于静态资源缓存要面临的优化和部署问题,新的问题又来了:这™让工程师怎么写码啊!!!

要解释优化与工程的结合处理思路,又会扯出一堆有关模块化开发、资源加载、请求合并、前端框架等等的工程问题,以上只是开了个头,解决方案才是精髓,但要说的太多太多,有空再慢慢展开吧。或者大家可以去我的blog看其中的一些拆解:https://github.com/fouber/blog

总之,前端性能优化绝逼是一个工程问题!

以上不是我YY的,可以观察 百度 或者 facebook 的页面以及静态资源源代码,查看它们的资源引用路径处理,以及网络请中静态资源的缓存控制部分。再次赞叹facebook的前端工程建设水平,跪舔了。

建议前端工程师多多关注前端工程领域,也许有人会觉得自己的产品很小,不用这么变态,但很有可能说不定某天你就需要做出这样的改变了。而且,如果我们能把事情做得更极致,为什么不去做呢?

另外,也不要觉得这些是运维或者后端工程师要解决的问题。如果由其他角色来解决,大家总是把自己不关心的问题丢给别人,那么前端工程师的开发过程将受到极大的限制,这种情况甚至在某些大公司都不少见!

妈妈,我再也不玩前端了。。。。5555


10.29 日更新

在评论中, @陈钢@fleuria @林翔 提到了rails,刚刚去看了一下,确实是完成了以上所说的优化细节,对整个静态资源的管理上的思考于本答案描述的一致。很遗憾我直到今天(2014-10-29)才了解到rails中的assets pipeline。这里向以上3位同学道歉,原谅我的无知。

不过整篇回答没有讲解到具体的解决方案实现思路,只是介绍了前端在工程化方向的思考,答案本身是可用的,了解rails的人也可以把此答案当做是对rails中assets pipeline设计原理的分析。

rails通过把静态资源变成erb模板文件,然后加入<%= asset_path 'image.png' %>,上线前预编译完成处理,不得不承认,fis的实现思路跟这个几乎完全一样,但我们当初确实不知道有rails的这套方案存在。


10.31 日更新

用 FIS3(https://fis.baidu.com/) 包装了一个小工具,完整实现整个回答所说的最佳部署方案,并提供了源码对照,可以感受一下项目源码和部署代码的对照。

  • 源码项目:fouber/static-resource-digest-project · GitHub
  • 部署项目:fouber/static-resource-digest-project-release · GitHub
  • 部署项目可以理解为线上发布后的结果,可以在部署项目里查看所有资源引用的md5化处理。

这个示例也可以用于和assets pipeline做比较。fis没有assets的目录规范约束,而且可以以独立工具的方式组合各种前端开发语言(coffee、less、sass/scss、stylus、markdown、jade、ejs、handlebars等等你能想到的),并与其他后端开发语言结合。

assets pipeline的设计思想值得独立成工具用于前端工程,fis就当做这样的一个选择吧。

1v1私教,帮大家拿到满意的 offer

我目前在做一个 前端训练营 ,主打的就是:1v1 私教,帮大家拿到满意的 offer 。

可以点击这里查看详情

也可以直接加我微信沟通,备注【训练营】:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/595928.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flask入门教程

Flask入门教程 简介 Flask是由Armin ronacher于2010年用Python语言基于 Werkzeug 工具箱编写的轻量级Web开发框架。 特点 Flask只提供核心功能&#xff0c;其他几乎所有的功能都需要用到拓展&#xff0c;比如可以通过Flask-SQLAlchemy拓展对数据库进行操作等等。 核心 由…

基于双向LSTM模型完成文本分类任务

6.4.1 数据处理 IMDB电影评论数据集是一份关于电影评论的经典二分类数据集&#xff0e;IMDB 按照评分的高低筛选出了积极评论和消极评论&#xff0c;如果评分 ≥7≥7&#xff0c;则认为是积极评论&#xff1b;如果评分 ≤4≤4&#xff0c;则认为是消极评论&#xff0e;数据集包…

“ManageEngine荣获Gartner SIEM客户选择四连冠“

我们非常激动地宣布&#xff0c;ManageEngine已经连续第四次被认定为Gartner Peer Insights‘Voice of the Customer’&#xff1a;安全信息与事件管理&#xff08;SIEM&#xff09;中的客户选择。这不仅是对我们卓越SIEM解决方案承诺的肯定&#xff0c;也延续了ManageEngine在…

LINUX基线要求及加固方法

《YDT 2701-2014 电信网和互联网安全防护基线配置要求及检测要求 操作系统 LINUX篇》 一、账号 应按照不同用户分配不同账号 检查/etc/passwd是否有只有root用户&#xff0c;应用应使用其他用户账号部署 限制用户su到root 编辑su文件(vi /etc/pam.d/su)&#xff0c;在开头添…

检测和缓解僵尸网络

僵尸网络源自“机器人网络”一词&#xff0c;是感染了恶意软件的网络或机器集群&#xff0c;允许黑客控制并发起一系列攻击。僵尸网络的强度完全取决于它所包含的受感染机器的数量。攻击者接管这些设备的操作&#xff0c;以使用僵尸网络命令和控制模型进行远程控制。 什么是僵…

<HarmonyOS第一课>应用程序框架

【习题】应用程序框架 目录 判断题 单选题 多选题 判断题 1. 一个应用只能有一个UIAbility。错误 正确(True)错误(False) 2. 创建的Empty Ability模板工程&#xff0c;初始会生成一个UIAbility文件。正确 正确(True)错误(False) 3. 每调用一次router.pushUrl()方法&…

MultipartFile转换file

文章目录 前言一、方法二、注意事项 前言 最近项目中需要处理一个图片上传的业务&#xff0c;将MultipartFile转换file类型文件&#xff0c;然后处理&#xff0c;这里浅浅记录一下 一、方法 private static File convert(MultipartFile file) throws IOException {File convFi…

K线+直线 现货黄金也可能变现

现货黄金行情怎么做&#xff0c;这是投资者需要思考的问题。幸运的是&#xff0c;现在市面上有很多书籍&#xff0c;是其他有经验、有想法的投资者们对其经验的总结和分享&#xff0c;此外网络上还有不同的文章和各种各样的视频介绍相关交易经验&#xff0c;这都是可以让我们借…

22款奔驰GLE450升级香氛负离子 车载香薰

相信大家都知道&#xff0c;奔驰自从研发出香氛负离子系统后&#xff0c;一直都受广大奔驰车主的追捧&#xff0c;香氛负离子不仅可以散发出清香淡雅的香气外&#xff0c;还可以对车内的空气进行过滤&#xff0c;使车内的有害气味通过负离子进行过滤&#xff0c;达到车内保持清…

prototype 和 __proto__

是什么&#xff1f; prototype&#xff08;显示原型&#xff09;&#xff1a;每个函数都有一个prototype属性__proto__&#xff08;隐式原型&#xff09;&#xff1a;每个实例对象都会有__proto__属性 两者有什么关系&#xff1f; 一般&#xff0c;构造函数的显示原型和其实例…

智能指针的延迟报错问题

最近工作上发现一个比较复杂的代码出现随机报错问题&#xff0c;话不多说&#xff0c;直接debug模式开启ASAN机制构建程序&#xff0c; set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g -fstack-protector -fsanitizeaddress -fno-omit-frame-pointer")很快能定位…

huggingface——设置不同层不同学习率

前言 这玩意教程咋这么难找&#xff1f;&#xff1f;&#xff1f;&#xff1f; 代码 参考&#xff1a;https://github.com/X-PLUG/mPLUG-Owl/blob/main/mPLUG-Owl2/mplug_owl2/train/mplug_owl2_trainer.py#L133C33-L133C33 先定义你的trainer&#xff0c;继承huggingface的…

[EFI]英特尔 冥王峡谷 NUC8i7HVK 电脑 Hackintosh 黑苹果efi引导文件

硬件型号驱动情况主板 英特尔 NUC8i7HVK 处理器 Intel Core™ i7-8809G (Kaby Lake-r) 已驱动内存2x16GB DDR4-2400已驱动硬盘1TB PCIe-NVMe M.2 SSD已驱动显卡Intel HD 630 (Empty Framebuffer)Radeon™ RX Vega M GH Graphics 4GB已驱动声卡Realtek HDA ALC700已驱动网卡 英特…

前端根据URL地址实现下载(txt,图片,word,xlsx,ppt)

前端根据URL地址实现下载&#xff08;txt&#xff0c;图片&#xff0c;word&#xff0c;xlsx&#xff0c;ppt&#xff09; 一、对于txt,图片类的二、对于word&#xff0c;xlsx&#xff0c;ppt类的1.a标签可以实现下载2. window.open&#xff08;&#xff09; 一、对于txt,图片类…

aliexpress商品API(item_get-获得aliexpress商品详情):进行批量操作

使用AliExpress的店铺或分类API&#xff1a;这些API可以为你提供某个店铺或分类下的所有商品列表&#xff0c;然后你可以根据这个列表逐个查询商品详情。分批查询&#xff1a;你可以将商品ID分成多个批次&#xff0c;每次只查询一部分商品详情&#xff0c;这样既可以减少每次请…

用雪花算法生成全局唯一序列

雪花算法是一种分布式唯一ID生成算法&#xff0c;通过对时间戳、工作节点ID和序列号进行位运算和组合&#xff0c;生成一个可排序且唯一的64位ID。 实现原理&#xff1a; 首先&#xff0c;我们需要定义算法中的参数&#xff1a; 时间戳&#xff1a;使用当前时间戳&#xff0c;…

记录一个常量定义导致的重复问题duplicate symbol ‘_kk‘ in:

原因&#xff1a; 在.h文件中定义了一个常量 如下 NSString *const kk "FASDF";interface CardCourseViewController : LBBaseViewControllerend将这句代码去掉即可 NSString *const kk "FASDF";![请添加图片描述](https://img-blog.csdnimg.cn/direct…

工业RFID技术发展趋势分析

RFID技术是物联网的重要组成部分&#xff0c;是连接物理世界和数字世界的关键节点。RFID技术已经广泛应用于供应链管理、智能物流、零售、医疗、安防等领域&#xff0c;在工业制造领域也有着广泛的应用前景和市场潜力。 工业RFID技术发展趋势分析 工业RFID技术是一种利用无线射…

买工业用品就找震坤行,提供震坤行商品数据,数据分析的API接口

要接入API接口以采集电商平台上的商品数据&#xff0c;可以按照以下步骤进行&#xff1a; 1、找到可用的API接口&#xff1a;首先&#xff0c;需要找到支持查询商品信息的API接口。这些信息通常可以在电商平台的官方文档或开发者门户网站上找到。 2、注册并获取API密钥&#x…

什么是差值表达式

在Vue.js中&#xff0c;差值表达式是一种基本的数据绑定形式&#xff0c;用于将数据绑定到文档对象模型&#xff08;DOM&#xff09;上。差值表达式通常使用双大括号 {{ }} 来表示&#xff0c;这种语法非常直观。当Vue实例的数据发生变化时&#xff0c;差值表达式的内容也会相应…