前端工程化
前端架构§
- SSR、SPA、双向绑定、懒加载、MVVM:Proxy 与 object.defineProperty
MV* 设计模式与框架?§
- MV* 框架
- MVC:模型、视图、控制器
- MVP:模型、视图、表示器
- MVVM:模型、视图、视图模型
- 为什么要使用 MV* 框架:关注点分离、简化日常任务、提升生产率、标准化、更高效的合作、独立代码更容易更改、更干净的单元测试。
- MVVM:它萌芽于2005年微软推出的基于 Windows 的用户界面框架 WPF ,前端最早的 MVVM 框架 knockout 在2010年发布。
- 分层:
- Model 层:对应数据层的域模型,它主要做域模型的同步。通过 Ajax/fetch 等 API 完成客户端和服务端业务 Model 的同 步。在层间关系里,它主要用于抽象出 ViewModel 中视图的 Model。
- View 层:为视图模板存在,在 MVVM 里,整个 View 是一个动态模板。除了定义结构、布局外,它展示的是 ViewModel 层的数据和状态。View 层不负责处理状态,View 层做的是 数据绑定的声明、 指令的声明、 事件绑定的声 明。
- ViewModel 层:把 View 需要的层数据暴露,并对 View 层的 数据绑定声明、 指令声明、 事件绑定声明负责,也就是处理 View 层的具体业务逻辑。ViewModel 底层会做好绑定属性的监听。当 ViewModel 中数据变化,View 层会得到更 新;而当 View 中声明了数据的双向绑定(通常是表单元素),框架也会监听 View 层(表单)值的变化。一旦值变 化,View 层绑定的 ViewModel 中的数据也会得到自动更新。
- 优点:
- 分离视图(View)和模型(Model),降低代码耦合,提高视图或者逻辑的重用性: 比如视图(View)可以独立于 Model变化和修改,一个ViewModel可以绑定不同的"View"上,当View变化的时候Model不可以不变,当Model变化 的时候View也可以不变。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑
- 提高可测试性: ViewModel的存在可以帮助开发者更好地编写测试代码
- 自动更新dom: 利用双向绑定,数据更新后视图自动更新,让开发者从繁琐的手动dom中解放
- 缺点:
- Bug很难被调试: 因为使用双向绑定的模式,当你看到界面异常了,有可能是你View的代码有Bug,也可能是Model 的代码有问题。数据绑定使得一个位置的Bug被快速传递到别的位置,要定位原始出问题的地方就变得不那么容易 了。另外,数据绑定的声明是指令式地写在View的模版当中的,这些内容是没办法去打断点debug的
- 一个大的模块中model也会很大,虽然使用方便了也很容易保证了数据的一致性,当时⻓期持有,不释放内存就造 成了花费更多的内存
- 对于大型的图形应用程序,视图状态较多,ViewModel的构建和维护的成本都会比较高
- 分层:
不同场景下前端集成的解决方案有什么思路?§
前端如何实现即时通信?§
- 短轮询:每隔一段时间客户端就发出一个请求,去获取服务器最新的数据,一定程度上模拟实现了及时通信。
- 优点:兼容性强,实现非常简单。
- 缺点:延迟性高,非常消耗请求资源,影响性能。
- Comet:
- 基于 AJAX 的长轮询:
- 优点:兼容性好,资源浪费较小。
- 缺点:服务器 hold 连接会消耗资源,返回数据顺序无保证,难于管理维护。
- 基于 iframe 及 htmlfile 的流方式(streaming)
- 基于 AJAX 的长轮询:
- SSE(Server-Sent Event),服务端推送事件:
- 优点:基于 HTTP 而生,因此不需要太多改造就能使用,使用方便
- 缺点:基于文本传输效率没有 WebSocket 高,不是严格的双向通信,客户端向服务端发送请求无法复用之前的连接,需要重新发出独立的请求。
- WebSocket:全新、独立的协议,基于 TCP 协议,与 HTTP 协议兼容,却不会融入 HTTP 协议,仅仅作为 HTML5 的一部分,其作用就是在服务器和客户端之间建立实时的双向通信。
- 优点:真正意义上的双向通信,性能好、延迟低
- 缺点:独立于 HTTP 协议,因此需要额外的项目改造,使用复杂度高,必须引入成熟的库,无法兼容低版本浏览器。
- Web Worker:为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运。
- Service Worker:本质上充当Web应用程序与浏览器之间的代理服务器,也可以在网络可用时作为浏览器和网络间的代理,创建有效的离线体验。
如何理解前端微服务?§
前端性能优化§
- 图片懒加载?
- 给页面注入50万个li怎么做提升性能?
- Base64
网页很卡的原因
- 带宽不足、硬件配置低、CPU 或者是内存被占满。
- HTTP 请求次数太多。
- 接收数据时间过长,如下载资源过大。
- JS 脚本过大,阻塞了页面的加载。
- 网页资源过多、接受数据时间长、加载某个资源慢。
- DNS 解析速度。
性能优化的方法
- 资源压缩、文件合并
- 非核心代码异步加载(script 标签的 defer 和 async 属性)
- 资源预加载:预解析DNS
前端部署§
- 如何保证打包文件替换过程中,用户体验不断
- 前端的多集群分布式部署?
前端 + 浏览器安全性§
- Xss csrf
移动端开发§
- React Native、Flutter
SPA 单页面应用有什么特点?§
“网络应用”相较于“网站”,具有高度的交互性和动态性,允许用户执行操作并接收他们的操作响应。
- 在过去,浏览器从服务器接收 HTML 并渲染。当用户导航到其它 URL 时,需要整页刷新,服务器会为新页面发送新的 HTML,这被称为服务器端渲染。
- 在现代的 SPA 中,客户端渲染取而代之,浏览器从服务器加载初始页面,以及整个应用程序所需的脚本(框架、库、应用代码)和样式表。当用户导航到其他页面时,不会触发页面刷新。该页面的 URL 通过 HTML5 History API 进行更新。浏览器通过 AJAX 请求向服务器检索新页面所需的数据(通常 JSON 格式)
- SPA 带来了:
- 应用的表现层从服务器端脱离出来,在浏览器管理
- 提升应用设计、代码维护和开发时间等方面的效率
- 服务端的事务处理仅限于数据
- 解决整页刷新、请求重复、重负荷事物处理等问题
- 嵌入脚本
-
好处:
- 用户感知响应快,用户切换页面时,不再看到因页面刷新而导致的白屏。
- 对服务器进行的 HTTP 请求减少,因为对于每个页面加载,不必再次下载相同的资源。
- 客户端和服务器之间的关注点分离。可以为不同平台(手机、聊天机器人、智能手表)建立新的客户端,而无需修改服务器代码。只要 API 没有修改,可以单独修改客户端和服务器上的代码。
-
缺点:
- 由于加载了多个页面所需的框架、应用和资源,导致初始页面加载时间较长。
- 服务器还需要进行额外的工作,需要将所有请求路由配置到单个入口点,然后由客户端接管路由。
- SPA 依赖于 JavaScript 来呈现内容,但并非所有搜索引擎都在抓取过程中执行 JavaScript,他们可能会在你的页面上看到空的内容。这无意中损害了应用的搜索引擎优化(SEO)。然而,当你构建应用时,大多情况下,搜索引擎优化并不是最重要的因素,因为并非所有内容都需要通过搜索引擎进行索引。为了解决这个问题,可以在服务器端渲染你的应用,或者使用诸如 Prerender 的服务来“在浏览器中呈现你的 JavaScript,保存静态 HTML,将其返回给爬虫”
-
SPA 技术要点:
- 组织项目(文件结构)
- 创建可维护的松耦合 UI
- 使用 JavaScript 模块
- 执行 SPA 导航:SPA 布局 = Shell 页面 + Region 容器
- 创建视图组成与布局
- 模块通信:pub/sub 设计模式
- 与服务器通信
- 执行单元测试
- 客户端自动化技术
-
SPA 模型
- 隐式模型:v-model、v-bind
- 显式模型:Backbone.js
- 模型的绑定
- 用来自由混入模板的 HTML 代码
- 绑定类型
- 属性:ng-bind、v-bind
- 表达式:{{ aaa }}、<%= aaa %>
- 定向绑定
- 单向绑定:ng-bind、v-bind
- 单次绑定:渲染期间只发生一次
- 双向绑定,与 UI 控件关联,采用观察者模式,需要付出开销代价:ng-model、v-model
-
SPA 模板
- 模板引擎:在 MV* 中将模板和模型数据结合起来
- 模板:HTML 片段——可额外包含多种绑定及其他指令
- 模板渲染
- 模板存放位置
- 内嵌模板:SPA 初始下载,type="text/template"
- 局部模板:按需下载
- SPA 模块:模块模式、模块化编程等
SPA 路由的原理?§
- 客户端路由器
- 侦测浏览器位置发生的变化,监听特定事件
- 管理 SPA 视图、数据以及业务事物状态
- 浏览器导航控制
- 路由术语
- 名称:路由标识
- 动词:get、put、on、when
- 路径:URL 部分,建立路由/路由处理程序之间的链接
- 功能:可能执行的相关代码(控制器、回调函数)
- 路由配置
- 路由语法
- 路由配置项:当路由找到匹配 URL 时,该如何动作
- 路由参数:在路由路径中定义的变量
- 缺省路由
- 客户端路由器的工作机制
- 片段标识符方式,# 为前缀,使用 location 的 onhashchange 时间
- HTML 历史 API 方式,兼容性差,使用片段标识符作为回退方案
- pushState、replaceState、pospstate
- 三个参数:状态对象、标题、URL
- 基准链接:服务器端调整(重定向)、移除 hash
虚拟 DOM 的原理是什么?§
近年来,前端的框架主要发展方向就是解放DOM操作的复杂性。虚拟的 DOM 的核心思想是:对复杂的文档 DOM 结构,提供一种方便的工具,进行最小化地 DOM 操作。
- 算法实现
- 用 JS 对象模拟 DOM 树
- 比较两棵虚拟 DOM 树的差异
- 把差异应用到真正的 DOM 树上
- DOM patching,DOM 修补
- DOM diff
前端性能优化需要注意什么?§
火焰图?
- 最大限度地减少 HTTP 请求:
- 使用内容分发网络
- headers 添加一个 Expires 或Cache-Control 头
- 用 gzip 的压缩内容
- 将样式表在顶部
- JS 代码放在底部
- 避免使用 CSS 表达式
- JavaScript 和 CSS 放在外部
- 减少 DNS 查找
- 缩小 JavaScript 和 CSS
- 避免重定向
- 删除重复的脚本和样式
- 减少 DOM 元素的数量
- CSS 雪碧图
- HTTP 缓存
- 尽量避免回流
- 复合层、简单层与硬件加速
- 工程化打包
- 复合层与性能优化
静态资源域名拆分(HTTP 2.0 不需要)
- 将静态资源分组,分别放到不同的域名下(如static.base.com)
- 而 page.base.com(页面所在域名)下请求时,是不会带上 static.base.com 域名的 cookie 的,所以就避免了浪费
- 在移动端,如果请求的域名数过多,会降低请求速度(因为域名整套解析流程是很耗费时间的,而且移动端一般带宽都比不上pc),此时就需要用到一种优化方案:dns-prefetch(让浏览器空闲时提前解析dns域名,不过也请合理使用,勿滥用)
前端项目如何部署到 CDN 上?§
常见的终端维护前端项目状态的命令都有哪些。§
- 查看端口占用
- 查看进程状态
- 查看 host、nginx 状态
前端都可以怎么压缩?§
GZip 压缩
- 是一种压缩格式,需要浏览器支持才有效(不过一般现在浏览器都支持), 而且 GZip 压缩效率很好(高达70%左右)
- 然后 GZip 一般是由 Apache、Tomcat 等 Web 服务器开启
- 服务器除了 GZip 外,也还会有其它压缩格式(如 deflate,没有 gzip 高效,且不流行)
- 一般只需要在服务器上开启了 GZip 压缩,然后之后的请求就都是基于 GZip 压缩格式的, 非常方便。