uWyndA 的 2021 年终总结

635 阅读6分钟

「时光不负,创作不停,本文正在参加2021年终总结征文大赛

前言

虽说是2021年总结,但故事却还从2020年10月开始讲起

正文

关于工作

2020年10月,我从一家10105.5的公司跳槽到目前的一家965的PaaS公司,也经历了一系列的挑战。

我所在的部门是一个大前端部门,部门内有安卓/ios开发,web/bff开发,electron开发以及C++开发。

而我所在的二级部门是其中的「web/bff开发」,最开始进去的主要从事一个从0到1的h5项目。

微服务

首先去了解了一下公司项目的部署方式。

公司内部的部署团队研发了一套容器化部署框架,因此这个h5项目也需要完成满足公司容器化部署框架的微服务,并注册到公司的容器服务集群中。

于是我就开始了我的h5项目微服务的搭建,其中涉及到了一些我之前没有使用过的技术:

  1. helm chart
  2. jenkins
  3. yaml(抱歉,我居然以前连yaml都没写过
  4. kubectl命令
  5. docker命令

由于公司没有专用的test,pre,prd环境,公司内部提供类似阿里云的云平台,可申请机子自用。因此我搭建了一套项目环境(内心OS,为啥没运维呢)

在jenkins pipeline失败了N多次,slb-nginx访问失败了N多次,ingress设置失败了N次,helm install失败了N多次后,我的pod终于安装好了!

微前端

在微服务pod完成后,我开始setup这个h5项目。

emm,项目其实没啥好说的,就正常的React + React Hooks + TypeScript。额外有一点是,这个项目是作为未来要在重点项目里实现的「客户端开放性」而预研的微前端技术。

而难点在于部署,按照刚才说的微服务的部署,难道我要每一个子应用都部署一个微服务吗,这也太坑爹了吧。

于是我想到一种方式:

  1. 在微服务pod的入口处架一个nginx的docker container
  2. 在微服务pod里注册其他的子应用的docker container
  3. 用nginx把流量导到对应的子应用docker container暴露的端口内

试了下,bingo!这样就可以我想怎么玩就怎么玩,而不需要跟每次新增子应用都要走上面微服务的部署流程了。这样每新增一个子应用,就只需要在nginx config里增加这个location,在helm chart里增加这个container,正常走构建出对应的镜像就好了。

monorepo

嗯,既然有1个主应用+N个子应用+一个nginx,那就弄一个monorepo吧。

通过 monorepo 策略组织代码,我的代码仓库的目录结构看起来会是这样:

├── lerna.json
├── package.json
├── composition # 子应用
    ├── app1 # 子应用1
    │   ├── index.ts
    │   ├── node_module/
    │   └── package.json
    ├── app2 # 子应用2
    │   ├── index.ts
    │   ├── node_module/
    │   └── package.json

    ...
├── core # 主应用
└── packages/ # 这里将存放所有可复用的代码
    ├── api # 可复用的请求以及req,res类型
    │   ├── index.ts
    │   ├── node_module/
    │   └── package.json
    ├── common # 可复用的hook,utils,context,const,store,types
    │   ├── index.ts
    │   ├── node_modules/
    │   └── package.json
    ├── components # 可复用的组件
    │   ├── index.ts
    │   ├── node_module/
    │   └── package.json
    ├── icons # 可复用的icons
    │   ├── index.ts
    │   ├── node_module/
    │   └── package.json
    ├── locales # 可复用的国际化
    │   ├── index.ts
    │   ├── node_module/
    │   └── package.json

    ...

monorepo的优势就不说了,只是在对的场景使用对的技术,毕竟软件开发没有「银弹」

性能优化

使用了lighthouse对首屏进行了优化检测,在几个层面做了优化

  • 措施1:优化LCP

    • 优化弹出框,替换过大背景图片。对图片做preload。加快图片下载
  • 措施2:减少无用JS、CSS,减小TBT,提升SI

    • 借助Webpack Bundle Analyzer帮助我们分析项目
    • 彻底code split
    • 前端路由懒加载
    • split chunk
    • 微前端预加载
  • 措施3:首图图片减小自定义首屏时间

  • 措施4:资源预加载

    • webpack插件来打包时增加preload属性
  • 措施5:减少CLS

    其实布局有偏移还是很常见的。比如我们的用户信息数据,在我的页面的用户信息卡片里,是异步接口获取的。所以看到可能会是页面先加载了一部分,然后拿到数据后进度条显示并生成进度条。这种异步的内容减少CLS的方式:

    • 可以想办法把这个异步接口合并到主接口里来解决,或者设置一个默认的图片占位。等数据来了再替换掉
    • useSWR:异步更新缓存策略
  • 措施6:浏览器缓存机制(协商缓存)

    结合强缓存和协商缓存,合理地缓存静态资源,比如当我们的资源内容不可复用时,直接为 Cache-Control 设置 no-store,拒绝一切形式的缓存;否则考虑是否每次都需要向服务器进行缓存有效确认,如果需要,那么设 Cache-Control 的值为 no-cache;否则考虑该资源是否可以被代理服务器缓存,根据其结果决定是设置为 private 还是 public;然后考虑该资源的过期时间,设置对应的 max-age 和 s-maxage 值;最后,配置协商缓存需要用到的 EtagLast-Modified 等参数。

插件框架

4个月后,我进入了公司的重点项目,进行客户端开放性的插件框架的开发

于是我给这个插件框架定义了几条属性

  • 插件开发的接入成本低
  • 重点项目本身需要支持插件开发的套壳开发
  • 插件框架对该重点项目的侵入性低

于是,在侵入性极低的前提下,我完成了插件框架。

倒也没啥难度,就二次封装了一下qiankun。

  • 做好拉取配置,格式化,注册,激活,依赖注入,切换,卸载等工作流的hook
  • 通过依赖注入,完成了提供主应用的能力给子应用的runtimeAPI
  • 适配了electron客户端的插件加载
  • 在框架中实现了插件开发的套壳开发,即使用一个支持了插件框架的重点项目的线上环境,使用sessionStorage注入一个定制的key和按开发文档规范配置的value,即可在线上环境里看到该插件,并热更新

关于技术

总结自己在这一年学习到了什么好像上文就已经概括了,说一些对明年的展望吧

React 18

毕竟要围绕自身工作的方向展开学习,而不是盲目学习前沿的技术

vue3

虽然不用,但是要学?

vite

让我感受一下极速的开发环境吧

Nest.js

在公司用到了,感觉很香,需要学习一下异常过滤器,管道,守卫,拦截器等

关于生活

今年是我跟她的第五个年头了,很幸运能在最美好的年华里遇到她

我们携手走过重庆的洪崖洞,漫步在成都的宽窄巷子,一起站在上海外滩FLIGHT集装箱里闭上眼睛,在大理苍山上举杯相拥

人潮拥挤

离别是常态,相逢只是意外

感激生命里

尚有你能让我满足到落泪

后记

推荐一首来自「发光曲线」的小雷音之歌

有一种向死而生的光线,每一個不曾起舞的日子,都是对生命的辜负

他应该漂亮,我应该对他充满信任,他应该成为我的爱情、我的偷盗、我的犯罪欲望的同谋

我是uWydnA,我们 2022 年再见,也祝读到此处的你,诸事顺利