浏览器前端优化
优化关乎速度和满意度。
- 从用户体验(UX)角度,我们希望前端网页可以快速加载
从开发体验(DX)角度,我们希望前端是快速,简洁,规范的
浏览器都做了什么
我们希望浏览器打开一个简单的网页
|
|
浏览器如何渲染网页
- 使用 HTML 创建文档对象模型(DOM)
- 使用 CSS 创建 CSS 对象模型(CSSOM)
- 基于 DOM 和 CSSOM 执行脚本(Scripts)
- 合并 DOM 和 CSSOM 形成渲染树(Render Tree)
- 使用渲染树布局(Layout)所有元素
- 渲染(Paint)所有元素
JavaScript 数组方法对比
原文:“JavaScript Array Methods: Mutating vs. Non-Mutating”
笔记:涂鸦码龙
JavaScript 提供了多种新增,移除,替换数组元素的方法,但是有些会影响原来的数组;有些则不会,它是新建了一个数组。
注意:区分以下两个方法的不同点:
array.splice()
影响原来的数组array.slice()
不影响原来的数组
I. 新增:影响原数组
使用 array.push()
和 array.ushift()
新增元素会影响原来的数组。
|
|
React Native 的组件通信方式
题外话,说几句我对 React 与 React Native 关系的理解:
- React 主要用于浏览器端实现一些 UI 组件,也可用于服务端渲染。React 可以使用 HTML 提供的标签,也可封装自定义的组件,React 也提供直接操作 DOM 的方法;
- React Native 主要用于实现客户端应用(App)的 UI 组件,它只能使用 Facebook 封装的 Native 组件,或者自己封装的 Native 组件。开发中主要借助 JavaScript,基本告别 HTML 和 CSS 了,不过优点是可以用 ES6。
言归正传,正文开始
之前没搞过 React ,直接开撸的 React Native,使用过程也是各种踩坑填坑,磕磕绊绊,这里简单总结一下我用过的组件通信的几种方式吧。
React 最基础的 props 和 state
组件内部用 state
|
|
针对易读性的背景滤镜兼容方案(CSS filter 兼容方案)
你知道现在有多火吗?用这种很大的,高质量的,支持 Retina 屏的模糊的 JPEG 图片作为 header 背景 :
See the Pen Web site header, circa 2016 by Taylor Hunt (@tigt) on CodePen.
潜在的问题是如果浏览器不支持滤镜 filter,文字将不可读 。这违背了可访问性的原则,再完美的视觉也无济于事。
4类 JavaScript 内存泄漏及如何避免
原文:4 Types of Memory Leaks in JavaScript and How to Get Rid Of Them
笔记:涂鸦码龙译者注:本文并没有逐字逐句的翻译,而是把我认为重要的信息做了翻译。如果您的英文熟练,可以直接阅读原文。
本文将探索常见的客户端 JavaScript 内存泄漏,以及如何使用 Chrome 开发工具发现问题。
简介
内存泄漏是每个开发者最终都要面对的问题,它是许多问题的根源:反应迟缓,崩溃,高延迟,以及其他应用问题。
什么是内存泄漏?
本质上,内存泄漏可以定义为:应用程序不再需要占用内存的时候,由于某些原因,内存没有被操作系统或可用内存池回收。编程语言管理内存的方式各不相同。只有开发者最清楚哪些内存不需要了,操作系统可以回收。一些编程语言提供了语言特性,可以帮助开发者做此类事情。另一些则寄希望于开发者对内存是否需要清晰明了。
JavaScript 内存管理
JavaScript 是一种垃圾回收语言。垃圾回收语言通过周期性地检查先前分配的内存是否可达,帮助开发者管理内存。换言之,垃圾回收语言减轻了“内存仍可用”及“内存仍可达”的问题。两者的区别是微妙而重要的:仅有开发者了解哪些内存在将来仍会使用,而不可达内存通过算法确定和标记,适时被操作系统回收。
JavaScript 内存泄漏
垃圾回收语言的内存泄漏主因是不需要的引用。理解它之前,还需了解垃圾回收语言如何辨别内存的可达与不可达。
Mark-and-sweep
大部分垃圾回收语言用的算法称之为 Mark-and-sweep 。算法由以下几步组成:
- 垃圾回收器创建了一个“roots”列表。Roots 通常是代码中全局变量的引用。JavaScript 中,“window” 对象是一个全局变量,被当作 root 。window 对象总是存在,因此垃圾回收器可以检查它和它的所有子对象是否存在(即不是垃圾);
- 所有的 roots 被检查和标记为激活(即不是垃圾)。所有的子对象也被递归地检查。从 root 开始的所有对象如果是可达的,它就不被当作垃圾。
- 所有未被标记的内存会被当做垃圾,收集器现在可以释放内存,归还给操作系统了。
现代的垃圾回收器改良了算法,但是本质是相同的:可达内存被标记,其余的被当作垃圾回收。
不需要的引用是指开发者明知内存引用不再需要,却由于某些原因,它仍被留在激活的 root 树中。在 JavaScript 中,不需要的引用是保留在代码中的变量,它不再需要,却指向一块本该被释放的内存。有些人认为这是开发者的错误。
为了理解 JavaScript 中最常见的内存泄漏,我们需要了解哪种方式的引用容易被遗忘。
实例解析防抖动(Debouncing)和节流阀(Throttling)
原文:Debouncing and Throttling Explained Through Examples
笔记:涂鸦码龙
防抖(Debounce)和节流(throttle)都是用来控制某个函数在一定时间内执行多少次的技巧,两者相似而又不同。
当我们给 DOM 绑定事件的时候,加了防抖和节流的函数变得特别有用。为什么呢?因为我们在事件和函数执行之间加了一个控制层。记住,我们是无法控制 DOM 事件触发频率的。
看下滚动事件的例子:
See the Pen Scroll events counter by Corbacho (@dcorb) on CodePen.
当使用触控板,滚动滚轮,或者拖拽滚动条的时候,一秒可以轻松触发30次事件。经我的测试,在智能手机上,慢慢滚动一下,一秒可以触发事件100次之多。这么高的执行频率,你的滚动回调函数压力大吗?
早在2011年,Twitter 网站抛出了一个问题:向下滚动 Twitter 信息流的时候,变得很慢,很迟钝。John Resig 发表了一篇博客解释这个问题,文中解释到直接给 scroll
事件关联昂贵的函数,是多么糟糕的主意。
John(5年前)建议的解决方案是,在 onScroll
事件外部,每 250ms 循环执行一次。简单的技巧,避免了影响用户体验。
现如今,有一些稍微高端的方式处理事件。我来结合用例介绍下 Debounce,Throttle 和 requestAnimationFrame 吧。
你好 ES2015
原文: Say Hello To ES2015
笔记:涂鸦码龙
介绍 ES2015
ES2015 是新版的 JavaScript,Node.js 已经完全支持,浏览器端可以用 Babel 库编译。
运行本文的示例代码,可以用 JSBin 环境,也可以结合原文中的测试题检测学习效果。
使用 let 和 const
ES2015 可以用 const
或 let
替换 var
,它们定义了块级作用域变量。
示例代码:
|
|
变量 value
只能在 for
循环中使用。
const
跟 let
很像,但是它定义的变量值无法改变。
示例代码:
|
|
改变的是变量 user
内部的属性,并没有改变 user
本身。
许多人更喜欢用 const
代替 let
。
使用箭头函数整理你的代码
熟悉的方式:
|
|
使用箭头函数以后:
|
|
如果方法接受不止1个参数,可以这么写:
|
|
箭头函数返回一个对象的话,需要加圆括号:
|
|
flex-grow 不易理解,难道不是吗?
当我刚接触 flex-grow
时,为了探寻它的工作原理,做了一个简单的例子。
我以为理解的挺透彻了,但是当我把它应用到同事的网站上时,效果跟我想象的完全不同。无论怎么改,布局都无法像我的demo那样展示。这时我才意识到,我并没有完全掌握 flex-grow
。
flex-grow 为何不正常
在我深入剖析 flex-grow
的功能之前,我想解释一下我起初犯了什么错。
我认为所有 flex 元素的 flex-grow
如果设置为 1
,它们将一样宽。如果某一项的 flex-grow
设置为 2
,它将是其它元素的二倍宽。
一切听起来顺理成章。我上面的例子 貌似也印证了这点。父元素是900px宽,flex-grow: 2
的 section 元素计算后是600px宽,flex-grow: 1
的 aside 元素计算后是300px宽。
如你所见,它在这个例子中展现的近乎完美,可是在真实的例子中却不尽人意,即使我们用了完全相同的 CSS。事实证明,问题不在 CSS,而在于内容(或者说缺乏内容)。我的测试用例只用了两个空元素,无法展示这个属性最重要的细节。
flex-grow 到底如何工作
啰嗦了半天,我终于要解释 flex-grow
没有尽如人意的原因了。
为了阐明原因,我又搞了个栗子 ,所有的设置跟第一个栗子 完全一致,只不过 section 和 aside 元素不再是空的。看吧,两个元素的比例不再是 2 : 1,flex-grow 为 1 的元素的确比 flex-grow 为 2 的元素宽不少呐。
CSS分层动画可以让元素沿弧形路径运动
原文:Moving along a curved path in CSS with layered animation
翻译:涂鸦码龙译者注:部分代码示例在原文中可以看效果(作者写在博文里面了…),我偷懒把它做成Gif图了。
CSS 的 animations (动画) 和 transitions(变换)擅于实现从点 A 到点 B 的直线运动,运动轨迹是直线路径。给一个元素添加了 animation
或者 transition
以后,无论你如何调整贝塞尔曲线,都无法让它沿着弧形路径运动。你可以通过自定义 timing function 属性,做出弹动的效果,但是它沿着 X 和 Y 轴相对移动的值永远是相同的。
与其使用 JavaScript 实现外观自然的运动,不如尝试用这种简单的方式:分层动画,绕过已有的限制。通过使用两个或多个元素实现动画效果,我们可以更加细粒度地控制某个元素的路径,沿着 X 轴运动使用一种 timing function ,沿着 Y 轴运动使用另一种 timing function 。
问题所在
当我们深入探讨解决方案之前,看看到底问题在哪。CSS animations
和 transitions
限制我们只能沿直线路径运动。元素总是沿着点 A 到点 B 的最短路径运动,如果我们另辟蹊径,告诉 CSS 沿着“更好的路径”,而不是“最短路径”运动呢?
用 CSS (开启硬件加速)实现两点之间的运动,最直截了当的方式是使用 transform
的 translate
在一定时间内移动某个元素。这就产生了直线运动。在 @keyframes
中,我们打算在 (0,0) 和 (100,-100) 间来回运动,见上图例子:
|
|
这些看起来并不难懂,但我们稍等片刻,思考一下我们需要的解决方案,拆分开来的动画,视觉上长什么样子呢。
0%
时,元素从 (0,0) 出发,50%
时,我们用了 translate3D(100px, -100px, 0)
把它移动到 (100,-100),然后原路返回。换句话说,我们把元素向右移动了 100px
,向上移动了 100px
,两个方向联合作用使元素沿着一个角度运动。
复选框的 CSS 魔法
Checkbox 复选框相当好用,加对 CSS 魔法有奇效。此文旨在展示一些利用 checkbox 实现的有创意的东西,并且文中的例子没用 JavaScript 哟。
基本配方
从 HTML 着手。
|
|
此处无技巧可言。<label>
的 for
属性匹配 <input>
的 id
属性,因此点击 <label>
可以控制 <input>
复选框。这点尤其重要,因为下一步将隐藏 <input>
。
|
|
为什么不用 display: none
?因为屏幕阅读机和键盘 Tab 会忽略它。此方法让 <input>
保持在文档流中,但是让它离屏隐藏(超出屏幕可见范围达到隐藏)。
隐藏 <input>
以后,我们更容易大展身手。我们仍需传达选中/未选两种状态,但是可以通过 <label>
完成。真正的派对开始啦。
|
|
我们使用 :checked
伪类, 和相邻兄弟元素选择器(+
)的组合达到目的,当复选框选中时,找到紧随其后的 <label>
元素,加上想要的样式。还可以利用 <label>
中的伪元素( ::before
和 ::after
)实现更有创意的想法。
|
|
来,看看实际效果吧。例子用到了以上提及的基本配方,把一个普普通通的复选框改造得当人眼前一亮。