Blog icon indicating copy to clipboard operation
Blog copied to clipboard

记录成长的过程

Results 54 Blog issues
Sort by recently updated
recently updated
newest added

# 【经济学+前端技术】双视角分析 - 哪些技术值得投入学习 我相信这是每一个前端从业者都关心的一个问题,特别是在今天,前端技术发展如此迅猛,各种框架、工具百花齐放,如何在有限的时间里去学习值得投入的技术是非常关键的一件事。 ## 透过现象看本质 回归到一个最本质的问题:什么决定了员工的工资?为什么程序员的工资比其他岗位高? > 如果您想问“哪些技术值得投入”和“是什么决定了员工的工资”之间的联系,这里简单推导一下:学习技术是为了什么?-> 找一份好工作 -> 找一份好工作是为了什么? -> 赚更多的工资 -> 是什么决定了工资的高低? > > 这里排除因为兴趣学技术的情况,因为兴趣学技术,不存在“值不值得”的问题。 在经济学领域有一个概念叫做 **“生产要素”** 是用于生产物品与服务的“投入”。当一家互联网企业生产科技服务时,它要利用程序员的时间(劳动),劳动是一种“生产要素”。生产要素的“需求”是派生需求,也就是说,企业的生产要素需求是从它向另一个市场供给物品或服务的决策所派生出来的。因此,对前端程序员的需求与企业对互联网服务的供给有不可分割的联系。 与经济中的其他市场一样,劳动市场也是由供需力量支配的,企业决定劳动的需求量是根据利润决定的,企业追求利润最大化,因此它并不直接关心雇佣的员工数量和它生产的产品和服务量。它只关心利润,利润等于生产服务带来的总收益减去生产这些服务的总成本。企业的产品服务量和员工需求都生产与“利润最大化”这个首要目标。 另一个概念是 **“劳动的边际产量”**,即增加一单位劳动所引起的产量增加量,在现实的生产过程表现出 **“边际产量递减”** 的效果,即一单位投入的边际产量随着投入量增加而减少的性质。 > 边际产量递减:一个程序员带来的产量假设为100,那么两个程序员可能是...

总结与思考

# 时间切片(Time Slicing) 上周我在FDConf的分享[《让你的网页更丝滑》](https://ppt.baomitu.com/d/b267a4a3)中提到了“时间切片”,由于时间关系当时并没有对时间切片展开更细致的讨论。所以回来后就想着补一篇文章针对“时间切片”展开详细的讨论。 从用户的输入,再到显示器在视觉上给用户的输出,这一过程如果超过100ms,那么用户会察觉到网页的卡顿,所以为了解决这个问题,每个任务不能超过50ms,W3C性能工作组在LongTask规范中也将超过50ms的任务定义为长任务。 > 关于这50毫秒我在FDConf的分享中进行了很详细的讲解,没有听到的小伙伴也不用着急,后续我会针对这次分享的内容补一篇文章。 > > 在线PPT地址:https://ppt.baomitu.com/d/b267a4a3 所以为了避免长任务,一种方案是使用Web Worker,将长任务放在Worker线程中执行,缺点是无法访问DOM,而另一种方案是使用时间切片。 ## 什么是时间切片 时间切片的核心思想是:如果任务不能在50毫秒内执行完,那么为了不阻塞主线程,这个任务应该**让出主线程的控制权**,使浏览器可以处理其他任务。让出控制权意味着停止执行当前任务,让浏览器去执行其他任务,随后再回来继续执行没有执行完的任务。 所以时间切片的目的是不阻塞主线程,而实现目的的技术手段是将一个长任务拆分成很多个不超过50ms的小任务分散在宏任务队列中执行。 ![LongTask](https://p.ssl.qhimg.com/t018f4a9c8003da97fd.png) 上图可以看到主线程中有一个长任务,这个任务会阻塞主线程。使用时间切片将它切割成很多个小任务后,如下图所示。 ![task](https://p.ssl.qhimg.com/t0165469668d61c85f6.png) 可以看到现在的主线程有很多密密麻麻的小任务,我们将它放大后如下图所示。 ![task2](https://p.ssl.qhimg.com/t013d48124638650087.png) 可以看到每个小任务中间是有空隙的,代表着任务执行了一小段时间后,将让出主线程的控制权,让浏览器执行其他的任务。 > 使用时间切片的缺点是,任务运行的总时间变长了,这是因为它每处理完一个小任务后,主线程会空闲出来,并且在下一个小任务开始处理之前有一小段延迟。 > > 但是为了避免卡死浏览器,这种取舍是很有必要的。 ## 如何使用时间切片 时间切片是一种概念,也可以理解为一种技术方案,它不是某个API的名字,也不是某个工具的名字。...

performance

# Vue 项目架构设计与工程化实践 > 转载文章请注明出处,谢谢 https://github.com/berwin/Blog/issues/14 文中会讲述我从0~1搭建一个前后端分离的vue项目详细过程 Feature: * 一套很实用的架构设计 * 通过 cli 工具生成新项目 * 通过 cli 工具初始化配置文件 * 编译源码与自动上传CDN * Mock 数据 * 反向检测server api接口是否符合预期 前段时间我们导航在开发一款新的产品,名叫 [快言](http://k.hao.360.cn/t/%E6%AF%92%E9%B8%A1%E6%B1%A4),是一个主题词社区,具体这个产品是干什么的就不展开讲了,有兴趣的小伙伴可以点进去玩一玩~ 这个项目的1.0乞丐版上线后,需要一个管理系统来管理这个产品,这个时候我手里快言项目的功能已经上线,暂时没有其他需要开发的功能,所以我跑去找我老大把后台这个项目给拿下了。 ##...

javascript
vue.js
工程化

# Vue.js 模板解析器原理 > 本文来自[《深入浅出Vue.js》](https://item.jd.com/12573168.html)模板编译原理篇的第九章,主要讲述了如何将模板解析成AST,这一章的内容是全书最复杂且烧脑的章节。本文未经排版,真实纸质书的排版会更加精致。 通过第8章的学习,我们知道解析器在整个模板编译中的位置。我们只有将模板解析成AST后,才能基于AST做优化或者生成代码字符串,那么解析器是如何将模板解析成AST的呢? 本章中,我们将详细介绍解析器内部的运行原理。 ## 9.1 解析器的作用 解析器要实现的功能是将模板解析成AST。 例如: ```html {{name}} ``` 上面的代码是一个比较简单的模板,它转换成AST后的样子如下: ```javascript { tag: "div" type: 1, staticRoot: false, static: false, plain: true, parent: undefined,...

vue.js

# 为什么Vue使用异步更新队列? ![image](https://user-images.githubusercontent.com/3739368/38133744-1459be04-3443-11e8-8bec-414b8a7e068c.png) > 本文假设你已经对Vue的变化侦测和渲染机制有一些了解。 > 如果不了解请移步[《深入浅出 - vue变化侦测原理》](https://github.com/berwin/Blog/issues/17)、[《PPT:深入浅出Vue.js - VirtualDOM篇》](https://ppt.baomitu.com/display?slide_id=2afbd5b9) 异步更新队列指的是当状态发生变化时,Vue异步执行DOM更新。 我们在项目开发中会遇到这样一种场景:当我们将状态改变之后想获取更新后的DOM,往往我们获取到的DOM是更新前的旧DOM,我们需要使用`vm.$nextTick`方法异步获取DOM,例如: ```javascript Vue.component('example', { template: '{{ message }}', data: function () { return { message: '没有更新' } },...

javascript
vue.js
总结与思考

# 2016年终总结 今天是16年12月30号,后天就是2017年了,一直拖到现在,趁着今天工作不是太忙,也是时候给自己做一个2016年的总结了。 ## 关于技术 ### Koa 由于我们组准备使用nodejs进行前后端分离,所以2016年最开始我的精力主要放在了研究Koa上面,仔细研究过Koa的每一行源码以及Koa使用到的依赖(co、koa-compose等),对Koa的实现及原理进行了非常深入的理解,对Koa深入了解后我又研究了Koa2的源码,深入了解他们的不同及各自的特点,总结来说,Koa2和Koa各有优缺点吧 研究完Koa还是不够的,在实际项目使用中会用到非常多的第三方模块,所以我就把项目中常用的模块的源码也看了一遍(包括但不限于 koa-router,koa-bodyparser,koa-etag,koa-error,koa-session,egg-logger 等等),主要就是想明白他们的工作原理,并确定他们的安全性,毕竟对于server端我还是想尽可能的知道每一行代码是如何工作的,这样可以避免出现一些问题,即便真出了问题我也可以清晰的明白为什么会出现问题,而使用最短的时间解决它。 关于Koa我写了两篇文章,我自认为是目前国内关于Koa最火,最好的两篇文章,没有之一 [深入浅出 Koa](https://github.com/berwin/Blog/issues/8) [深入浅出 Koa2](https://github.com/berwin/Blog/issues/9) ### Promise 其实异步解决方案无论是co还是async都是基于Promise的,所以Promise已经是一个必备技能,所以我就花了一点时间把Promise好好研究了一下,并进行了一个分享 [我分享的关于Promise的ppt](http://berwin.github.io/ppts/promise/) 后来关于Promise我遇到一个坑,其实这个问题也挺有意思的,后来找到了答案,下面是我在cnodejs上的提问 [《关于promise的一个很奇怪的问题》](https://cnodejs.org/topic/5809847b27a1d99178a9904d) ### ES6 ES6也已经是一项必备技能了,所以我系统的学习了一下ES6,我精读了一遍阮一峰的《ECMAScript6入门》,后来我又跟着我们组内的小伙伴一起精读了原版的 《understanding ECMAScript6》每周4大家会来总结每章的内容和一些使用经验与存在哪些天坑 ### Vue 我们组前后端分离技术选型选择的是...

Blog
Me
总结与思考

# 关键渲染路径 通常我们只需要编写HTML,CSS,JavaScript屏幕上就会显示出漂亮的页面,但浏览器是如何使用我们的代码在屏幕上渲染像素的呢? 浏览器将HTML,CSS,JavaScript转换为屏幕上所呈现的实际像素,这期间所经历的一系列步骤,叫做关键渲染路径(Critical Rendering Path)。 ![关键渲染路径](https://s3.ssl.qhres.com/static/24ffa9da95444a99.svg) 图1-1 关键渲染路径的具体步骤 图1-1给出了关键渲染路径的具体步骤。如图所示,首先,浏览器获取HTML并开始构建DOM(文档对象模型 - Document Object Model)。然后获取CSS并构建CSSOM(CSS对象模型 - CSS Object Model)。然后将DOM与CSSOM结合,创建渲染树(Render Tree)。然后找到所有内容都处于网页的哪个位置,也就是布局(Layout)这一步。最后,浏览器开始在屏幕上绘制像素。 正常情况下浏览器会以上面我们描述的步骤进行渲染,但有一个特殊情况是在构建DOM时遇见了JavaScript,这时情况就会变得不太一样。JavaScript会影响渲染的流程,所以它是性能领域很重要的部分,这个特殊情况我们后面再详细讨论,我们先讨论如何构建DOM和CSSOM。 ## 1. 构建DOM 浏览器会遵守一套定义完善的步骤来处理HTML并构建DOM。宏观上,可以分为几个步骤。如图1-2所示。 ![构建DOM的具体步骤](https://s4.ssl.qhres.com/static/88365d78f80f69ca.svg) 图1-2 构建DOM的具体步骤 第一步(转换):浏览器从磁盘或网络读取HTML的原始字节,并根据文件的指定编码(例如 UTF-8)将它们转换成字符,如图1-3所示。 ![将字节码转换成字符](https://s4.ssl.qhres.com/static/f39ac8ff6c4ca6bd.svg)...

performance

# Web性能领域常见的专业术语 测量与排查网页的性能瓶颈,是一名专业Web性能优化者的基本功。本章将详细介绍Web性能领域的一些专业术语,通过这些术语也可以侧面了解是哪些因素在影响加载性能。 ## 背景 衡量网页的性能是一个比较琐碎的事情,因为没有某一个指标或数字可以直接告诉我们网页的性能怎样,因为加载网页不是一瞬间的事,准确地说,它是一个过程,不存在某个单独的 **“时间点”** 可以完全体现出网页的性能,因为在网页加载的过程中,有很多个比较关键的 **“时间点”** 可以影响用户的感觉(感觉我们的网页是 **“快”** 还是 **“慢”**)。而且不同类型的产品所侧重的点也都不太一样,可能同一个时间点,对于某些产品至关重要,但对于另外一些产品,则完全不care。 以`https://www.google.com.hk`为例,下图是使用Lighthouse(一个性能测评工具)捕获出的测评结果报告。 ![图1 - Lighthouse报告](http://berwin.github.io/articles/Web%E6%80%A7%E8%83%BD%E9%A2%86%E5%9F%9F%E7%9A%84%E4%B8%93%E4%B8%9A%E6%9C%AF%E8%AF%AD/Lighthouse.png) 下图是使用Chrome浏览器的DevTools捕获出的加载性能结果报告。 ![图2 - Chrome DevTools 报告](http://berwin.github.io/articles/Web%E6%80%A7%E8%83%BD%E9%A2%86%E5%9F%9F%E7%9A%84%E4%B8%93%E4%B8%9A%E6%9C%AF%E8%AF%AD/Devtools.png) 从上面这两张性能测评报告中,我们会发现报告通常会给出很多个 **“关键时间点”** 来表示性能数据,单独的某个“时间点”无法体现出网页的性能,只有将它们与自身的产品类型相结合,综合评估,才能判断出网页的性能到底怎样。而我们要做的,就是读懂报告中的各种专业术语,并分辨出哪些因素影响了网页的加载性能。 ## 术语 ### FP、FCP、FMP与LCP...

performance

# 深入浅出 - vue变化侦测原理 其实在一年前我已经写过一篇关于 [vue响应式原理的文章](https://github.com/berwin/Blog/issues/11),但是最近我翻开看看发现讲的内容和我现在心里想的有些不太一样,所以我打算重新写一篇更通俗易懂的文章。 我的目标是能让读者读完我写的文章能学到知识,有一部分文章标题都以深入浅出开头,目的是把一个复杂的东西排除掉干扰学习的因素后剩下的核心原理通过很简单的描述来让读者学习到知识。 关于vue的内部原理其实有很多个重要的部分,变化侦测,模板编译,virtualDOM,整体运行流程等。 今天主要把变化侦测这部分单独拿出来讲一讲。 ## 如何侦测变化? 关于变化侦测首先要问一个问题,在 js 中,如何侦测一个对象的变化,其实这个问题还是比较简单的,学过js的都能知道,js中有两种方法可以侦测到变化,`Object.defineProperty` 和 ES6 的`proxy`。 到目前为止vue还是用的 `Object.defineProperty`,所以我们拿 `Object.defineProperty`来举例子说明这个原理。 这里我想说的是,不管以后vue是否会用 `proxy` 重写这部分,我讲的是原理,并不是api,所以不论以后vue会怎样改,这个原理是不会变的,哪怕vue用了其他完全不同的原理实现了变化侦测,但是本篇文章讲的原理一样可以实现变化侦测,原理这个东西是不会过时的。 之前我写文章有一个毛病就是喜欢对着源码翻译,结果过了半年一年人家源码改了,我写的文章就一毛钱都不值了,而且对着源码翻译还有一个缺点是对读者的要求有点偏高,读者如果没看过源码或者看的和我不是一个版本,那根本就不知道我在说什么。 好了不说废话了,继续讲刚才的内容。 知道 `Object.defineProperty` 可以侦测到对象的变化,那么我们瞬间可以写出这样的代码: ```javascript function...

javascript
vue.js

# 小程序底层实现原理及一些思考 两月以后,看着电脑,我回想起接到通知说要开发小程序引擎的那个下午。当时的我以为,这个小程序和其他小程序都不一样,因为它是个假的,其实是个网页。两月之后,我才发现,“噢~原来大家都是这么做的啊”。 最近一直在做小程序的底层实现,过程中磕磕绊绊也多次进行架构方向上的转型,趁着周末抽空写一篇文章记录一下开发过程中遇到的问题和一些思考与决策。 > 本篇文章更多的是在描述架构与技术方向层面的思考和决策,不会过多介绍具体某个问题是如何解决的,因为细节实在太多。 ## 1. 单线程 当时的我将我们的小程序定位成一个SPA(单页应用),因为我们的小程序的宿主环境是浏览器。 它只是看起来像小程序(因为这个窗口没有地址栏什么的),但其实包括UI渲染和事件交互在内的绝大部分功能都是基于Web技术,虽然会提供Native和OS的一些能力与API,但本质上其实是个网页。又考虑到目前很多人使用第三方工具用Vue或React写小程序,我就在思考:“反正本质上就是一个网页,那为什么不原生内置Vue让用户直接用Vue的语法写小程序呢?”。 所以当时定了一个基本方向:让开发者使用Vue开发我们的小程序,开发体验完全与Web保持一致。 虽然开发体验与Web保持一致,但是Web技术实在是太开放了,开发者可以为所欲为。这种情况在小程序中是不允许的,不允许使用``、不允许``直接外跳到其他在线网页、不允许开发者触碰DOM、不允许使用某些未知的危险API等。 所以遇到的第一个问题是如何禁止用户在Vue的模板中使用`iframe`或`a`或其他不允许使用的东西。 若想做到这一点就不得不对Vue的渲染层进行一个托管与改造。 ### 1.1 改造Vue 对Vue进行改造通常有两种方案: 1. 使用类似`polyfill`的手法覆盖一些Vue原生提供的API 2. Fork一个Vue出来自己改 第一个方案能力有限,有一些Vue内部的逻辑没有办法通过`polyfill`的形式更改。第二种方案的缺陷是如果我只想修改Vue中的某一块逻辑,其他我不修改的部分如果有Bug,Vue官方更新了版本我没有办法同步。 **这两种方案都有缺陷和不足,所以我没有使用这两个其中的任何一个,我使用了另一个方案,我觉得应该是目前为止最好的一种方案。** 我简单介绍一下这种方案: 1. 把Vue.js装到`node_modules`里 2. 项目里使用webpack,并设置上别名...

javascript
总结与思考
架构