- 博客(44)
- 收藏
- 关注
原创 第五篇《内存泄露》
这篇文章是针对浏览器的 JavaScript 脚本,Node.js 大同小异,这里不涉及到 Node.js 的场景。当然 Node.js 作为服务端语言,必然更关注内存泄漏的问题。用户一般不会在一个 Web 页面停留比较久,即使有一点内存泄漏,重载页面内存也会跟着释放。而且浏览器也有自动回收内存的机制,所以我们前端其实并没有像 C、C++ 这类语言一样,特别关注内存泄漏的问题。但是如果我们对内存泄漏没有什么概念,有时候还是有可能因为内存泄漏,导致页面卡顿。了解内存泄漏,如何避免内存泄漏,也是我们
2021-12-16 15:34:23 1416
原创 第四篇《缓存策略》
概述浏览器的缓存机制也就是我们说的HTTP缓存机制,其机制是根据HTTP报文的缓存标识进行的,所以在分析浏览器缓存机制之前,我们先使用图文简单介绍一下HTTP报文,HTTP报文分为两种:HTTP请求(Request)报文,报文格式为:请求行 – HTTP头(通用信息头,请求头,实体头) – 请求报文主体(只有POST才有报文主体),如下图HTTP响应(Response)报文,报文格式为:状态行 – HTTP头(通用信息头,响应头,实体头) – 响应报文主体,如下图注:通用信息头指的是请求
2021-12-16 15:31:04 193
原创 第三篇《DOM树》
在上一篇文章中,我们通过开发者工具中的网络面板,介绍了网络请求过程的几种性能指标以及对页面加载的影响。而在渲染流水线中,后面的步骤都直接或者间接地依赖于 DOM 结构,所以本文我们就继续沿着网络数据流路径来介绍 DOM 树是怎么生成的。然后再基于 DOM 树的解析流程介绍两块内容:第一个是在解析过程中遇到 JavaScript 脚本,DOM 解析器是如何处理的?第二个是 DOM 解析器是如何处理跨站点资源的?什么是 DOM从网络传给渲染引擎的 HTML 文件字节流是无法直接被渲染引擎理解的,所以要
2021-12-16 15:24:55 1794
原创 第二篇《history和hash两种路由》
为什么要使用路由现在的网络应用程序越来越多的使用AJAX异步请求完成页面的无缝刷新,导致浏览器的URL不会发生任何变化而完成了请求,从而破换了用户浏览体验。同时本次浏览的页面内容在用户下次使用URL访问时将无法重新呈现,使用路由可以很好地解决这个问题。单页面应用利用了JavaScript动态变换网页内容,避免了页面重载;路由则提供了浏览器地址变化,网页内容也跟随变化,两者结合起来则为我们提供了体验良好的单页面web应用。前端路由实现方式路由需要实现三个功能:当浏览器地址变化时,切换页
2021-12-16 15:21:56 233
原创 第一篇《跨标签页通信》
引言在浏览器中,我们可以同时打开多个Tab页,每个Tab页可以粗略理解为一个“独立”的运行环境,即使是全局对象也不会在多个Tab间共享。然而有些时候,我们希望能在这些“独立”的Tab页面之间同步页面的数据、信息或状态。正如下面这个例子:我在列表页点击“收藏”后,对应的详情页按钮会自动更新为“已收藏”状态;类似的,在详情页点击“收藏”后,列表页中按钮也会更新。这就是我们所说的前端跨页面通信。你知道哪些跨页面通信的方式呢?如果不清楚,下面我就带大家来看看七种跨页面通信的方式。一、同源页面间的
2021-12-16 15:19:20 653
原创 第八篇《BFC》
一、常见定位方案在讲 BFC 之前,我们先来了解一下常见的定位方案,定位方案是控制元素的布局,有三种常见方案:普通流 (normal flow)在普通流中,元素按照其在 HTML 中的先后位置至上而下布局,在这个过程中,行内元素水平排列,直到当行被占满然后换行,块级元素则会被渲染为完整的一个新行,除非另外指定,否则所有元素默认都是普通流定位,也可以说,普通流中元素的位置由该元素在 HTML 文档中的位置决定。浮动 (float)在浮动布局中,元素首先按照普通流的位置出现,然后根据浮动
2021-12-10 09:15:50 298
原创 第七篇《css优先级》
什么是权重权重决定了你css规则怎样被浏览器解析直到生效。“css权重关系到你的css规则是怎样显示的”。当很多的样式被应用到某一个元素上时,权重是一个决定哪种样式生效,或者是优先级的过程。每个选择器都有自己的权重。你的每条css规则,都包含一个权重级别。 这个级别是由不同的选择器加权计算的,通过权重,不同的样式最终会作用到你的网页中 。如果两个选择器同时作用到一个元素上,权重高者生效。权重记忆口诀:从0开始,一个行内样式+1000,一个id选择器+100,一个属性选择器、class或者伪类+
2021-12-10 09:10:54 631
原创 第六篇《CSS选择器》
简介选择器是 CSS 规则的一部分且位于 CSS 声明块前。选择器可以被分为以下类别:简单选择器(Simple selectors):通过元素类型、class 或 id 匹配一个或多个元素。属性选择器(Attribute selectors):通过 属性 / 属性值 匹配一个或多个元素。伪类(Pseudo-classes):匹配处于确定状态的一个或多个元素,比如被鼠标指针悬停的元素,或当前被选中或未选中的复选框,或元素是 DOM 树中一父节点的第一个子节点。伪元素(Pseudo-elemen
2021-12-10 09:07:06 277
原创 第五篇《盒子模型》
盒模型的认识基本概念:标准模型+IE模型。 包括margin,border,padding,content标准模型和IE模型的区别css如何设置获取这两种模型的宽和高js如何设置获取盒模型对应的宽和高根据盒模型解释边距重叠BFC(边距重叠解决方案,还有IFC)解决边距重叠一、基本概念:标准模型+IE模型**什么是盒模型:**盒模型又称框模型(Box Model),包含了元素内容(content)、内边距(padding)、边框(border)、外边距(margin)几个要素。如图:由于
2021-12-10 09:05:24 135
原创 第四篇《CSS3新特性》
1.前言css3这个相信大家不陌生了,是个非常有趣,神奇的东西!有了css3,js都可以少写很多!我之前也写过关于css3的文章,也封装过css3的一些小动画。个人觉得css3不难,但是很难用得好,用得顺手,最近我也在过一遍css3的一些新特性(不是全部,是我在工作上常用的,或者觉得有用的),以及一些实例,就写了这一篇总结!希望,这篇文章能帮到大家认识css3。写这篇文章主要是让大家能了解css3的一些新特性,以及基础的用法,感觉css3的魅力!如果想要用好css3,这个得靠大家继续努力学习,寻找一些讲得
2021-12-10 09:00:06 675
原创 第三篇《CSS性能优化》
提高性能的方法有哪些?合并css文件,如果页面加载10个css文件,每个文件1k,那么也要比只加载一个100k的css文件慢。减少css嵌套,最好不要嵌套三层以上。不要在ID选择器前面进行嵌套,ID本来就是唯一的而且权限值大,嵌套完全是浪费性能。建立公共样式类,把相同样式提取出来作为公共类使用。减少通配符*或者类似[hidden=“true”]这类选择器的使用,挨个查找所有…这性能能好吗?巧妙运用css的继承机制,如果父节点定义了,子节点就无需定义。拆分出公共css文件,对于比较大的项目可以
2021-12-10 08:56:12 203
原创 第二篇《CSS样式隔离》
CSS 发展我们在书写 css 的时候其实经历了以下几个阶段:手写源生 CSS使用预处理器 Sass/Less使用后处理器 PostCSS使用 css modules使用 css in js手写源生 CSS在我们最初学习写页面的时候,大家都学过怎么去写 css,也就以下几种情况:行内样式,即直接在 html 中的 style 属性里编写 css 代码。内嵌样式,即在 html h 中的 style 标签内编写 class,提供给当前页面使用。导入样式,即在内联样式中 通过 @im
2021-12-10 08:55:11 1147
原创 第一篇《层叠上下文》
零、世间的道理都是想通的在这个世界上,凡事都有个先后顺序,凡物都有个论资排辈。比方说食堂排队打饭,对吧,讲求先到先得,总不可能一拥而上。再比如说话语权,老婆的话永远是对的,领导的话永远是对的。在CSS届,也是如此。只是,一般情况下,大家歌舞升平,看不出什么差异,即所谓的众生平等。但是,当发生冲突发生纠葛的时候,显然,是不可能做到完全等同的,先后顺序,身份差异就显现出来了。例如,杰克和罗斯,只能一人浮在木板上,此时,出现了冲突,结果大家都知道的。那对于CSS世界中的元素而言,所谓的“冲突”指什么呢,其
2021-12-10 08:51:55 395
原创 第十七篇《 基础数据类型,引用数据类型,区别?》
基础数据类型:Undfined,Null,Bollean,Number,String,Symbol引用类型:Object,Array,Date,RegExp,Function1、栈(stack)和堆(heap)stack为自动分配的内存空间,它由系统自动释放;而heap则是动态分配的内存,大小也不一定会自动释放2、数据类型JS分两种数据类型:基本数据类型:Number、String、Boolean、Null、 Undefined、Symbol(ES6),这些类型可以直接操作保存在变量中的实际
2021-12-09 20:42:20 121
原创 第五篇《描述下浏览器从输入网址到页面展现的整个过程》
对浏览器原理有过了解的一定不会陌生这篇神文《How Browsers Work》中文翻译:浏览器原理:新式网络浏览器幕后揭秘。另外还有一篇 《What really happens when you navigate to a URL》。大神写的东西很长很复杂,阅读成本虽然大,但能学到东西。所以,我也试着用自己的理解去写一写,算是做个巩固。里面有很多参考,如涉及版权,侵权删!表述有误,请指正!前端为什么要研究渲染原理?像素完美(Pixel Perfection)、分辨率无关(Resolution I.
2021-12-03 09:40:04 423
原创 第四篇《大量图片加载优化》
饿了么 App 中新零售项目主要是以图片展示为主,引导用户点击轮播广告栏或者店铺列表进入指定的商品页面,因此页面中包含了大量图片,如搜索框下面的轮播广告栏、中部的促销栏以及底部的店铺列表,这些区域中都有大量的展示图片。因此图片的加载速率直接影响页面的加载速度。下面将从图片加载存在的问题和原因、解决方案两个方面来阐述如何优化新零售图片的加载。本文所有数据及图片都是通过 Charles 模拟 256 kbps ISDN/DSL 网络环境获取到的。在本案例中只考虑位图,因此文本中提及的图片都是指位图而非矢量图。
2021-12-03 09:37:30 398
原创 第三篇《性能优化》
减少体积利用webpack等压缩工具(js压缩,css压缩,img压缩)提供公共方法,第三方库gzip压缩http2合理分配CDN资源和域名每个游览器的同一域名下的在相同时间段内有一个最大连接数合理分配不同的域名,可以让游览器更快的进行请求,不至于堵塞缓存网络资源,缓存,更快的进入页面对第一次进入页面美业影响,对第二次及为需要更新时,影响最为明显如果需要更新:进入页面时判断当前版本号是否与所需版本号一致,不一致进行更新还可以部分数据缓存,例如:localStorage对资
2021-12-03 09:32:44 421
原创 第二篇《重排(reflow)和重绘(repaint)》
页面生成的过程:1.HTML 被 HTML 解析器解析成 DOM 树;2.CSS 被 CSS 解析器解析成 CSSOM 树;3.结合 DOM 树和 CSSOM 树,生成一棵渲染树(Render Tree),这一过程称为 Attachment;4.生成布局(flow),浏览器在屏幕上“画”出渲染树中的所有节点;5.将布局绘制(paint)在屏幕上,显示出整个页面。第四步和第五步是最耗时的部分,这两步合起来,就是我们通常所说的渲染。渲染:在页面的生命周期中,网页生成的时候,至少会渲染一次。在用
2021-12-03 09:30:50 951
原创 第一篇《白屏》
前言该篇文章会为您分享在前端性能优化中非常重要的一环-白屏时间,将从白屏时间的概念、重要性以及白屏的过程一一进行阐述,同时提供性能优化的策略与实践。一、概念白屏时间:即用户点击一个链接或打开浏览器输入URL地址后,从屏幕空白到显示第一个画面的时间。白屏时间的长短将直接影响用户对该网站的第一印象。二、白屏时间的重要性当用户点开一个链接或者是直接在浏览器中输入URL开始进行访问时,就开始等待页面的展示。页面渲染的时间越短,用户等待的时间就越短,用户感知到页面的速度就越快。这样可以极大的提升用户的
2021-12-03 09:27:47 115
原创 第九篇《如何使用 JS 实现发布订阅器》
class Event { events = {} emit (type, ...args) { const listeners = this.events[type] for (const listener of listeners) { listener(...args) } } on (type, listener) { this.events[type] = this.events[type] || [] this.event
2021-11-24 11:03:01 536
原创 第八篇《JS 实现两个大数相加》
当有两个整数 a 和 b ,在通常情况下我们有“+”运算符对其进行相加运算:let sum = a + b; 但是 JS 在存放整数的时候是有一个安全范围的,一旦数字超过这个范围便会损失精度。我们不能拿精度损失的数字进行运行,因为运算结果一样是会损失精度的。所以,我们要用字符串来表示数据!(不会丢失精度)JS 中整数的最大安全范围可以查到是:9007199254740991假如我们要进行 9007199254740991 + 1234567899999999999我们要先准备两个字符串变
2021-11-24 10:53:38 205
原创 第七篇《如何实现无限累加的一个函数》
function sum (...args) { const f = (...rest) => sum(...args, ...rest) f.valueOf = () => args.reduce((x, y) => x + y, 0) return f}const a = sum(1, 2, 3).valueOf() //6const b = sum(2, 3)(2).valueOf() //7const c = sum(1)(2)(3)(4).valueOf()
2021-11-24 10:51:51 284
原创 第六篇《实现一个数组扁平化的函数 flatten》
function flatten (list, depth = 1) { if (depth === 0) return list return list.reduce((a, b) => a.concat(Array.isArray(b) ? flatten(b, depth - 1) : b), [])}const a = flatten([1, 2, 3, [4, [5, 6]]])const b = flatten([1, 2, 3, [4, [5, 6]]], 2)con
2021-11-24 10:46:20 168
原创 第五篇《如何实现一个 ORM 类似的 find 链式调用》
const data = [ {userId: 8, title: 'title1'}, {userId: 11, title: 'other'}, {userId: 15, title: null}, {userId: 19, title: 'title2'}];function find (data) { return { data, where (match) { this.data = this.data.filter((item) =>
2021-11-24 10:43:44 158
原创 第四篇《如何实现一个数组洗牌函数 shuffle》
function shuffle (list) { const len = list.length let result = [...list] for (let i = len - 1; i > 0; i--) { const swapIndex = Math.floor(Math.random() * (i + 1)); [result[i], result[swapIndex]] = [result[swapIndex], result[i]] } retur
2021-11-24 10:41:39 384
原创 第三篇《实现千位分隔符》
将普通的数字转换为带千位分隔符格式的数字字符串是一个非常常见的问题,千位分隔符格式的规则是数字的整数部分每三位一组,以“,”分节。小数部分不分节 。示例:19,351,235.235767这里有几个常见的实现方法。1.方法一实现思路是将数字转换为字符数组,再循环整个数组, 每三位添加一个分隔逗号,最后再合并成字符串。因为分隔符在顺序上是从后往前添加的:比如 1234567添加后是1,234,567 而不是 123,456,7 ,所以方便起见可以先把数组倒序,添加完之后再倒序回来,就是正常的顺序了。要
2021-11-22 14:47:29 497
原创 第二篇《实现 add(1)(2)(3)》
前言本文主要从 3W (what, how, why) 角度出发通俗易懂的解释一下 什么是函数柯里化,以及怎么用三行代码来实现 add(1)(2)(3) 这个很常见的面试题。什么是函数柯里化(curry)函数柯里化(curry)是函数式编程里面的概念。curry的概念很简单:只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。简单点来说就是:每次调用函数时,它只接受一部分参数,并返回一个函数,直到传递所有参数为止。举个???? 将下面接受两个参数的函数改为接受一个参数的函数。con
2021-11-22 14:46:06 308
原创 第一篇《笔试》
一道算法题一共10颗糖,每次拿1颗或2颗,问有多少种方法?例:1,1,1,1,1,1,1,1,1,1为一种2,2,2,2,2为一种function test(n) { if(n == 1){ return 1 } else if(n == 2){ return 2 } else{ return test(n - 1) + test(n - 2) }}console.log(test(10));f(n) = f(n-1) + f(n-2)
2021-11-22 14:43:53 423
原创 第十六篇《generator原理》
随着 Javascript 语言的发展,ES6 规范为我们带来了许多新的内容,其中生成器 Generators 是一项重要的特性。利用这一特性,我们可以简化迭代器的创建,更加令人兴奋的,是 Generators 允许我们在函数执行过程中暂停、并在将来某一时刻恢复执行。这一特性改变了以往函数必须执行完成才返回的特点,将这一特性应用到异步代码编写中,可以有效的简化异步方法的写法,同时避免陷入回调地狱。本文将对 Generators 进行简单介绍,然后结合笔者在 C#上的一点经验,重点探讨 Generators
2021-11-21 22:22:17 411 1
原创 第十五篇《promise原理》
这一次,彻底弄懂 Promise 原理Promise 必须为以下三种状态之一:等待态(Pending)、执行态(Fulfilled)和拒绝态(Rejected)。一旦Promise 被 resolve 或 reject,不能再迁移至其他任何状态(即状态 immutable)。基本过程:初始化 Promise 状态(pending)立即执行 Promise 中传入的 fn 函数,将Promise 内部 resolve、reject 函数作为参数传递给 fn ,按事件机制时机处理执行 then(…)
2021-11-21 22:21:59 111
原创 第十四篇《事件循环机制》
前言我们都知道,javascript从诞生之日起就是一门单线程的非阻塞的脚本语言。这是由其最初的用途来决定的:与浏览器交互。单线程意味着,javascript代码在执行的任何时候,都只有一个主线程来处理所有的任务。而非阻塞则是当代码需要进行一项异步任务(无法立刻返回结果,需要花一定时间才能返回的任务,如I/O事件)的时候,主线程会挂起(pending)这个任务,然后在异步任务返回结果的时候再根据一定规则去执行相应的回调。单线程是必要的,也是javascript这门语言的基石,原因之一在其
2021-11-21 22:21:39 110
原创 第十三篇《new操作符》
new一句话介绍 new:new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象类型之一也许有点难懂,我们在模拟 new 之前,先看看 new 实现了哪些功能。举个例子:// Otaku 御宅族,简称宅function Otaku (name, age) { this.name = name; this.age = age; this.habit = 'Games';}// 因为缺乏锻炼的缘故,身体强度让人担忧Otaku.prototype.
2021-11-21 22:21:10 63
原创 第十二篇《浮点数精度》
前言0.1 + 0.2 是否等于 0.3 作为一道经典的面试题,已经广外熟知,说起原因,大家能回答出这是浮点数精度问题导致,也能辩证的看待这并非是 ECMAScript 这门语言的问题,今天就是具体看一下背后的原因。数字类型ECMAScript 中的 Number 类型使用 IEEE754 标准来表示整数和浮点数值。所谓 IEEE754 标准,全称 IEEE 二进制浮点数算术标准,这个标准定义了表示浮点数的格式等内容。在 IEEE754 中,规定了四种表示浮点数值的方式:单精确度(32位)、双精确度
2021-11-21 22:20:19 163
原创 第十一篇《v8垃圾回收机制》
引言作为目前最流行的JavaScript引擎,V8引擎从出现的那一刻起便广泛受到人们的关注,我们知道,JavaScript可以高效地运行在浏览器和Nodejs这两大宿主环境中,也是因为背后有强大的V8引擎在为其保驾护航,甚至成就了Chrome在浏览器中的霸主地位。不得不说,V8引擎为了追求极致的性能和更好的用户体验,为我们做了太多太多,从原始的Full-codegen和Crankshaft编译器升级为Ignition解释器和TurboFan编译器的强强组合,到隐藏类,内联缓存和HotSpot热点代码收集等
2021-11-18 09:22:28 285
原创 第十篇《柯里化》
定义维基百科中对柯里化 (Currying) 的定义为:In mathematics and computer science, currying is the technique of translating the evaluation of a function that takes multiple arguments (or a tuple of arguments) into evaluating a sequence of functions, each with a single ar
2021-11-18 09:06:01 83
原创 第九篇《细说 call、apply 以及 bind 的区别和用法》
call 和 apply 的共同点它们的共同点是,都能够改变函数执行时的上下文,将一个对象的方法交给另一个对象来执行,并且是立即执行的。为何要改变执行上下文?举一个生活中的小例子:平时没时间做饭的我,周末想给孩子炖个腌笃鲜尝尝。但是没有适合的锅,而我又不想出去买。所以就问邻居借了一个锅来用,这样既达到了目的,又节省了开支,一举两得。改变执行上下文也是一样的,A 对象有一个方法,而 B 对象因为某种原因,也需要用到同样的方法,那么这时候我们是单独为 B 对象扩展一个方法呢,还是借用一下 A 对象的方法呢
2021-11-18 09:05:08 71
原创 第八篇《instanceof原理》
typeof 实现原理typeof 一般被用于判断一个变量的类型,我们可以利用 typeof 来判断number, string, object, boolean, function, undefined, symbol 这七种类型,这种判断能帮助我们搞定一些问题,比如在判断不是 object 类型的数据的时候,typeof能比较清楚的告诉我们具体是哪一类的类型。但是,很遗憾的一点是,typeof 在判断一个 object的数据的时候只能告诉我们这个数据是 object, 而不能细致的具体到是哪一种 ob
2021-11-18 09:04:15 164
原创 第七篇《立即执行函数》
也许你没有注意到,我是一个对于专业术语有一点强迫症的人。所以,当我多次听到流行却易产生误解的术语「自执行匿名函数」,我最终决定将我的想法写进这篇文章里。更进一步地说,除了提供关于该模式究竟是如何工作的全面信息,事实上我还建议了我们应该怎样称呼这种模式。另外,如果你想跳过这里,你可以直接跳到立即调用函数表达式进行阅读,但是我建议你读完整篇文章。请理解这篇文章不是想说「我对了,你错了」。我发自真心地想帮助人们理解看似复杂的概念,并且我认为使用前后一致的精确术语是有助于人们理解的最简单的方式之一。它是什么
2021-11-17 17:20:46 134
原创 第六篇《this的指向》
前言在《JavaScript深入之执行上下文栈》中讲到,当JavaScript代码执行一段可执行代码(executable code)时,会创建对应的执行上下文(execution context)。对于每个执行上下文,都有三个重要属性变量对象(Variable object,VO)作用域链(Scope chain)this今天重点讲讲 this,然而不好讲。……因为我们要从 ECMASciript5 规范开始讲起。先奉上 ECMAScript 5.1 规范地址:英文版:http:/
2021-11-17 17:19:24 109
原创 第五篇《变量提升》
前言在上篇《JavaScript深入之执行上下文栈》中讲到,当 JavaScript 代码执行一段可执行代码(executable code)时,会创建对应的执行上下文(execution context)。对于每个执行上下文,都有三个重要属性:变量对象(Variable object,VO)作用域链(Scope chain)this今天重点讲讲创建变量对象的过程。变量对象变量对象是与执行上下文相关的数据作用域,存储了在上下文中定义的变量和函数声明。因为不同执行上下文下的变量对象稍有不
2021-11-17 17:17:34 93
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人