首先是大佬登场介绍 AC 是每年一度的 Alloy Team 团队技术分享会,而前段时间 TFC 主要是邀请业界大牛的技术分享。AC 希望给开发者提供最好的参会体验,也希望现场的各位分享自己的故事。
插个开场舞图:
第一场:面向亿万级用户的 Web 同构直出
以兴趣部落为例讲解面向亿万用户的 Web 同构直出。
首先介绍了一些基本概念。
什么是直出?
以 Node 作为后端语言实现的服务端渲染页面并输出的技术。
什么是同构?
客户端与服务端可以共享部分代码
然后给出了两个二维码,让大家扫码体验哪个是直出前页面,哪个是直出后页面。
接下来主要分两部分内容继续议题,如何同构直出以及服务的高可用行。
如何改造直出
同构直出的三要素
- DOM 一致性
保持DOM一致性利用了 React 虚拟 DOM 的思想。服务端通过ReactDomServer.renderToString
拼装 HTML 字符串,返回给浏览器。浏览器端根据服务端返回的数据ReactDom.render
出真实 DOM。 - Data 一致性
保持数据一致性服务端通过http.request请求需要直出页面的数据,通过 store 保存数据,浏览器端通过Provider 中的 store 属性渲染服务器返回的数据。
遇到的问题:前端代码不能在服务端执行,浏览器使用 ajax,Node端使用 http.request 如何解决。
不能在服务端执行的前端代码通过打标签,使用构建工具处理。`_BROWSER_`; ... `_END_`;
- Route 一致性
前后端路由保持一致性,避免返回错误页面。
方案
通过直出框架机来实现。
- 首先是项目构建
- 接下来是 actions 提取。
整个框架机的工作流如下:
高可用性
开发调试
框架集本地开发调试通过使用命令行工具包 fireDragon
,执行以下命令就可以啦。
npm link // 建立全局链接
firedragon init //初始化路由配置
firedragon // 读取路由配置文件,启动服务
容灾
容灾采用两种方式,框架机进行柔性处理,以及接入层转发。
压测
通过 wetest.qq.com
平台监控各项应用数据了解承受能力,找出性能瓶颈。
灰度
采用灰度发布,逐步扩大直出页面访问用户从 10 拓展到 3亿,服务器从 1 台拓展到 111 台。
监控告警
服务器层面从 CPU 使用率,CPU 性能,内存占用,磁盘 IO,网络 IO 监控。
运行时数据从脚本错误,测试,PV/UV,直出服质量,后台接口质量和染色日志。
第二场:大型 Web 项目可用性提升零脚本错误的实战
零脚本错误实战主要从下面五个方面展开讲解。
如何发现代码出了问题
客户反馈?老板连环夺命 call ? 经历了这些思考采用更高效的方案。
基础监控体系组成
体系组成分为三步,监听->上报->数据收集系统。
- 监听
使用try-catch
,window-onerror
。 - 上报
发送ajax
请求或者直接使用img
。 - 数据收集系统
- 提供上报接口
- 存储上报数据
- 数据分析展示
错误信息分析与优化
上报发现遇到很多 script error
错误,是由浏览器的同源策略导致的。
如何解决呢?script
标签添加 crossorigin
属性,后端做 CORS 处理。
Web 安全与脚本错误
错误脚本分析基于 SourceMap
监控方案解决。
通过生成 SourceMap
文件维护源文件和处理后文件的映射关系,使用 VLQ
编码来存储映射。
或者使用开源的 sentry
。
CSP 内容安全策略
监控、上报白名单中的前端资源。
- 使用方式
HTML Meta
标签<meta http-equiv="Content-Security-Policy" content="script-src 'self'" >
HTTP Header
(响应头带上CSP
的指令) - 配置
使用上报(不拦截),拦截两种方式。
直接采用 https://
开发测试与脚本错误
推荐了两个插件,js-error-dialog
报错弹窗和prettyjs
代码格式化、高亮和错误展示。
第三场:如何构建后现代前端工程化开发体系
分享提问开发者开发的第一个网站为引导,引出前端工程化的议题,并且从开发环境、衔接和生产环境三个环节来讲述。
开发
开发工程化从三个主要环节进行,脚手架与命令行、组件化和接口联调。
- 脚手架与命令行
脚手架的搭建从5个要素考虑:快速部署与更新、团队约定、快速配置、页面性能、构建性能。
alloy team 基于以上几点要素开发了steamerjs
。即装即用的插件式机制方便项目快速搭建,只需要键入以下几条命令就好啦:npm i -g steamerjs npm i -g steamer-plugin-kit npm i -g steamer-react steamer kit
- 组件化
组件化推荐采用跨项目组件的开发方式,把通用组件发布到公网npm
或者npm
私服,方便跨项目的组件复用。
业内优秀的组件库如element
。 - 接口联调
推荐了一些工具和插件,postman
,easy-mock.com
,steamer-plugin-mock
。
开发环境与生产环境衔接
- 数据上报与错误监控
主要采用一些成熟的市场方案。统计推荐百度统计 or 腾讯统计,性能监控推荐wetest
, 日志监控推荐sentry.io
。 - 持续集成
开源项目可以使用github + travis-ci
,私有项目可以使用bitbucket + pipeline
orgithub + pipeline
。
代码规范推荐使用 IDE 提醒 +pre-Commit
检查。
测试环境部署- 多域名测试环境
对于纯Web站,不需要代理工具,测试便利。节省服务器。 - 单域名多测试环境
对于APP内嵌页面,可以方便测试。各测试环境独立,互不干扰。
- 多域名测试环境
生产环境
生产部署推荐使用腾讯云(此处有广告硬植入,哈哈~)
第四场:Service Worker 主题分享
首先介绍了什么是 Service Worker。
Service Worker 是浏览器后台运行 JS 处理网络请求和管理缓存相应的方法。Service Worker 提供了一个 Application Cache 的替代方案。
快速上手
最简单的 Service Worker 样例:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./sw.js')
}
// sw.js
self.onfetch = (e) => {
e.respondWith(new Response('Hello Service Worker!'))
}
基础知识
- 生命周期
首次加载会经历Installing
->Active
,出错的话会进入Error
。 - 更新机制
Service Worker 更新会经历Installing
->Waiting
->Active
,出错的话同样会进入Error
。
工程实践
-
兼容性
-
Service Worker 的 URL
千万不要打版本号!!!正确的做法是保持 SW URL 不变,且与主页在同一域名下。xxx.com/xxx/sw.js
-
Dev Tool
在 Chrome 调试工具network
选项中,Size
栏为from Service Worker
就是启用了Service Worker
加载的资源。 -
自动构建
业界比较成熟的是谷歌的 sw-precache。使用也很简单,一行命令搞定:sw-precache —config=sw-config.js // sw-config.js module.exports = { // 需要SW缓存的⽂文件,默认使⽤用缓存优先策略略 staticFileGlobs: [ 'dist/cdn/**', 'dist/webserver/**' ], // 前缀替换 stripPrefixMulti: { 'dist/cdn/': '//path/to/your/cdn/', 'dist/webserver/': '//path/to/your/webserver' }, // 输出路路径 swFile: '/dist/webserver/sw.js', // 动态内容的缓存策略略 runtimeCaching: [{ // 对于所有url中带有 '/api/' 的请求,优先⽹网络请求,若离线,则使⽤用之前的缓存 urlPattern: /\/api\//, handler: 'networkFirst' }] };
当然 sw-precache 也有一些缺陷,比如没有集成的 Runtime,不支持外部 CDN 资源。
考虑到这些缺陷,基于 sw-precache 做了一些改进解决这些缺点,命名为 create-sw。
- 业务接入
手机QQ-附近-颜值配对模块使用了该方案。约为 80% 的的安卓用户,因为安卓手机 QQ 内置腾讯浏览器采用 X5 内核,Service Worker API 支持率达到了 91%。采用 Service Worker 的有效率约为 50%。
为什么需要 Service Worker
- 资源换成
- 加载速度比 304 更快
- 离线能力
- 完全的缓存控制能力
- 渐进式增强,无痛迁移
最后还提到了 PWA 实践,有兴趣可以详细了解。
第五场:Javascript 与机器学习
首先简单描述了人工智能的大背景,人工智能时代背景下每个人都需要了解或学习人工智能。之后推荐了一个前端深度学习库 deeplearn.js
。
分享目标
- 掌握机器学习基本概念
机器学习是生成算法的算法。人工神经网络是目前最流行的机器学习方法,神经网络由大量的人工神经元联结进行计算。 - 掌握神经网络分类器
主要从线性分类、异或分类和数据分类几个方面讲述,并且现场运行了数据分类的 Demo。
- 掌握两种神经网络训练方法
- 遗传算法变异神经网络
- 反向传播矫正神经网络
- 掌握遗传算法+神经网络的案例
以 flappyBird 为例。通过随机生成一批种群 -> 执行设定的关卡程序 -> 待种群全部阵亡按照分数高地排序取前20% -> 对选出的20%以及由他们变异出的80%的种群进行下一轮关卡程序。
继续第二步执行关卡程序直到关卡测试终止。 - 掌握反向传播算法
反向传播是“误差反向传播”的简称,是一种与最优化方法(如梯度下降法)结合使用的,用来训练人工神经网络的常见方法。该方法计算对网络中所有权重计算损失函数的梯度。这个梯度会反馈给最优化方法,用来更新权值以最小化损失函数。反向传播要求有对每个输入值想得到的已知输出,来计算损失函数梯度。因此,它通常被认为是一种监督式学习方法。 - 掌握手写数字识别案例
通过机器学习提高手写文字识别率。
总结
- 任何可以使用 JS 写的,都会有 JS 写。
- webgl 用来训练神经网络是不错的选择
- AI 技能和数据库编程,网络编程一样会成为通用技能
- 量子计算无法遍历所有神经网络权重树,还是需要研究算法
- 机器学习在基础物理没有突破之前无法得到质的突破
- 毁灭人类的一定是人类或者自然灾害,而不是人工智能
第六场:高效 H5 动画设计与性能优化
分享主要以兴趣部落送礼页面的实践为例,分以下几个话题讲述:
常用动画方案
- GIF
缺点明显- 是一张图片资源
- 最多 256 种颜色
- 支持全透明,不支持半透明
- 不适用于”真彩色”-RGB
- 动画质量遇资源体积成正比
- APNG
缺点明显- 也是一张图片资源
- 非官方认可
- 第一帧是 PNG,后续是拓展块
- 支持度低
- Video
是一种不错的方案,不过带宽问题需要考虑。- 设置autoplay 属性自动播放
- 设置 loop 属性控制循环
- 视频长度很重要(12s-30s)
- 带宽是个问题
- SVG
- 矢量无失真
- 难以呈现复杂位图效果
- 复杂动画具有渲染问题
- Canvas
推荐,也是业界主流的方式。- 可编程画布
- 2D Context API
- 单个 Dom 元素,无状态
- WebGL
- JS
- 使用 JS 控制 DOM、CSS
- 自身维护时间流和动画速度
- CSS3
- 过渡动画(transition)
- 关键帧动画(keyframes)
- 渲染引擎会使用跳帧保证动画的流畅性
- 渲染引擎会停止或降低不可见元素动画的刷新频率
这么多方案选哪一种好呢?性能说话!可以使用 FPS 工具 stats.js 进行性能分析。
移动端屏幕适配
移动端的屏幕适配分为以下几种场景阐述:
- 背景
- 背景为纯色或渐变色,直接铺满
- 背景为单张大图,设置为 cover
- 背景为可重复性纹理,直接 repeat 就好
- 主体
- 主体区域默认 iphone6 基准尺寸
- 基于主体区定位的元素
- 默认屏幕居中缩放
- 采用 rem 保持页面完整性及好的用户体验
如何界定主体区域?
- 边缘元素
- 音乐图片、操作指引等主体无关元素
- 处于屏幕固定位置,基于屏幕定位
性能监控遇优化
需考虑内存消耗和帧率,推荐工具 stats.js 和 Chrome developTool。
-
使用 GPU 硬件加速
- 避免频繁重绘和重排
- 避免 width 和 height,使用 transform:scale(x)
- 避免 margin、top / left,使⽤用 transform: translate(x, y)
- 元素创建后,⽴立即设置 transform: translateZ(0) 或 translate3d(0,0,0)
- 元素会使⽤用独⽴立的 layer 参与渲染
-
图片压缩
- 图片压缩:tinypny tinypng.com/
- 图⽚片合并:tonytony.club/tool/dongdo…,可预览帧 动画
- TextureMerger
-
性能问题
性能的监控使用之前推荐的 stats.js 就好。分析发现 translate 的表现明显优于 background。
测试过程中发现动画有锯齿,卡顿明显,有可能是图片太大导致的。 -
性能调试 timeline
锯齿是如何产生的呢?- FPS 降低时,GPU 罢工
- 大图 -> 丢帧
- 大图烧显卡
-
帧动画图片性能
帧动画到底用不用合图?建议不要合图使用 HTTP2.0 即可。合图之后的雪碧图会有空白区域,一个动画大概 40 – 50 帧的图片,单张图片要 500 500 px,合并图后达到 4000px 3000px。 -
帧动画优化方案 – zip 压缩包
- 资源打包,减少请求数
- 避免单个⼤大图渲染瓶颈
- 前端解压使用jszip stuk.github.io/jszip/
- jszip解析出ArrayBuffer,base64 ? Blob
- URL.createObjectURL(blob)
使用zip 动画资源 CDN 部署,max-age和前端缓存加速。
-
帧动画优化方案 – indexedDB
-
硬件加速 will-change
- 提前通知浏览器元素哪些属性会发生动画
- 浏览器预优化
- 不能过多滥用
-
兼容性问题 CSS3 动画控制
- 使用 setTimeout 的 CSS3 动画结束后回调误差大
- CSS3 Animation提供了动画事件 animationStart & animationEnd
- 部分机器不支持
- 降级使用JavaScript实现精准控制
-
兼容性问题 FPS 控制
- setTimeout/setInterval。执行时不准确
- 使用 requestAnimationFrame
- 与浏览器刷新频率保持一致
- IOS 全部支持,Android 支持率约 89%
-
限制帧率 RAF
一般建议保证 60 FPS 的帧率。如果不限制帧率的时候,使用 RAF 自由发挥,但需要注意资源包体积。 -
兼容性问题 canvas Retina适配
250px 250px 的原图到 500px 500px 的画布上发现变模糊了,原因是设备像素比 window.devicePixelRatio 导致的。可以画在 500px * 500px 的 Canvas 上再 scale(0.5)。
性能评分
导致性能问题的原因可能是机器性能低,内存紧张,帧率低。
性能评分的原理是页面创建一定数量的DOM,并添加 transform 和 opacity 变化。根据帧率衡量机器性能。
- 性能评分方法
首先在页面创建 200 个正方形 DIV 元素。
每个 DIV 宽度和高度均为 100px,DIV 初始位置的中心点与页面的中心点重合。
设置时间 t1 和 t2,在每一帧周期内对页面中每个 DIV 进行随机位移、缩放和透明度变换。
开始时间 t1,结束时间 t2,帧数为 nfps = 1000 * n/t
取帧率的10倍为性能评分
“` score = floor( 10000 * n / t)
分级
- 提高性能措施
- 减少帧数(图片数)
- 减少装饰及动画复杂度
- 取消特效
- 使用
@1x
图片
自动化与可配置性
产品频繁新增/更换礼物,如果每次更换都修改代码无疑是不可取的。因此需要把动画效果改为可配置,定义统一配置文件,动画资源由 packageID 唯一标识,礼物配置与动画资源分离。
- “常规操作”
- 礼物 “面板” 懒加载
- 礼物 “配置” 预加载
- 礼物面板 “图片” 预加载
- 面板呼起时送礼 “动画资源” 预加载
- 送礼 “动画资源” 缓存 indexDB
课程资源
第七场:在 ES7 时代下的异步处理机制
Javascript 语言的执行环境是单线程的。如果一个任务耗时很长,就会阻塞后面的任务,导致页面无响应。于是,Javascript 将任务的执行模式分为同步和异步。
原生 Javascript 解决异步的方式
- 回调函数
回调函数优点和缺点都很明显。
优点是简单、容易理解和部署。
缺点是不利于代码的阅读和维护、高度耦合、流程混乱,而且每个任务只能指定一个回调函数。 - 事件监听
与回调不同。添加事件监听,在异步函数触发监听事件处理逻辑。 - 发布/订阅
发布/订阅与“事件监听”,类似,但优于后者。可以监控程序运行,并且实现多任务绑定。
通过 jQuery 解决异步方式
通过jQuery when
方法同样可以实现类似于 Promise
对象的功能。并且通过 when
可以使得多个异步并行请求,然后获取返回值进行回调处理
通过 done
或者 then
两种方式进行回调。
通过 Promise 解决异步方式
promise的功能是可以将复杂的异步处理轻松地进行模式化。
接着简单介绍了 promise
的 API,就不再详细讲述了:
- then(onResolve, onReject)
- catch(onReject)
- resolve(callback)
- reject(callback)
- all(Array)
- race(Array)
同步调用和异步调用同时存在导致的混乱
Promise只能进行异步调用方式。
理论上,在promise.then 执行的时候promise对象已经是确定状态,从程序上说对回调函数进行同步调用也是行得通的。
Promise也会以异步的方式调用该回调函数,这是在Promise设计上的规定方针。
当需求变得复杂后,多层嵌套和链式调用,也让代码看起来不那么优雅。
ES7下异步处理的终极解决方案
通过 async/await 解决异步方式有以下几个有优点:
- 简约而干净
- 同、异步混合错误处理
- 条件判别
- 轻松获取中间值
- 错误堆栈信息
- 调试便捷
async/await 基本规则:
- async表示这是一个async函数,await只能用在这个函数里面。
- await 表示在这里等待promise返回结果了,再继续执行。
- await 后面跟着的应该是一个promise对象。
- await等待的虽然是promise对象,但不必写.then(),直接可以得到返回值。
之后是下午甜点:
第八场:ES2017时代的后函数式编程
首先以一个 Demo 为例判断是否为函数式编程。
function f(h){
return h + 1;
}
var x = 3;
f(x + 1);
理解函数式编程意味着:
- 有能力阅读开源代码
- 开拓新的思维方式
- 编写整齐有序的代码
通过点击计数任务不同的写法来讲述函数式编程的特点。代码传送门:
- 普通实现 jsfiddle.net/jpwqt93n/
- 函数式 jsfiddle.net/sjy64zfk/
- CycleJs widdersh.in/tricycle/
什么是函数式编程
函数式编程是种编程范式,它将电脑运算视为函数的计算,关注纯逻辑与数学运算。
函数式编程特点
- 声明式与命令式
- 流式,更适合人的阅读
函数式编程基石 —— 纯函数
纯函数只有逻辑运算和数学运算,同一个输入总得到同一个输出。纯函数的优点是可缓存、可测试、可并行(web worker),可进行惰性计算。
- 变量缓存
var memoize = function(f) { var cache = {}; return function() { var arg_str = JSON.stringify(arguments); cache[arg_str] = cache[arg_str] || f.apply(f, arguments); return cache[arg_str]; }; };
- 副作用
- 往数据库插入记录
- 发送一个 http 请求
- 可变数据
- 打印/log
- 获取用户输入
- DOM 查询
- 访问系统状态等
这些函数执行并不能总是返回相同的结果,可以通过延迟执行避免产生。
函数的变换和操作
- 柯里化
通过柯里化将低阶函数转换为高阶函数,可以形象地比喻成吃豆豆的过程。 - Compose
从右至左依次执行。let f = x => x + 1; let g = x => x * 2; g(f(1)) compose(g, f)(1)
- Functor
functor 是实现了 map 函数并遵守一些特定规则的容器类。通过调用Container.of
把东西装进容器中隔绝外部影响,通过 Map 来接触、操作窗口内的值,获得包含新值的容器。var Container = function(x) { this._value = x; } Container.of = function(x) { return new Container(x); } Container.of(3) // => Container(3) Container.prototype.map = function(f){ return Container.of(f(this._value)) } Container.of('flamethrowers').map(function(s) { return s.toUpperCase() } // => Container('FLAMETHROWERS')
- Monad
实现了 chain 的 Functor。
chain( flatMap )
使用Map执行后(可能会加容器/卷)剥离一次容器/卷,不会产生新的卷。
流式特点
上个函数输出是下个函数函数输入。
流式框架有 xtream 和 RxJS。
实战
- Redux Middleware 源码
- CycleJS 代码解读
最后附上参考资料
- JS函数式编程指南
- www.gitbook.com/book/llh911…
- Swift Functors, Applicatives 和 Monads 的图文解释
- github.com/nathanwhy/w…
- Redux
- RxJs
- CycleJS
第九场:如何把自己构建成大型互联网公司需要的前端人才
老教授首先抛出一个经典问题,“如果你是一个大学毕业生,你会选择大型互联网公司还是创业公司?”。
这个问题从来没有标准的答案,并且现场的回答者就很坚定的选择小公司,而老教授的建议是选择大公司。
大公司有什么好?
- 丰富的学习资源
- 活跃的技术交流氛围
- 专注做前端深入研究
合格面试官需要具备完整前端知识体系,抓住重点辨别人才。
关于前端校招的考察内容可以查看老教授的这篇文章《前端校招面试该考察什么?》
社招与校招的区别
校招面试流程
前端基础
- HTML
- 常用的 meta 头
- 语义化
- HTML5 新增功能
- HTML 渲染解析知识
- CSS
- 可读规范的 CSS 代码
- 盒模型
- CSS3 特性:动画、弹性布局等
- JS
- 事件模型
- 闭包和内存泄漏
- 原型链
- 渲染树、重排重绘、分层渲染等(进阶)
- HTTP
- 常见 HTTP 状态码
- 不同请求类型的区别
- 如何缓存
- HTTP2
- 调试
- 如何抓包
- 如何 debug 程序问题
- 如何做移动端调试
- 如何发现页面问题
- 移动 Web 开发
- 移动 Web 开发和 PC Web开发的区别
- 响应式布局
- 移动端的手势和事件
- 怎么提高移动页面的渲染性能
以及一些综合知识考察,比如:用户从输入 url 到最终页面展示,这个过程中发生了什么?老板反馈页面打开白屏,而你手机是正常的,怎么办?页面卡顿,怎么优化?
校招前端专业知识是考察重点吗?
如果你连前端基础知识都没掌握好,我怎么相信你是热爱前端的学习者?
项目经历
一个字,怼!找出项目经历的关键词,然后由浅入深,一直问到答不上来为止。暗中观察团队协作意识、攻克难题决心、搜索资料能力等。
大学阶段该做什么积累?
- 补齐学好前端基础
- 跟进新技术,尝试新语言
- 实践项目中吃透用到的技术项
怎么用大公司标准要求自己、提升自己?
- 技术准备
- 补齐基础知识
- 单点深挖
大公司推崇一专多长大学的时候以广度为主,拓展视野; 工作之后以深度为主,单点深挖; 当达到瓶颈后,再次向广度拓展,打通知识。 ————百度某总监
- 以技术项目练兵
从业务优化出发,以好玩有趣为主,挖掘技术项目。 - 写文、分享
- 思想准备
- 沟通能力
用沟通代替自作主张
多做反馈,主动反馈
有风险及时抛出 - 正式资源不足
“如果什么都准备好了,谁都能做,那要你干嘛?” - 问题到我为止
- 培养高效工作方法
- 沟通能力
跳槽社招
-
基础知识
基础知识相比社招有更高的要求。 -
项目经验
项目经验需对比腾讯的高级前端工程师要求。
最后,乐观自信和技术能力一样重要!
到这里本次 AC 大会的现场实录就更新完了,一整天 9 场的技术分享加圆桌讨论,议题也是从项目搭建、优化、监控到编程思想、前沿科技以及职业发展涵盖各个方面,真的是干到不能再干的大会了。
一天很短,内容很长,希望对大家有所帮助,未来几天慢慢消化,接下来也可以多多交流。
今天的文章Alloyteam Conf 2017 现场实录分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/20318.html