HZNU-IISLab

杭师大信息安全实验室技术博客

0%

前端开发规范

前端方向(新人快看,有人在爬数!)

新人指南

工具

  • Visual Studio Code 编辑器
  • Google Chrome/Firefox 浏览器
    • Developer Tools 调试(F12)
  • Git 分布式版本控制系统,GitHub, Git Flow(要求掌握)
  • Postman http请求调试工具

技术栈

  • W3C

  • HTML5

  • CSS3

    • 预处理器
      • Sass
      • LESS
      • Stylus
    • CSS Modules 模块化
  • Javascript

    • ES6(当前js标准,需要掌握新特性,当前和较旧的浏览器或环境需要用 Babel 编译器转换向后兼容的版本 )
    • HTML DOM
    • jQuery
    • JSON
    • AJAX
    • TypeScript
  • Node.js (提供js服务端环境,前端必学)

    • npm 默认包管理工具, 还有 cnpm,yarn 等,安装依赖更快, npx调用项目安装的依赖
  • MV*框架 (客户端渲染, 源码github上都有)

    • React(入门难度中, 阿里系前端主要框架)

      • 官网

      • create-react-app 脚手架

      • React Hook

        Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
        React全家桶系列

      • react-dom

      • react-router(路由管理)

      • axios/fetch (数据交互)

      • Redux/mobx(状态管理, 适用任何MV*框架)

        使用mobx-react + mobx-state-tree 相对redux来说更轻量,面向对象编程,自由度高。
        redux有一套严格的规范,适合大型项目特别和团队开发的项目,函数式编程,虽然代码编写稍显繁复,但是整体数据流向清楚,便于问题跟踪和后期维护。

        • MobX State Tree数据组件化开发

          • 官网
          1. 开篇
          2. MST基础
          3. 实例-TodoList
          4. 选择正确的types.xxx
      • Antd/React-Desktop/Material-UI 快速开发UI组件库 (适合定制化要求不高,对性能会有影响)
        移动应用开发

      • React Native

    • Vue.js(入门简单, 适合初学者)

      • 官网

      • vue-cli 脚手架

      • vue-router(路由管理)

      • vuex(状态管理)

      • axios

      • element-ui(组件库)

    • AngularJs (入门难,学习成本高,大项目使用)

      • 官网
  • 模版引擎(服务端渲染)

    • Handlebars
    • Jade
    • Ejs
    • ……
  • Webpack 模块打包器

    • require.context 自动化导入模块
  • Babel JavaScript编译器

  • Gulp/Grunt 自动化工具

  • 渲染引擎

    • Trident (IE)
    • Blink / prev. WebKit (Chrome)
    • Gecko (Firefox)
    • WebKit (Safari)
    • Blink / prev. Presto (Opera)
    • EdgeHTML (Edge)
  • 脚本引擎(最好去阅读下Google V8引擎的源码)

    • JScript (IE8- / ASP)
    • Chakra (IE9+ / Edge)
    • V8 (Chrome / Opera / Nodejs / MongoDB)[GitHub]
    • SpiderMonkey (Firefox)
    • JavaScriptCore (Safari)
  • HTTP协议

  • WebSocket

  • 数据可视化

    • Echarts(推荐学习,简单易用)
    • HighCharts
    • svg
      • SVG Sprite
    • canvas
    • D3.js (当下最流行的数据可视化库)
    • WebGL (web图形库)
    • Three.js(3D库)
    • Mapbox GL JS(地图库),react-map-gl(react中更简易的使用mapbox)
    • deck.gl(可视化图层)

开发规范

加入团队开发,要遵从团队的风格

Markdown

  • 目录结构的制定

    以React项目为例
    public 公共资源
    config 配置目录,脚手架npm run eject后弹出react项目的配置文件,若不需要修改默认配置可忽略
    scripts 脚本目录,脚手架npm run eject后弹出react项目的脚本文件
    src 子目录说明

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    src/index.jsx:入口文件
    src/common:通用工具目录
    src/models:树模型目录,若不使用mobx(mobx-react + mobx-state-tree)状态管理,可忽略
    src/components:组件目录, 减少树形目录结构
    - index.js 组件目录索引,组件多的时候最好写下
    - example 组件示例
    - index.js 入口文件
    - example.jsx JSX组件文件,编写组件代码
    - example.module.styl css moudle文件,局部作用,这里我用的是stylus预处理器,可根据团队风格自行选择
    - field 输入域组件
    - index.js 入口文件
    - base.jsx 输入域基础(父级),统一所有输入域的布局和样式
    - base.module.styl
    - check 单选框组件,基于base组件的布局和样式
    - check.module.styl
    - text.jsx
    - textarea.jsx
    - icon 图标组件
    - panel 面板组件
    - src/pages:页面级入口`component`目录,和`src/components`中组件的主要区别,是这里的组件是异步载入的,Suspense 结合 lazy()
    - main 主页面
    - index.js 入口文件
    - main.jsx
    - main.module.styl
    - `src/icons` 图标目录
    `package.json` npm管理的项目的基础配置文件,开发环境依赖安装在devDependencies
    1
    2
    3
    // index.js
    import Example from './example'
    export default Example
  • 编码规范
    ps:偷个懒!放个名言。
    “程序是写给人读的,只是偶尔让计算机执行一下” ——Donald Knuth

    • JavaScript编码规范
      1. https://blog.csdn.net/pig_is_duck/article/details/106180125
      2. https://www.cnblogs.com/hustskyking/p/javascript-spec.html
    • CSS编码规范
      https://www.cnblogs.com/hustskyking/p/css-spec.html
    • 缩进:tab键设置2个空格,空行:最多空一行,代码保证层次感、阅读性的同时尽量紧凑
    • 注释
      1. 统一写在代码上方
      2. 可以使用JSDOC自动生成js注释文档
        • 入门指南
  • 前后端接口规范

    • 前后端分离开发时,前端可以通过Postman,mock,进行请求测试,假数据测试
    • 接口文档范例
      puer-mock-api-doc-html
  • 文档规范

    Markdown格式文档

    • 可行性分析报告(产品人员)
    • 项目开发计划(产品人员)
    • 软件需求说明书(产品人员)
    • 概要设计说明书 (开发人员)
    • 用户操作手册(产品人员)
    • 测试计划(测试人员)
    • 测试分析报告(测试人员)
    • 开发进度月报(开发人员)
    • 项目开发总结报告(产品人员)
    • 项目维护手册(开发人员)
    • 项目问题报告(测试人员)
    • 项目修改报告(开发人员)
  • 组件管理

    • 尽量设计低耦合,高复用的,功能性组件要满足能够独立交互,实现一个小功能即可,而不是承担多个职责
    • 集中/统一的状态管理
    • 组件目录中列出所有功能性组件,减少树形目录结构
    • 维护组件库文档,说明各组件的props(入参), state(状态),功能,设计思路(复杂组件)
  • Git分支管理

    阮一峰的网络日志
    Git分支管理策略http://www.ruanyifeng.com/blog/2012/07/git.html
    创建项目时(一般是服务型项目,工具型或辅助型项目可以简单一些),会针对不同环境创建三个常设分支:

    1. develop:开发环境的稳定分支,公共开发环境基于该分支构建。
    2. pre-release:测试环境的稳定分支,测试环境基于该分支构建。
    3. master:生产环境的稳定分支,生产环境基于该分支构建。仅用来发布新版本,除了从pre-release或生产环境Bug修复分支进行merge,不接受任何其它修改
      平时开发工作中,会根据需要由开发人员创建两类临时分支:
    4. 功能(feature)分支:为了开发某个特定功能,从develop分支上面分出来的。开发完成后,要merge到develop分支。功能分支的命名,可以采用feature-的形式命名(为任务单号)
    5. Bug修复(fixbug)分支:为了修复某个bug,从常设分支上面分出来的。修复完成后,再merge到对应的分支。Bug修复分支的命名,可以采用fixbug-的形式命名(为bug单号)
  • Commit描述规范
    commit 信息包括三个字段: type (必需), scope(可选) 和 subject(必需)。

    1. type。type 是用于说明该 commit 的类型的,一般我们会规定 type 的类型如下:
      • feat: 新功能(feature)
      • fix: 修复 bug
      • docs: 文档(documents)
      • style: 代码格式(不影响代码运行的格式变动,注意不是指 CSS 的修改)
      • refactor: 重构(既不是新增功能,也不是修改 bug 的代码变动)
      • test: 提交测试代码(单元测试,集成测试等)
      • chore: 构建或辅助工具的变动
      • misc: 一些未归类或不知道将它归类到什么方面的提交
    2. scope。scope 说明 commit 影响的范围,比如数据层,控制层,视图层等等,这个需要视具体场景与项目的不同而灵活变动
    3. subject。subject 是对于该 commit 目的的简短描述
      • 使用第一人称现在时的动词开头,比如 modify 而不是 modified 或 modifies
      • 首字母小写,并且结尾不加句号
    4. ISSUEE_ID。这个与公司的需求管理与项目管理有关,假设你的项目放在 github 上,你的需求或者 bug 修复可能会有对应的 issues 记录,你可以加到你的 commit 信息中如 issue-37938634
  • 定期CodeReview

    1. 检查设计的合理性和业务逻辑的正确性
      • 代码的设计是否符合设计要求
      • 业务逻辑是否正确
      • 关注业务可拓展性
      • 关注使用到的数据结构、设计模式和代码性能
    2. 检查代码可读性和可维护性
    3. 分享设计、技术、知识和经验
  • 视觉图标规范

    • 对界面元素的样式、颜色和大小设定统一的规范和使用原则
    • 图标视觉统一
  • 工程化

    • 构建、管理工具

      • Eslint 代码质量管理工具
      • Webpack打包工具
      • Gulp/Grunt 自动化构建工具
      • Git 分布式版本控制工具
    • js模块化

    1. Webpack+Babel 将所有模块打包成一个文件同步加载,也可以打成多个chunk异步加载
    2. SystemJS+Babel主要是分模块异步加载
    3. 用浏览器的<script type="module">加载
      目前Webpack远比SystemJS流行。Safari已经支持用type=”module”加载了
  • css模块化

  • 静态资源管理

  • 性能优化

    传输层面:减少请求数,降低请求量
    执行层面:减少重绘&回流

    传输层面的从来都是优化的核心点,而这个层面的优化要对浏览器有一个基本的认识,比如:

    ① 网页自上而下的解析渲染,边解析边渲染,页面内CSS文件会阻塞渲染,异步CSS文件会导致回流

    ② 浏览器在document下载结束会检测静态资源,新开线程下载(有并发上限),在带宽限制的条件下,无序并发会导致主资源速度下降,从而影响首屏渲染

    ③ 浏览器缓存可用时会使用缓存资源,这个时候可以避免请求体的传输,对性能有极大提高

    衡量性能的重要指标为首屏载入速度(指页面可以看见,不一定可交互),影响首屏的最大因素为请求,所以请求是页面真正的杀手,一般来说我们会做这些优化:

    • 减少请求数
      ① 合并样式、脚本文件

      ② 合并背景图片

      ③ CSS3图标、Icon Font,CSS Sprite

    • 降低请求量

      ① 开启GZip

      ② 优化静态资源,jQuery->Zepto、阉割IScroll、去除冗余代码

      ③ 图片无损压缩

      ④ 图片延迟加载

      ⑤ 减少Cookie携带

    很多时候,我们也会采用类似“时间换空间、空间换时间”的做法,比如:

    ① 缓存为王,对更新较缓慢的资源&接口做缓存(浏览器缓存、localsorage、application cache这个坑多)

    ② 按需加载,先加载主要资源,其余资源延迟加载,对非首屏资源滚动加载

    ③ fake页技术,将页面最初需要显示Html&Css内联,在页面所需资源加载结束前至少可看,理想情况是index.html下载结束即展示(2G 5S内)

    ④ CDN

    ……

    从工程的角度来看,上述优化点半数以上是重复的,一般在发布时候就直接使用项目构建工具做掉了,还有一些只是简单的服务器配置,开发时不需要关注。

    可以看到,我们所做的优化都是在减少请求数,降低请求量,减小传输时的耗时,或者通过一个策略,优先加载首屏渲染所需资源,而后再加载交互所需资源(比如点击时候再加载UI组件),Hybrid APP这方面应该尽可能多的将公共静态资源放在native中,比如第三方库,框架,UI甚至城市列表这种常用业务数据。

    • 消灭冗余(做代码精简)

      单从一个页面的加载来说,他需要以下资源:

      框架MVC骨架模块&框架级别CSS

      ② UI组件(header组件、日历、弹出层、消息框……)

      ③ 业务HTML骨架

      ④ 业务CSS

      ⑤ 业务Javascript代码

      ⑥ 服务接口服务

      因为产品&视觉会经常折腾全站样式加之UI的灵活性,UI最容易产生冗余的模块。

      1. UI组件

        UI组件本身包括完整的HTML&CSS&Javascript,一个复杂的组件下载量可以达到10K以上,就UI部分来说容易导致两个工程化问题:

        ① 升级产生代码冗余

        ② 对外接口变化导致业务升级需要额外开发

        UI升级

        最理想的升级是保持对外的接口不变甚至保持DOM结构不变,但多数情况的UI升级其实是UI重做,最坏的情况是不做老接口兼容,这个时候业务同事便需要修改代码。为了防止业务抱怨,UI制作者往往会保留两个组件(UI+UI1),如果原来那个UI是核心依赖组件(比如是UIHeader组件),便会直接打包至核心框架包中,这时便出现了新老组件共存的局面,这种情况是必须避免的,UI升级需要遵守两个原则:

        ① 核心依赖组件必须保持单一,相同功能的核心组件只能有一个

        ② 组件升级必须做接口兼容,新的特性可以做加法,绝不允许对接口做减法

        UI组成

        各个UI组件的样式打包至UI中按需加载

      2. 拆分页面

        一个PC业务页面,其模块是很复杂的,这个时候可以将之分为多个模块。业务组件一般重用性较低,会产生模块间的业务耦合,还会对业务数据产生依赖,但是主体仍然是HTML&CSS&Javascript,这部分代码也是经常导致冗余的,如果能按模块拆分,可以很好的控制这一问题发生。

        按照上述的做法现在的加载规则是:

        ① 公共样式文件

        ② 框架文件,业务入口文件

        ③ 入口文件,异步加载业务模块,模块内再异步加载其它资源

        这样下来业务开发时便不需要引用样式文件,可以最大限度的提升首屏载入速度;需要关注的一点是,当异步拉取模块时,内部的CSS加载需要一个规则避免对其它模块的影响,因为模块都带有样式属性,页面回流、页面闪烁问题需要关注。

        一个实际的例子是,点击出发后的城市列表便是一个完整的业务组件,城市选择的资源是在点击后才会发生请求,而业务组件内部又会细分小模块,再细分的资源控制由实际业务情况决定,过于细分也会导致理解和代码编写难度上升

        冗余是首屏载入速度最大的拦路虎,是历史形成的包袱,只要能消除冗余,便能在后面的路走的更顺畅,这种组件化编程的方法也能让网站后续的维护更加简单。

      3. 代码压缩,优化和压缩静态资源,减少总下载量

        ① 文本优化

        ② 图像优化

    • 资源加载优化

      解决冗余便抛开了历史的包袱,是前端优化的第一步也是比较难的一步,但模块拆分也将全站分成了很多小的模块,载入的资源分散会增加请求数;如果全部合并,会导致首屏加载不需要的资源,也会导致下一个页面不能使用缓存,如何做出合理的入口资源加载规则,如何合理的善用缓存,是前端优化的第二步。

      资源缓存

      资源缓存是为二次请求加速,比较常用的缓存技术有:

      ① 浏览器缓存

      ② localstorage缓存

      ③ application缓存

      application缓存更新一块不好把握容易出问题,所以更多的是依赖浏览器以及localstorage

    • 渲染优化

      当请求资源落地后便是浏览器的渲染工作了,每一次操作皆可能引起浏览器的重绘,在PC浏览器上,渲染对性能影响不大,但因为配置原因,渲染对移动端性能的影响却非常大,错误的操作可能导致滚动迟钝、动画卡帧,大大降低用户体验。

      减少重绘、减少回流降低渲染带来的耗损基本人尽皆知了,但是引起重绘的操作何其多,每次重绘的操作又何其微观:

      ① 页面滚动

      ② javascript交互

      ③ 动画

      ④ 内容变化

      ⑤ 属性计算(求元素的高宽)

      ……

      与请求优化不同的是,一些请求是可以避免的,但是重绘基本是不可避免的,而如果一个页面卡了,这么多可能引起重绘的操作,如何定位到渲染瓶颈在何处,如何减少这种大消耗的性能影响是真正应该关心的问题。

      Chrome渲染分析工具

      1. Timeline/Performance工具

        timeline可以展示web应用加载过程中的资源消耗情况,包括处理DOM事件,页面布局渲染以及绘制元素,通过该工具基本可以找到页面存在的渲染问题。