bt365体育投注.主頁欢迎您!!

    <acronym id="zvmrr"></acronym>
    <td id="zvmrr"></td>
  • <tr id="zvmrr"><label id="zvmrr"></label></tr>
  • <acronym id="zvmrr"></acronym>
  • 夜尽天明

    夜尽天明 查看完整档案

    广州编辑  |  填写毕业院校  |  填写所在公司/组织 github.com/biaochenxuying/blog 编辑
    编辑

    公众号:全栈修炼

    转载文章,请联系笔者。

    个人动态

    夜尽天明 收藏了文章 · 今天 13:00

    Node.js:浅析高并发与分布式集群

    本文首发于我的个人博客: kmknkk.xin
    不足之处欢迎斧正!

    Node特性:高并发

    在解释node为什么能够做到高并发之前,不妨先了解一下node的其他几个特性:

    单线程

    我们先来明确一个概念,即:node是单线程的,这一点与JavaScript在浏览器中的特性相同,并且在node中JavaScript主线程与其他线程(例如I/O线程)是无法共享状态的。

    单线程的好处就是:

    • 无需像多线程那样去关注线程之间的状态同步问题
    • 没有线程切换所带来的开销
    • 没有死锁存在

    当然单线程也有许多坏处:

    • 无法充分利用多核CPU
    • 大量计算占用CPU会导致应用阻塞(即不适用CPU密集型)
    • 错误会引起整个应用的退出

    不过在今天看来,这些坏处都已经不再是问题或者得到了适当的解决:

    (1) 创建进程 or 细分实例

    关于第一个问题,最直白解决方案就是使用child_process核心模块或者cluster:child_process 和 net 组合应用。我们可以通过在一台多核服务器上创建多个进程(通常使用fork操作)来充分利用每个核心,不过要处理好进程间通信问题。

    另一个方案是,我们可以将物理机器划分为多台单核的虚拟机,并通过pm2等工具,管理多台虚拟机形成一个集群架构,高效运行所需服务,至于每台机器间的通信(状态同步)我这里先按下不表,在下文的Node分布式架构中再做详细说明。

    (2) 时间片轮转

    关于第二点,我跟小伙伴讨论过后认为可以通过时间片轮转方式,在单线程上模拟多线程,适当减少应用阻塞的感觉(虽然这种方法不会真的像多线程那样节约时间)

    (3) 负载均衡、坏点监控/隔离

    至于第三点,我跟小伙伴们也讨论过,认为主要的痛点就在于node不同于JAVA,它所实现的逻辑是以异步为主的。

    这就导致了node无法像JAVA一样方便地使用 try/catch 来来捕获并绕过错误,因为无法确定异步任务会何时传回异常。而在单线程环境下,绕不过错误就意味着导致应用退出,重启恢复的间隙会导致服务中断,这是我们不愿意看到的。

    当然,在服务器资源丰富的当下,我们可以通过 pm2 或 nginx 这些工具,动态的判断服务状态。在服务出错时隔离坏点服务器,将请求转发到正常服务器上,并重启坏点服务器以继续提供服务。这也是Node分布式架构的一部分。

    异步I/O

    你可能会问,既然node是单线程的,事件全部在一个线程上处理,那不是应该效率很低、与高并发相悖吗?

    恰恰相反,node的性能很高。原因之一就是node具有异步I/O特性,每当有I/O请求发生时,node会提供给该请求一个I/O线程。然后node就不管这个I/O的操作过程了,而是继续执行主线程上的事件,只需要在该请求返回回调时在处理即可。也就是node省去了许多等待请求的时间。

    这也是node支持高并发的重要原因之一

    实际上不光是I/O操作,node的绝大多数操作都是以这种异步的方式进行的。它就像是一个组织者,无需事必躬亲,只需要告诉成员们如何正确的进行操作并接受反馈、处理关键步骤,就能使得整个团队高效运行。

    事务驱动

    你可能又要问了,node怎么知道请求返回了回调,又应该何时去处理这些回调呢?

    答案就是node的另一特性:事务驱动,即主线程通过event loop事件循环触发的方式来运行程序

    这是node支持高并发的另一重要原因

    图解node环境下的Event loop:

       ┌───────────────────────┐
    ┌─>│        timers         │<————— 执行 setTimeout()、setInterval() 的回调
    │  └──────────┬────────────┘
    |             |<-- 执行所有 Next Tick Queue 以及 MicroTask Queue 的回调
    │  ┌──────────┴────────────┐
    │  │     I/O callbacks     │<————— 执行几乎所有的回调,除了 close callbacks 以及 timers 调度的回调和 setImmediate() 调度的回调
    │  └──────────┬────────────┘
    |             |<-- 执行所有 Next Tick Queue 以及 MicroTask Queue 的回调
    │  ┌──────────┴────────────┐
    │  │     idle, prepare     │<————— 内部调用,可忽略
    │  └──────────┬────────────┘     
    |             |<-- 执行所有 Next Tick Queue 以及 MicroTask Queue 的回调
    |             |                   ┌───────────────┐
    │  ┌──────────┴────────────┐      │   incoming:   │ - (retrieve new I/O events; node will block here when appropriate)
    │  │         poll          │<─────┤  connections, │ 
    │  └──────────┬────────────┘      │   data, etc.  │ 
    │             |                   |               | 
    |             |                   └───────────────┘
    |             |<-- 执行所有 Next Tick Queue 以及 MicroTask Queue 的回调
    |  ┌──────────┴────────────┐      
    │  │        check          │<————— setImmediate() 的回调将会在这个阶段执行
    │  └──────────┬────────────┘
    |             |<-- 执行所有 Next Tick Queue 以及 MicroTask Queue 的回调
    │  ┌──────────┴────────────┐
    └──┤    close callbacks    │<————— socket.on('close', ...)
       └───────────────────────┘
    

    poll阶段:

    当进入到poll阶段,并且没有timers被调用的时候,会发生下面的情况:

    (1)如果poll队列不为空:

    • Event Loop 将同步的执行poll queue里的callback(新的I/O事件),直到queue为空或者执行的callback到达上线。

    (2)如果poll队列为空:

    • 如果脚本调用了setImmediate(), Event Loop将会结束poll阶段并且进入到check阶段执行setImmediate()的回调。
    • 如果脚本没有setImmediate()调用,Event Loop将会等待回调(新的I/O事件)被添加到队列中,然后立即执行它们。

    当进入到poll阶段,并且调用了timers的话,会发生下面的情况:

    • 一旦poll queue是空的话,Event Loop会检查是否timers, 如果有1个或多个timers时间已经到达,Event Loop将会回到timer阶段并执行那些timer的callback(即进入到下一次tick)。

    优先级:

    根据上面的图,我们不难得出:

    Next Tick Queue > MicroTask Queue

    那么setTimeout、setInterval和setImmediate谁快呢?

    答案是:不确定

    单单从执行图上看,如果两者都是在mian module里定义的,那么:setTimeout、setInterval > setImmediate

    但是有两个条件制约了这一结论:

    • event loop初始化需要一定时间
    • setTimeout有最小毫秒数(一般认为最少1ms)

    所以当 event loop准备时间 > setTimeout毫秒数时,进入timers检查时已有setTimeout的任务,故timeout先输出。反之则immediate先输出。

    如果是在poll阶段定义的setTimeout和setImmediate,那么immediate先于timeout输出。原因是在poll阶段,会先进入check阶段再进入timers阶段。例如:

    const fs = require('fs');
    
    fs.readFile('./test.txt', 'utf8', (err, data) => {
        setTimeout( () => {
            console.log('setTimeout');
        }, 0);
        setImmediate( () => {
            console.log('setImmediate');
        })
    })
    
    /**
     *
     * console:
     * > setImmediate
     * > setTimeout
     *
     **/

    多说一句:
    由于timer需要从红黑树中取出定时器来判断时间是否到了,时间复杂度为O(lg(n)),故如果想立即异步执行一个事件,最好不要用 setTimeout(func, 0)。而是使用 process.nextTick() 来完成。


    分布式Node架构

    我了解到的Node集群架构主要分为以下几个模块:

    Nginx(负载均衡、调度) -> Node集群 -> Redis(同步状态)

    按我的理解整理了一副图:

    Node集群架构

    当然,这应该是比较理想状态下的架构方式。因为虽然 Redis 的读/写相当快,但这是因为其将数据存储在内存池里,在内存上进行相关操作。

    这对于服务器的内存负荷是相当高的,所以通常我们还是会在架构中加入 Mysql,如下图:

    Mysql-Redis

    先解释一下这幅图:
    当用户数据到来时,将数据先写入 Mysql,Node 需要数据时再去 Redis 读取,若没有找到再去 Mysql 里面查询想要的数据,并写入 Redis,下次使用时就可以直接去 Redis 里面查询了。

    加入 Mysql 相较于只在 Redis 里读/写的好处有:

    (1)避免了短期内无用的数据写入 Redis,占用内存,减轻 Redis 负担

    (2)在后期需要对数据进行特定查询、分析的时候(比如分析运营活动用户涨幅),SQL关系查询能提供很大的帮助

    当然在应对短时间大流量写入的时候,我们也可以直接将数据写入 Redis,以达到快速存储数据、增加服务器应对流量能力的目的,等流量下去了再单独将数据写入 Mysql。


    简单介绍完了大体的架构组成,接下来我们来细看每个部分的细节:

    流量接入层

    流量接入层所做的就是对所有接受的流量进行处理,提供了以下服务:

    • 流量缓冲
    • 分流和转发

    • 超时检测

      • 与用户建立连接超时
      • 读取用户body超时
      • 连接后端超时
      • 读后端响应头超时
      • 写响应超时
      • 与用户长连接超时
    • 集群健康检查/隔离坏点服务器

      • 隔离坏点服务器并尝试修复/重启,直到该服务器恢复正常
    • 失败重试机制

      • 在请求转发到某集群某机器上,返回失败后,将该请求转发到该集群的别的机器,或者跨集群的机器上进行重试
    • 连接池/会话保持机制

      • 对于延迟敏感用户使用连接池机制,减少建立连接的时间
    • 安全防护
    • 数据分析

    当转发到各个产品线后就到了负载层工作的时候了:将请求根据情况转发到各地机房

    当然,这个平台并不止转发这一个功能,你可以把它理解为一个大型的私有云系统,提供以下服务:

    • 文件上传/服务线上部署
    • 线上配置修改
    • 设置定时任务
    • 线上系统监控/日志打印服务
    • 线上实例管理
    • 镜像中心
    • 等等...

    Node集群层

    这一层主要的工作是:

    (1)编写可靠的 Node 代码,为需求提供后端服务

    (2)编写高性能查询语句,与 Redis、Mysql 交互,提高查询效率

    (3)通过 Redis 同步集群里各个 Node 服务的状态

    (4)通过硬件管理平台,管理/监控物理机器的状态、管理IP地址等

    (当然这部分我只是粗浅地列列条目,还是需要时间来积累、深入理解)

    数据库层

    这一层主要的工作是:

    (1)创建 Mysql 并设计相关页、表;建立必要的索引、外键,提升查询便利性

    (2)部署 redis 并向 Node 层提供相应接口

    总结

    虽然 Node 的单线程特性给其提供的服务带来了许多问题,但只要我们积极面对这些问题,用合理的方法(如使用 child_process 等模块或构建分布式集群)去解决他们,发挥 Node 的各种优势,就可以享受到它所带来的好处!

    待更新:

    • Redis相关特性
    • sql查询性能指标 & 优化策略
    • Node内存监控 & 内存泄露排查/处理
    查看原文

    夜尽天明 发布了文章 · 今天 08:38

    10 个 GitHub 上超火的 CSS 奇技淫巧项目,找到写 CSS 的灵感!

    大家好,我是你们的 超级猫,一个不喜欢吃鱼、又不喜欢喵 的超级猫 ~

    如果 CSS 是女孩子,肯定如上图那样吧 ?? ~

    简介

    一般人没事的时候刷刷朋友圈、微博、电视剧、知乎,而有些人是没事的时候刷刷 GitHub ,看看最近有哪些流行的项目。

    久而久之,这差距就越来越大,因此总会有开源信息的不对称,有哪些优秀的前端开源项目值得学习的也不知道。

    初步前端与高级前端之间,最大的差距可能就是信息差造成的。

    超级猫从 2016 年加入 GitHub,到现在的 2020 年,快整整 5 个年头了。

    从 2018 年开始,我就养成了每天逛 GitHub 的习惯,一般在早上上班前或者中午午休的时候都会逛一下。

    看看每天都开源了哪些好的前端项目,还有用到的主流前端技术栈又是哪些,值得我去学习的。

    因此也收藏了不少好的开源项目,在此推荐给大家,每周会有一到三篇精华文章推送。

    希望你在浏览、学习了超级猫推荐的这些开源项目的过程中,你能学习到更多编程知识、提高编程技巧、找到编程的乐趣。

    公众号:前端GitHub,专注于挖掘 GitHub 上优秀的前端开源项目,抹平你的前端信息不对称,涵盖 JavaScript、Vue、React、Node、小程序、Flutter、Deno、HTML、CSS、数据结构与算法 等等。

    平时如何发现好的开源项目,可以看看这篇文章:GitHub 上能挖矿的神仙技巧 - 如何发现优秀开源项目


    以下为【前端GitHub】的第 7 期精华内容。

    今天给大家带来的是 GitHub 上超火的 10 个 CSS 项目,希望你在这里面找到写 CSS 的灵感!

    喵~ 喵~ 喵~ 正文开始了,上车坐稳扶好了~


    You-need-to-know-css

    该项目是 CSS 的各种效果实现,尤其是动画效果。

    笔者把自己的收获和工作中常用的一些 CSS 小样式总结成这份文档。

    目前文档一共包含 43 个 CSS 的小样式(持续更新…),所以还是很不错的学习 CSS 的项目来的。

    比如: 打字效果

    <style>
      main {
        width: 100%; height: 229px;
        display: flex;
        justify-content: center;
        align-items: center;
      }
      span {
        display: inline-block;
        width: 21ch;
        font: bold 200% Consolas, Monaco, monospace;   /*等宽字体*/
        overflow: hidden;
        white-space: nowrap;
        font-weight: 500;
        border-right: 1px solid transparent;
        animation: typing 10s steps(21), caret .5s steps(1) infinite;
      }
      @keyframes typing{
        from {
            width: 0;
        }
      }
      @keyframes caret{
        50% { border-right-color: currentColor}
      }
    </style>
    <template>
      <main class="main">
        <span>前端GitHub</span>
      </main>
    </template>
    <script>
    </script>
    https://lhammer.cn/You-need-to-know-css/#/zh-cn/

    CSS-Inspiration

    这里可以让你寻找到使用或者是学习 CSS 的灵感,以分类的形式,展示不同 CSS 属性或者不同的课题使用 CSS 来解决的各种方法。

    包含了:布局(Layout)、阴影(box-shadow、drop-shadow)、伪类/伪元素、滤镜(fliter)、边框(border)、背景/渐变(linear-gradient/radial-gradient/conic-gradient)、混合模式(mix-blend-mode/background-blend-mode)、3D、动画/过渡(transition/animation)、clip-path、文本类、综合、CSS-Doodle、SVG 等内容。

    比如:巧用 CSS 实现酷炫的充电动画

    https://github.com/chokcoco/CSS-Inspiration

    css_tricks

    该项目总结了一些常用的 CSS 样式,记录一些 CSS 的新属性和一点奇技淫巧。

    比如 提示气泡的效果

    <div class="poptip btn" aria-controls="弹出气泡">poptip</div>
    $poptipBg: #30363d;
    $color: #fff;
    $triangle: 8px;
    $distance: -12px;
    .poptip {
      position: relative;
      z-index: 101;
      &::before,
      &::after {
        visibility: hidden;
        opacity: 0;
        transform: translate3d(0, 0, 0);
        transition: all 0.3s ease 0.2s;
        box-sizing: border-box;
      }
      &::before {
        content: "";
        position: absolute;
        width: 0;
        height: 0;
        border-style: solid;
        border-width: $triangle $triangle 0 $triangle;
        border-color: $poptipBg transparent transparent transparent;
        left: calc(50% - #{$triangle});
        top: 0px;
        transform: translateX(0%) translateY($distance);
      }
    
      &::after {
        font-size: 14px;
        color: $color;
        content: attr(aria-controls);
        position: absolute;
        padding: 6px 12px;
        white-space: nowrap;
        z-index: -1;
        left: 50%;
        bottom: 100%;
        transform: translateX(-50%) translateY($distance);
        background: $poptipBg;
        line-height: 1;
        border-radius: 2px;
      }
      &:hover::before,
      &:hover::after {
        visibility: visible;
        opacity: 1;
      }
    }
    
    .btn {
      min-width: 100px;
      line-height: 1.5;
      padding: 5px 10px;
      color: #fff;
      background: #00adb5;
      border-radius: 4px;
      text-align: center;
      cursor: pointer;
    }

    效果:

    https://github.com/QiShaoXuan/css_tricks

    animista

    该项目里面有各种 CSS 实现的效果,还有代码演示,方便直接复制代码,还可以复制压缩后的代码,如果你在找某个 CSS 的效果的话,可以到这里找找看。

    http://animista.net/

    spinkit

    汇集了实现各种加载效果的 CSS 代码片段。

    SpinKit 仅使用(transformopacity)CSS 动画来创建平滑且易于自定义的动画。

    https://tobiasahlin.com/spinkit/

    十天精通 CSS3

    这是前端大佬大漠出的一个免费的 CSS3 教程,对于有一定 CSS2 经验的伙伴,能让您系统的学习 CSS3,快速的理解掌握并应用于工作之中。

    里面的内容有讲解,还有代码演习,学完之后,可以练习所学的 api ,真的很不错。

    超级猫入门前端时,也学习过里面的内容呢,虽然现在忘记的差不多了 ??,但是学过!。

    https://www.imooc.com/learn/33

    Animate

    是一个有趣的,跨浏览器的 css3 动画库,内置了很多典型的 css3 动画,兼容性好使用方便。

    animate.css 的使用非常简单,因为它是把不同的动画绑定到了不同的类里,所以想要使用哪种动画,只需要把通用类 animated 和相应的类添加到元素上就行了。

    做为一个前端开发,如果不知道这个库就真的很失败了。

    https://animate.style/

    sass

    Sass 是一种 CSS 的预编译语言,Sass 为 CSS 赋予了更强大的功能。

    它提供了?变量(variables)、嵌套(nested rules)?[混合(mixins)、函数(functions)等功能,并且完全兼容 CSS 语法。

    Sass 能够帮助复杂的样式表更有条理, 并且易于在项目内部或跨项目共享设计。

    https://sass.bootcss.com/documentation

    less

    Less 是一门 CSS 预处理语言,它扩展了 CSS 语言,增加了变量、Mixin、函数等特性。

    Less 可以运行在 Node 或浏览器端。

    https://less.bootcss.com/

    stylus

    富有表现力、动态、健壮的 CSS。

    它提供了一种高效,动态和表达方式来生成 CSS。同时支持缩进语法和常规 CSS 样式。

    https://stylus-lang.com/

    CSS 预处理器技术已经非常的成熟了,而且也涌现出了越来越多的 CSS 的预处理器框架。

    对于 sass 、less 和 stylus,都是在现在的 vue 和 react 项目中经常用到的,用法也很简单,只要学会一种,其他两种都很容易上手,项目中用哪一种就要看自己的喜欢了。

    最后

    最近加班有点严重,所有文章更新慢了很多,同是打工猫,生活不易啊!

    好了啦,【前端GitHub】的第 7 期内容已经讲完了啦。

    更多精彩内容请关注下方仓库:

    原文地址:https://github.com/FrontEndGitHub/FrontEndGitHub

    平时如何发现好的开源项目,可以看看这两篇文章:GitHub 上能挖矿的神仙技巧 - 如何发现优秀开源项目恕我直言,你可能连 GitHub 搜索都不会用 - 如何精准搜索的神仙技巧

    可以加超级猫的 wx:CB834301747 ,一起闲聊前端。

    觉得有用 ?喜欢就收藏,顺便点个赞吧,你的支持是我最大的鼓励!

    往期精文

    查看原文

    赞 25 收藏 21 评论 0

    夜尽天明 发布了文章 · 11月18日

    11 个 GitHub 上超火的前端面试项目,打造自己的加薪宝库!

    大家好,我是你们的 超级猫,一个不喜欢吃鱼、又不喜欢喵 的超级猫 ~

    简介

    一般人没事的时候刷刷朋友圈、微博、电视剧、知乎,而有些人是没事的时候刷刷 GitHub ,看看最近有哪些流行的项目。

    久而久之,这差距就越来越大,因此总会有开源信息的不对称,有哪些优秀的前端开源项目值得学习的也不知道。

    初步前端与高级前端之间,最大的差距可能就是信息差造成的。

    前端章鱼猫从 2016 年加入 GitHub,到现在的 2020 年,快整整 5 个年头了。

    从 2018 年开始,我就养成了每天逛 GitHub 的习惯,一般在早上上班前或者中午午休的时候都会逛一下。

    看看每天都开源了哪些好的前端项目,还有用到的主流前端技术栈又是哪些,值得我去学习的。

    因此也收藏了不少好的开源项目,在此推荐给大家,每周会有一到三篇精华文章推送。

    希望你在浏览、学习了前端章鱼猫推荐的这些开源项目的过程中,你能学习到更多编程知识、提高编程技巧、找到编程的乐趣。

    公众号:前端GitHub,专注于挖掘 GitHub 上优秀的前端开源项目,抹平你的前端信息不对称,涵盖 JavaScript、Vue、React、Node、小程序、Flutter、Deno、HTML、CSS、数据结构与算法 等等。

    以下为【前端GitHub】的第 6 期精华内容。

    今天给大家带来的是 GitHub 上超火的 10 个前端面试项目

    Front-end-Developer-Questions

    这个项目里面很多面试题,而且 star 数非常高,最大的缺点就是 没有答案!

    包含了:常见问题、HTML 相关问题、CSS 相关问题、JS 相关问题、测试相关问题、效能相关问题、网络相关问题、代码相关问题、趣味问题。

    比如 JS 相关问题:

    • 请解释事件代理 (event delegation)。
    • 请解释 JavaScript 中?this?是如何工作的。
    • 请解释原型继承 (prototypal inheritance) 的原理。
    • 你怎么看 AMD vs. CommonJS?
    • 请解释为什么接下来这段代码不是 IIFE (立即调用的函数表达式):function foo(){ }();,要做哪些改动使它变成 IIFE?
    • 描述以下变量的区别:nullundefined?或?undeclared?该如何检测它们?
    • 什么是闭包 (closure),如何使用它,为什么要使用它?
    • 请举出一个匿名函数的典型用例?
    • 你是如何组织自己的代码?是使用模块模式,还是使用经典继承的方法?

    超级猫 觉得可以作为前端自检清单吧。

    ?https://h5bp.org/Front-end-Developer-Interview-Questions/

    javascript-questions

    JavaScript 进阶问题列表

    从基础到进阶,测试你有多了解 JavaScript,刷新你的知识,或者帮助你的 coding 面试! ?? ?? 我每周都会在这个仓库下更新新的问题。

    https://github.com/lydiahalli...

    Daily-Question

    这是山月大佬整理的:互联网大厂内推及大厂面经整理,并且每天一道面试题推送。每天五分钟,半年大厂中。

    每天至少一个问题,有关前后端,DevOps,微服务以及软技能,促进个人职业成长。

    https://github.com/shfshanyue/Daily-Question

    还有 掘金前端面试题合集

    用简单的命令爬取了掘金的面试集合榜单,还是挺全的。

    https://github.com/shfshanyue/blog/blob/master/post/juejin-interview.md

    CS-Interview-Knowledge-Map

    这是小册作者 yck 大佬花了半年的时间做了一个这个开源项目。在半年的时间里,收集了大量的一线大厂面试题,通过大数据统计出了近百个常考知识点,然后根据这些知识点写成了近十万字的内容。

    目前的内容包括 js、网络、浏览器相关、性能优化、安全性、框架、git、数据结构、算法等。

    https://github.com/InterviewMap/CS-Interview-Knowledge-Map

    Daily-Interview-Question

    每天搞定一道前端大厂面试题,祝大家天天进步,一年后会看到不一样的自己。

    这项目的问题,很多同学参与回答,内容也很新,作为每日突击的学习,很适合准备跳槽的同学。

    https://github.com/Advanced-Frontend/Daily-Interview-Question

    fe-interview

    这是一份作者总结的关于准备前端面试的一个复习汇总项目,项目不定时更新。

    这不仅仅是一份用于求职面试的攻略,也是一份前端 er 用来检视自己,实现突破的宝典。

    希望通过这个指南,大家可以打通自己的任督二脉,在前端的路上更进一步。

    本仓库大量采用图的形式来传达知识,所谓一图胜千言,希望通过这种图文并茂的表达方式让你更容易记住一些抽象,难以理解的概念。

    https://lucifer.ren/fe-interview

    fe-interview

    该专题的面试内容包含:HTML + CSS + JS + ES6 + Webpack + Vue + React + Node + HTTPS + 数据结构与算法 + Git ,内容还是比较齐全的。

    复习前端面试的知识,是为了巩固前端的基础知识,最重要的还是平时的积累!

    内容大概是一年前了,内容都在一个 readme 文件里面,阅读不是很方便。

    https://github.com/biaochenxu...

    fe-interview

    这是一个涉及前端知识题库 最多(3000+)、最全,参与人数最多的免费开源项目!

    前端面试每日 3+1,以面试题来驱动学习,提倡每日学习与思考,每天进步一点!每天早上 5 点纯手工发布面试题(死磕自己,愉悦大家)。

    https://github.com/haizlin/fe-interview

    node-interview

    该项目的目的是教你如何通过饿了么大前端的面试, 职位是 2~3 年经验的 Node.js 服务端程序员 (并不是全栈)。

    需要注意的是, 该项目针对的并不是零基础的同学, 你需要有一定的 JavaScript/Node.js 基础, 并且有一定的工作经验. 另外该项目的重点更准确的说是服务端基础中 Node.js 程序员需要了解的部分。

    https://github.com/ElemeFE/node-interview/tree/master/sections/zh-cn

    Front-End-Interview-Notebook

    这个仓库是笔者校招时的前端复习笔记,主要总结一些比较重要的知识点和前端面试问题,对大家应该有所帮助。

    https://github.com/CavsZhouyou/Front-End-Interview-Notebook

    FE-Interview

    每天 get 一个知识点。

    前端面试必备题库,1000+ 面试真题,Html、Css、JavaScript、Vue、React、Node、TypeScript、Webpack、算法、网络与安全、浏览器。

    https://github.com/lgwebdream/FE-Interview

    更多

    更多前端面试开源项目 ...

    https://github.com/search?o=desc&p=1&q=%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95&s=&type=Repositories

    最后

    好了,【前端GitHub】的第 6 期内容已经讲完了,更多精彩请看下方仓库地址:

    原文地址:https://github.com/FrontEndGitHub/FrontEndGitHub

    平时如何发现好的开源项目,可以看看这篇文章:GitHub 上能挖矿的神仙技巧 - 如何发现优秀开源项目恕我直言,你可能连 GitHub 搜索都不会用 - 如何精准搜索的神仙技巧

    可以加超级猫的 wx:CB834301747 ,一起闲聊前端GitHub。

    觉得有用 ?喜欢就收藏,顺便点个赞吧,你的支持是我最大的鼓励!

    微信搜 “前端GitHub”,回复 “电子书” 即可以获得 160 本前端精华书籍哦。

    往期精文

    点此评论及推荐好的开源项目哦!

    查看原文

    赞 41 收藏 37 评论 1

    夜尽天明 发布了文章 · 11月11日

    推荐几个大厂的前端代码规范,学会了,你也能写出诗一样的代码!

    大家好,我是你们的 前端章鱼猫,一个不喜欢吃鱼、又不喜欢喵 的超级猫 ~

    简介

    前端章鱼猫从 2016 年加入 GitHub,到现在的 2020 年,快整整 5 个年头了。

    相信很多人都没有逛 GitHub 的习惯,因此总会有开源信息的不对称,有哪些优秀的前端开源项目值得学习的也不知道。

    初步前端与高级前端之间,最大的差距可能就是信息差造成的。

    从 2018 年开始,我就养成了每天逛 GitHub 的习惯,一般在早上上班前或者中午午休的时候都会逛一下。

    看看每天都开源了哪些好的前端项目,还有用到的主流前端技术栈又是哪些,值得我去学习的。

    因此也收藏了不少好的开源项目,在此推荐给大家,每周会有一到三篇精华文章推送。

    希望你在浏览、学习了前端章鱼猫推荐的这些开源项目的过程中,你能学习到更多编程知识、提高编程技巧、找到编程的乐趣。

    公众号:前端GitHub,专注于挖掘 GitHub 上优秀的前端开源项目,抹平你的前端信息不对称,涵盖 JavaScript、Vue、React、Node、小程序、Flutter、Deno、HTML、CSS、数据结构与算法 等等。

    以下为【前端GitHub】的第 5 期内容。

    今天给大家带来的是 几个大厂的前端代码规范

    前端代码规范?

    代码千万行,安全第一行;前端不规范,同事两行泪。

    腾讯

    包含内容也挺多的:

    PC端专题:快速上手、文件目录、页面头部、通用title、通用foot、统计代码、兼容测试

    移动端专题:快速上手、文件目录、页面头部、REM布局、通用foot、统计代码、分享组件、兼容要求

    双端官网:快速上手、页面跳转

    http://tgideas.qq.com/doc/index.html

    不过里面也有一些内容是针对其业务的,并不通用。

    京东

    对比腾讯的代码规范,我更推荐凹凸实验室的代码规范,比较齐全。

    HTML规范

    基于W3C、苹果开发者等官方文档,并结合团队日常业务需求以及团队在日常开发过程中总结提炼出的经验而约定。

    图片规范

    了解各种图片格式特性,根据特性制定图片规范,包括但不限于图片的质量约定、图片引入方式、图片合并处理等。

    CSS 规范

    统一团队 CSS 代码书写和 SASS 预编译语言的语法风格,提供常用媒体查询语句和浏览器私有属性引用,并从业务层面统一规范常用模块的引用。

    命名规范

    从 “目录命名”、“图片命名”、“ClassName” 命名等层面约定规范团队的命名习惯,增强团队代码的可读性。

    JavaScript 规范

    统一团队的 JS 语法风格和书写习惯,减少程序出错的概率,其中也包含了 ES6 的语法规范和最佳实践。

    凹凸实验室:https://guide.aotu.io/index.html

    阿里巴巴

    包含了:类型、对象、数组、字符串、函数、属性、变量、提升、比较运算符 & 等号、块、注释、空白、逗号、分号、类型转化、命名规则、存取器、构造函数、事件、模块、jQuery、ECMAScript 5 兼容性、测试、性能、资源、JavaScript 风格指南说明

    Airbnb Javascript Style Guide:https://github.com/airbnb/javascript

    百度

    JavaScript编码规范、HTML、CSS、Less、E-JSON 数据传输标准、模块和加载器、包结构、项目目录结构、图表库标准、react 编码规范。

    比如:缩进

    • [强制] 使用?4?个空格做为一个缩进层级,不允许使用?2?个空格 或?tab?字符。
    • [强制]?switch?下的?case?和?default?必须增加一个缩进层级。
    // good
    switch (variable) {
    
        case '1':
            // do...
            break;
    
        case '2':
            // do...
            break;
    
        default:
            // do...
    
    }
    
    // bad
    switch (variable) {
    
    case '1':
        // do...
        break;
    
    case '2':
        // do...
        break;
    
    default:
        // do...
    
    }
    规范文档:https://github.com/ecomfe/spec/blob/master/javascript-style-guide.md

    网易编码规范:

    CSS规范:一系列规则和方法,帮助你架构并管理好样式

    HTML规范:一系列建议和方法,帮助你搭建简洁严谨的结构

    工程师规范:前端页面开发工程师的工作流程和团队协作规范

    但是并不止于此,还有更多:

    http://nec.netease.com/standard

    JavaScript Standard Style

    除很多公司组织外,很多个人也在项目中使用的规范。

    https://github.com/standard/standard

    Vue

    这里是官方的 Vue 特有代码的风格指南。

    如果在工程中使用 Vue,为了回避错误、小纠结和反模式,该指南是份不错的参考。

    不过我们也不确信风格指南的所有内容对于所有的团队或工程都是理想的。

    所以根据过去的经验、周围的技术栈、个人价值观做出有意义的偏差是可取的。

    官方风格指南:?https://cn.vuejs.org/v2/style-guide/index.html

    es6

    如何将 ES6 的新语法,运用到编码实践之中,与传统的 JavaScript 语法结合在一起,写出合理的、易于阅读和维护的代码。

    es6 编程风格:http://es6.ruanyifeng.com/#docs/style

    Bootstrap

    内容包含 HTML 和 CSS。

    HTML

    语法、HTML5 doctype、语言属性、IE 兼容模式、字符编码、引入 CSS 和 JavaScript 文件、实用为王、属性顺序、布尔型属性、减少标签的数量、JavaScript 生成的标签。

    CSS

    语法、声明顺序、不要使用 @import、媒体查询(Media query)的位置、带前缀的属性、单行规则声明、简写形式的属性声明、Less 和 Sass 中的嵌套、Less 和 Sass 中的操作符、注释、class 命名、选择器、代码组织。

    Bootstrap 编码规范:https://codeguide.bootcss.com/

    ESLint

    目前绝大多数前端项目都会用到的 可组装的 JavaScrip t和 JSX 检查工具。

    发现问题

    ESLint 静态分析您的代码以快速发现问题。ESLint 内置于大多数文本编辑器中,您可以将ESLint 作为持续集成管道的一部分运行。

    自动修复

    ESLint 发现的许多问题都可以自动修复。ESLint 修复程序可识别语法,因此您不会遇到传统的查找和替换算法引入的错误。

    定制

    预处理代码,使用自定义解析器,并编写与 ESLint 内置规则一起使用的自己的规则。您可以自定义 ESLint,使其完全按照项目所需的方式工作。

    ESLint: https://eslint.org/

    ESLint 中文网:https://eslint.bootcss.com/

    Prettier

    Prettier 是一个“有主见”的代码格式化工具。

    简而言之,这个工具能够使输出代码保持风格一致。

    也是目前绝大多数前端项目都会用到的哦。

    Prettier:https://prettier.io/

    最后

    好了,【前端GitHub】的第 5 期内容已经讲完了,更多精彩请看下方仓库地址:

    原文地址:https://github.com/FrontEndGitHub/FrontEndGitHub

    平时如何发现好的开源项目,可以看看这两篇文章:GitHub 上能挖矿的神仙技巧 - 如何发现优秀开源项目恕我直言,你可能连 GitHub 搜索都不会用 - 如何精准搜索的神仙技巧

    觉得有用 ?喜欢就收藏,顺便点个赞吧,你的支持是我最大的鼓励!

    微信搜 “前端GitHub”,回复 “电子书” 即可以获得 160 本前端精华书籍哦。

    往期精文

    查看原文

    赞 23 收藏 19 评论 0

    夜尽天明 收藏了文章 · 11月5日

    前端都该懂的浏览器工作原理,你懂了吗?

    前言

    在我们面试过程中,面试官经常会问到这么一个问题,那就是从在浏览器地址栏中输入URL到页面显示,浏览器到底发生了什么?这个问题看起来是老生常谈,但是这个问题回答的好坏,确实可以很好的反映出面试者知识的广度和深度。

    本文从浏览器角度来告诉你,URL后输入后按回车,浏览器内部究竟发生了什么,读完本文后,你将了解到:

    • 浏览器内有哪些进程,这些进程都有些什么作用
    • 浏览器地址输入URL后,内部的进程、线程都做了哪些事
    • 我们与浏览器交互时,内部进程是怎么处理这些交互事件的

    原文地址 欢迎star

    浏览器架构

    在讲浏览器架构之前,先理解两个概念,进程线程

    进程(process)是程序的一次执行过程,是一个动态概念,是程序在执行过程中分配和管理资源的基本单位,线程(thread)是CPU调度和分派的基本单位,它可与同属一个进程的其他的线程共享进程所拥有的全部资源。

    简单的说呢,进程可以理解成正在执行的应用程序,而线程呢,可以理解成我们应用程序中的代码的执行器。而他们的关系可想而知,线程是跑在进程里面的,一个进程里面可能有一个或者多个线程,而一个线程,只能隶属于一个进程。

    大家都知道,浏览器属于一个应用程序,而应用程序的一次执行,可以理解为计算机启动了一个进程,进程启动后,CPU会给该进程分配相应的内存空间,当我们的进程得到了内存之后,就可以使用线程进行资源调度,进而完成我们应用程序的功能。

    而在应用程序中,为了满足功能的需要,启动的进程会创建另外的新的进程来处理其他任务,这些创建出来的新的进程拥有全新的独立的内存空间,不能与原来的进程内向内存,如果这些进程之间需要通信,可以通过IPC机制(Inter Process Communication)来进行。

    进程1

    很多应用程序都会采取这种多进程的方式来工作,因为进程和进程之间是互相独立的它们互不影响,也就是说,当其中一个进程挂掉了之后,不会影响到其他进程的执行,只需要重启挂掉的进程就可以恢复运行。

    浏览器的多进程架构

    假如我们去开发一个浏览器,它的架构可以是一个单进程多线程的应用程序,也可以是一个使用IPC通信的多进程应用程序。

    不同的浏览器使用不同的架构,下面主要以Chrome为例,介绍浏览器的多进程架构。

    在Chrome中,主要的进程有4个:

    • 浏览器进程 (Browser Process):负责浏览器的TAB的前进、后退、地址栏、书签栏的工作和处理浏览器的一些不可见的底层操作,比如网络请求和文件访问。
    • 渲染进程 (Renderer Process):负责一个Tab内的显示相关的工作,也称渲染引擎。
    • 插件进程 (Plugin Process):负责控制网页使用到的插件
    • GPU进程 (GPU Process):负责处理整个应用程序的GPU任务

    进程关系

    这4个进程之间的关系是什么呢?

    首先,当我们是要浏览一个网页,我们会在浏览器的地址栏里输入URL,这个时候Browser Process会向这个URL发送请求,获取这个URL的HTML内容,然后将HTML交给Renderer ProcessRenderer Process解析HTML内容,解析遇到需要请求网络的资源又返回来交给Browser Process进行加载,同时通知Browser Process,需要Plugin Process加载插件资源,执行插件代码。解析完成后,Renderer Process计算得到图像帧,并将这些图像帧交给GPU ProcessGPU Process将其转化为图像显示屏幕。

    进程关系

    多进程架构的好处

    Chrome为什么要使用多进程架构呢?

    第一,更高的容错性。当今WEB应用中,HTML,JavaScript和CSS日益复杂,这些跑在渲染引擎的代码,频繁的出现BUG,而有些BUG会直接导致渲染引擎崩溃,多进程架构使得每一个渲染引擎运行在各自的进程中,相互之间不受影响,也就是说,当其中一个页面崩溃挂掉之后,其他页面还可以正常的运行不收影响。

    浏览器容错性

    第二,更高的安全性和沙盒性(sanboxing)。渲染引擎会经常性的在网络上遇到不可信、甚至是恶意的代码,它们会利用这些漏洞在你的电脑上安装恶意的软件,针对这一问题,浏览器对不同进程限制了不同的权限,并为其提供沙盒运行环境,使其更安全更可靠

    第三,更高的响应速度。在单进程的架构中,各个任务相互竞争抢夺CPU资源,使得浏览器响应速度变慢,而多进程架构正好规避了这一缺点。

    多进程架构优化

    之前的我们说到,Renderer Process的作用是负责一个Tab内的显示相关的工作,这就意味着,一个Tab,就会有一个Renderer Process,这些进程之间的内存无法进行共享,而不同进程的内存常常需要包含相同的内容。

    浏览器的进程模式

    为了节省内存,Chrome提供了四种进程模式(Process Models),不同的进程模式会对 tab 进程做不同的处理。

    • Process-per-site-instance (default) - 同一个 site-instance 使用一个进程
    • Process-per-site - 同一个 site 使用一个进程
    • Process-per-tab - 每个 tab 使用一个进程
    • Single process - 所有 tab 共用一个进程

    这里需要给出 site 和 site-instance 的定义

    • site 指的是相同的 registered domain name(如: google.com ,bbc.co.uk)和scheme (如:https://)。比如a.baidu.com和b.baidu.com就可以理解为同一个 site(注意这里要和 Same-origin policy 区分开来,同源策略还涉及到子域名和端口)。
    • site-instance 指的是一组 connected pages from the same site,这里 connected 的定义是 can obtain references to each other in script code 怎么理解这段话呢。满足下面两中情况并且打开的新页面和旧页面属于上面定义的同一个 site,就属于同一个 site-instance

      • 用户通过<a target="_blank">这种方式点击打开的新页面
      • JS代码打开的新页面(比如 window.open)

    理解了概念之后,下面解释四个进程模式

    首先是Single process,顾名思义,单进程模式,所有tab都会使用同一个进程。接下来是Process-per-tab ,也是顾名思义,每打开一个tab,会新建一个进程。而对于Process-per-site,当你打开 a.baidu.com 页面,在打开 b.baidu.com 的页面,这两个页面的tab使用的是共一个进程,因为这两个页面的site相同,而如此一来,如果其中一个tab崩溃了,而另一个tab也会崩溃。

    Process-per-site-instance 是最重要的,因为这个是 Chrome 默认使用的模式,也就是几乎所有的用户都在用的模式。当你打开一个 tab 访问 a.baidu.com ,然后再打开一个 tab 访问 b.baidu.com,这两个 tab 会使用两个进程。而如果你在 a.baidu.com 中,通过JS代码打开了 b.baidu.com 页面,这两个 tab 会使用同一个进程

    默认模式选择

    那么为什么浏览器使用Process-per-site-instance作为默认的进程模式呢?

    Process-per-site-instance兼容了性能与易用性,是一个比较中庸通用的模式。

    • 相较于 Process-per-tab,能够少开很多进程,就意味着更少的内存占用
    • 相较于 Process-per-site,能够更好的隔离相同域名下毫无关联的 tab,更加安全

    导航过程都发生了什么

    前面我们讲了浏览器的多进程架构,讲了多进程架构的各种好处,和Chrome是怎么优化多进程架构的,下面从用户浏览网页这一简单的场景,来深入了解进程和线程是如何呈现我们的网站页面的。

    网页加载过程

    之前我们我们提到,tab以外的大部分工作由浏览器进程Browser Process负责,针对工作的不同,Browser Process 划分出不同的工作线程:

    • UI thread:控制浏览器上的按钮及输入框;
    • network thread:处理网络请求,从网上获取数据;
    • storage thread: 控制文件等的访问;

    浏览器进程线程

    第一步:处理输入

    当我们在浏览器的地址栏输入内容按下回车时,UI thread会判断输入的内容是搜索关键词(search query)还是URL,如果是搜索关键词,跳转至默认搜索引擎对应都搜索URL,如果输入的内容是URL,则开始请求URL。

    处理输入

    第二步:开始导航

    回车按下后,UI thread将关键词搜索对应的URL或输入的URL交给网络线程Network thread,此时UI线程使Tab前的图标展示为加载中状态,然后网络进程进行一系列诸如DNS寻址,建立TLS连接等操作进行资源请求,如果收到服务器的301重定向响应,它就会告知UI线程进行重定向然后它会再次发起一个新的网络请求。

    开始导航

    第三步:读取响应

    network thread接收到服务器的响应后,开始解析HTTP响应报文,然后根据响应头中的Content-Type字段来确定响应主体的媒体类型(MIME Type),如果媒体类型是一个HTML文件,则将响应数据交给渲染进程(renderer process)来进行下一步的工作,如果是 zip 文件或者其它文件,会把相关数据传输给下载管理器。

    与此同时,浏览器会进行 Safe Browsing 安全检查,如果域名或者请求内容匹配到已知的恶意站点,network thread 会展示一个警告页。除此之外,网络线程还会做 CORB(Cross Origin Read Blocking)检查来确定那些敏感的跨站数据不会被发送至渲染进程。

    第四步:查找渲染进程

    各种检查完毕以后,network thread 确信浏览器可以导航到请求网页,network thread 会通知 UI thread 数据已经准备好,UI thread 会查找到一个 renderer process 进行网页的渲染。

    查找渲染进程

    浏览器为了对查找渲染进程这一步骤进行优化,考虑到网络请求获取响应需要时间,所以在第二步开始,浏览器已经预先查找和启动了一个渲染进程,如果中间步骤一切顺利,当 network thread 接收到数据时,渲染进程已经准备好了,但是如果遇到重定向,这个准备好的渲染进程也许就不可用了,这个时候会重新启动一个渲染进程。

    第五步:提交导航

    到了这一步,数据和渲染进程都准备好了,Browser Process 会向 Renderer Process 发送IPC消息来确认导航,此时,浏览器进程将准备好的数据发送给渲染进程,渲染进程接收到数据之后,又发送IPC消息给浏览器进程,告诉浏览器进程导航已经提交了,页面开始加载。

    提交导航

    这个时候导航栏会更新,安全指示符更新(地址前面的小锁),访问历史列表(history tab)更新,即可以通过前进后退来切换该页面。

    第六步:初始化加载完成

    当导航提交完成后,渲染进程开始加载资源及渲染页面(详细内容下文介绍),当页面渲染完成后(页面及内部的iframe都触发了onload事件),会向浏览器进程发送IPC消息,告知浏览器进程,这个时候UI thread会停止展示tab中的加载中图标。

    网页渲染原理

    导航过程完成之后,浏览器进程把数据交给了渲染进程,渲染进程负责tab内的所有事情,核心目的就是将HTML/CSS/JS代码,转化为用户可进行交互的web页面。那么渲染进程是如何工作的呢?

    渲染进程中,包含线程分别是:

    • 一个主线程(main thread)
    • 多个工作线程(work thread)
    • 一个合成器线程(compositor thread)
    • 多个光栅化线程(raster thread)

    浏览器进程中线程

    不同的线程,有着不同的工作职责。

    构建DOM

    当渲染进程接受到导航的确认信息后,开始接受来自浏览器进程的数据,这个时候,主线程会解析数据转化为DOM(Document Object Model)对象。

    DOM为WEB开发人员通过JavaScript与网页进行交互的数据结构及API。

    子资源加载

    在构建DOM的过程中,会解析到图片、CSS、JavaScript脚本等资源,这些资源是需要从网络或者缓存中获取的,主线程在构建DOM过程中如果遇到了这些资源,逐一发起请求去获取,而为了提升效率,浏览器也会运行预加载扫描(preload scanner)程序,如果HTML中存在imglink等标签,预加载扫描程序会把这些请求传递给Browser Process的network thread进行资源下载。

    加载子资源

    JavaScript的下载与执行

    构建DOM过程中,如果遇到<script>标签,渲染引擎会停止对HTML的解析,而去加载执行JS代码,原因在于JS代码可能会改变DOM的结构(比如执行document.write()等API)

    不过开发者其实也有多种方式来告知浏览器应对如何应对某个资源,比如说如果在<script> 标签上添加了 asyncdefer 等属性,浏览器会异步的加载和执行JS代码,而不会阻塞渲染。

    样式计算 - Style calculation

    DOM树只是我们页面的结构,我们要知道页面长什么样子,我们还需要知道DOM的每一个节点的样式。主线程在解析页面时,遇到<style>标签或者<link>标签的CSS资源,会加载CSS代码,根据CSS代码确定每个DOM节点的计算样式(computed style)。

    计算样式是主线程根据CSS样式选择器(CSS selectors)计算出的每个DOM元素应该具备的具体样式,即使你的页面没有设置任何自定义的样式,浏览器也会提供其默认的样式。

    样式计算

    布局 - Layout

    DOM树和计算样式完成后,我们还需要知道每一个节点在页面上的位置,布局(Layout)其实就是找到所有元素的几何关系的过程。

    主线程会遍历DOM 及相关元素的计算样式,构建出包含每个元素的页面坐标信息及盒子模型大小的布局树(Render Tree),遍历过程中,会跳过隐藏的元素(display: none),另外,伪元素虽然在DOM上不可见,但是在布局树上是可见的。

    layout

    绘制 - Paint

    布局 layout 之后,我们知道了不同元素的结构,样式,几何关系,我们要绘制出一个页面,我们要需要知道每个元素的绘制先后顺序,在绘制阶段,主线程会遍历布局树(layout tree),生成一系列的绘画记录(paint records)。绘画记录可以看做是记录各元素绘制先后顺序的笔记。

    paint

    合成 - Compositing

    文档结构、元素的样式、元素的几何关系、绘画顺序,这些信息我们都有了,这个时候如果要绘制一个页面,我们需要做的是把这些信息转化为显示器中的像素,这个转化的过程,叫做光栅化(rasterizing)。

    那我们要绘制一个页面,最简单的做法是只光栅化视口内(viewport)的网页内容,如果用户进行了页面滚动,就移动光栅帧(rastered frame)并且光栅化更多的内容以补上页面缺失的部分,如下:

    最简单的光栅化过程

    Chrome第一个版本就是采用这种简单的绘制方式,这一方式唯一的缺点就是每当页面滚动,光栅线程都需要对新移进视图的内容进行光栅化,这是一定的性能损耗,为了优化这种情况,Chrome采取一种更加复杂的叫做合成(compositing)的做法。

    那么,什么是合成?合成是一种将页面分成若干层,然后分别对它们进行光栅化,最后在一个单独的线程 - 合成线程(compositor thread)里面合并成一个页面的技术。当用户滚动页面时,由于页面各个层都已经被光栅化了,浏览器需要做的只是合成一个新的帧来展示滚动后的效果罢了。页面的动画效果实现也是类似,将页面上的层进行移动并构建出一个新的帧即可。

    合成的光栅化过程

    为了实现合成技术,我们需要对元素进行分层,确定哪些元素需要放置在哪一层,主线程需要遍历渲染树来创建一棵层次树(Layer Tree),对于添加了 will-change CSS 属性的元素,会被看做单独的一层,没有 will-change CSS属性的元素,浏览器会根据情况决定是否要把该元素放在单独的层。

    layer tree

    你可能会想要给页面上所有的元素一个单独的层,然而当页面的层超过一定的数量后,层的合成操作要比在每个帧中光栅化页面的一小部分还要慢,因此衡量你应用的渲染性能是十分重要的一件事情。

    一旦Layer Tree被创建,渲染顺序被确定,主线程会把这些信息通知给合成器线程,合成器线程开始对层次数的每一层进行光栅化。有的层的可以达到整个页面的大小,所以合成线程需要将它们切分为一块又一块的小图块(tiles),之后将这些小图块分别进行发送给一系列光栅线程(raster threads)进行光栅化,结束后光栅线程会将每个图块的光栅结果存在GPU Process的内存中。

    光栅线程创建图块的位图并发送给GPU

    为了优化显示体验,合成线程可以给不同的光栅线程赋予不同的优先级,将那些在视口中的或者视口附近的层先被光栅化。

    当图层上面的图块都被栅格化后,合成线程会收集图块上面叫做绘画四边形(draw quads)的信息来构建一个合成帧(compositor frame)。

    • 绘画四边形:包含图块在内存的位置以及图层合成后图块在页面的位置之类的信息。
    • 合成帧:代表页面一个帧的内容的绘制四边形集合

    以上所有步骤完成后,合成线程就会通过IPC向浏览器进程(browser process)提交(commit)一个渲染帧。这个时候可能有另外一个合成帧被浏览器进程的UI线程(UI thread)提交以改变浏览器的UI。这些合成帧都会被发送给GPU从而展示在屏幕上。如果合成线程收到页面滚动的事件,合成线程会构建另外一个合成帧发送给GPU来更新页面。

    合成线程构建出合成帧,合成帧会被发送给浏览器进程然后再发送给GPU

    合成的好处在于这个过程没有涉及到主线程,所以合成线程不需要等待样式的计算以及JavaScript完成执行。这就是为什么合成器相关的动画最流畅,如果某个动画涉及到布局或者绘制的调整,就会涉及到主线程的重新计算,自然会慢很多。

    浏览器对事件的处理

    当页面渲染完毕以后,TAB内已经显示出了可交互的WEB页面,用户可以进行移动鼠标、点击页面等操作了,而当这些事件发生时候,浏览器是如何处理这些事件的呢?

    以点击事件(click event)为例,让鼠标点击页面时候,首先接受到事件信息的是Browser Process,但是Browser Process只知道事件发生的类型和发生的位置,具体怎么对这个点击事件进行处理,还是由Tab内的Renderer Process进行的。Browser Process接受到事件后,随后便把事件的信息传递给了渲染进程,渲染进程会找到根据事件发生的坐标,找到目标对象(target),并且运行这个目标对象的点击事件绑定的监听函数(listener)。

    点击事件从浏览器进程路由到渲染进程

    渲染进程中合成器线程接收事件

    前面我们说到,合成器线程可以独立于主线程之外通过已光栅化的层创建组合帧,例如页面滚动,如果没有对页面滚动绑定相关的事件,组合器线程可以独立于主线程创建组合帧,如果页面绑定了页面滚动事件,合成器线程会等待主线程进行事件处理后才会创建组合帧。那么,合成器线程是如何判断出这个事件是否需要路由给主线程处理的呢?

    由于执行 JS 是主线程的工作,当页面合成时,合成器线程会标记页面中绑定有事件处理器的区域为非快速滚动区域(non-fast scrollable region),如果事件发生在这些存在标注的区域,合成器线程会把事件信息发送给主线程,等待主线程进行事件处理,如果事件不是发生在这些区域,合成器线程则会直接合成新的帧而不用等到主线程的响应。

    非快速滚动区域有用户事件发生

    而对于非快速滚动区域的标记,开发者需要注意全局事件的绑定,比如我们使用事件委托,将目标元素的事件交给根元素body进行处理,代码如下:

    document.body.addEventListener('touchstart', event => {
      if (event.target === area) {
        event.preventDefault()
      }
    })

    在开发者角度看,这一段代码没什么问题,但是从浏览器角度看,这一段代码给body元素绑定了事件监听器,也就意味着整个页面都被编辑为一个非快速滚动区域,这会使得即使你的页面的某些区域没有绑定任何事件,每次用户触发事件时,合成器线程也需要和主线程通信并等待反馈,流畅的合成器独立处理合成帧的模式就失效了。

    当整个页面都是非快速滚动区域时页面的事件处理示意图

    其实这种情况也很好处理,只需要在事件监听时传递passtive参数为 true,passtive会告诉浏览器你既要绑定事件,又要让组合器线程直接跳过主线程的事件处理直接合成创建组合帧。

    document.body.addEventListener('touchstart', ?event => {
        if (event.target === area) {
            event.preventDefault()
        }
     }, {passive: true});

    查找事件的目标对象(event target)

    当合成器线程接收到事件信息,判定到事件发生不在非快速滚动区域后,合成器线程会向主线程发送这个时间信息,主线程获取到事件信息的第一件事就是通过命中测试(hit test)去找到事件的目标对象。具体的命中测试流程是遍历在绘制阶段生成的绘画记录(paint records)来找到包含了事件发生坐标上的元素对象。

    当整个页面都是非快速滚动区域时页面的事件处理示意图

    浏览器对事件的优化

    一般我们屏幕的帧率是每秒60帧,也就是60fps,但是某些事件触发的频率超过了这个数值,比如wheel,mousewheel,mousemove,pointermove,touchmove,这些连续性的事件一般每秒会触发60~120次,假如每一次触发事件都将事件发送到主线程处理,由于屏幕的刷新速率相对来说较低,这样使得主线程会触发过量的命中测试以及JS代码,使得性能有了没必要是损耗。

    事件淹没了屏幕刷新的时间轴,导致页面很卡顿

    出于优化的目的,浏览器会合并这些连续的事件,延迟到下一帧渲染是执行,也就是requestAnimationFrame之前。

    和之前相同的事件轴,可是这次事件被合并并延迟调度了

    而对于非连续性的事件,如keydown,keyup,mousedown,mouseup,touchstart,touchend等,会直接派发给主线程去执行。

    总结

    浏览器的多进程架构,根据不同的功能划分了不同的进程,进程内不同的使命划分了不同的线程,当用户开始浏览网页时候,浏览器进程进行处理输入、开始导航请求数据、请求响应数据,查找新建渲染进程,提交导航,之后渲染又进行了解析HTML构建DOM、构建过程加载子资源、下载并执行JS代码、样式计算、布局、绘制、合成,一步一步的构建出一个可交互的WEB页面,之后浏览器进程又接受页面的交互事件信息,并将其交给渲染进程,渲染进程内主进程进行命中测试,查找目标元素并执行绑定的事件,完成页面的交互。

    本文大部分内容也是对inside look at modern web browser系列文章的整理、解读和翻译吧,整理过程还是收获非常大的,希望读者读了本文只有有所启发吧。

    相关参考链接

    查看原文

    夜尽天明 发布了文章 · 11月4日

    恕我直言,你可能连 GitHub 搜索都不会用 - 如何精准搜索的神仙技巧

    大家好,我是你们的 前端章鱼猫,一个不喜欢喵、又不喜欢吃鱼的超级猫 ~

    今天给大家带来的是 在 GitHub 上如何精准搜索的神仙技巧

    【前端GitHub】,专注于挖掘 GitHub 上优秀的前端开源项目,抹平你的前端信息不对称,涵盖 JavaScript、Vue、React、Node、小程序、Flutter、Deno、HTML、CSS、数据结构与算法 等等。

    [前端GitHub] 地址:https://github.com/biaochenxu...

    以下为【前端GitHub】的第 4 期内容。

    普通的搜索

    相信一般人搜索项目时,都是直接搜索技术栈相关的项目。

    高级一点的搜索,会根据 最匹配、最多 Star 来进行排序、选择相应的语言、选择仓库或者代码来进行筛选。

    但是 GitHub 的搜索功能只支持以上这些而已吗 ?

    No!

    如果你只会用以上的功能,那你知道的仅仅是 GitHub 搜索的冰山一角!

    GitHub 的搜索是非常强大的!下面介绍更高级的搜索技巧。

    搜索语法

    搜索 GitHub 时,你可以构建匹配特定数字和单词的查询。

    查询大于或小于另一个值的值

    您可以使用?>>=<?和?<=?搜索大于、大于等于、小于以及小于等于另一个值的值。

    查询示例
    >*n*cats vue:>1000?匹配含有 "vue" 字样、星标超过 1000 个的仓库。
    >=*n*vue topics:>=5?匹配含有 "vue" 字样、有 5 个或更多主题的仓库。
    <*n*vue size:<10000?匹配小于 10 KB 的文件中含有 "vue" 字样的代码。
    <=*n*vue stars:<=50?匹配含有 "vue" 字样、星标不超过 50 个的仓库。

    您还可以使用 范围查询 搜索大于等于或小于等于另一个值的值。

    查询示例
    *n*..*vue stars:10..*?等同于?stars:>=10?并匹配含有 "vue" 字样、有 10 个或更多星号的仓库。
    *..*n*vue stars:*..10?等同于?stars:<=10?并匹配含有 "vue" 字样、有不超过 10 个星号的仓库。

    查询范围之间的值

    您可以使用范围语法?*n*..*n*?搜索范围内的值,其中第一个数字?n?是最低值,而第二个是最高值。

    查询示例
    *n*..*n*vue stars:10..50?匹配含有 "vue" 字样、有 10 到 50 个星号的仓库。

    查询日期

    您可以通过使用?>>=<<=?和 范围查询 搜索早于或晚于另一个日期,或者位于日期范围内的日期。

    日期格式必须遵循?ISO8601 标准,即?YYYY-MM-DD(年-月-日)。

    查询示例
    >*YYYY*-*MM*-*DD*vue created:>2016-04-29?匹配含有 "vue" 字样、在 2016 年 4 月 29 日之后创建的议题。
    >=*YYYY*-*MM*-*DD*vue created:>=2017-04-01?匹配含有 "vue" 字样、在 2017 年 4 月 1 日或之后创建的议题。
    <*YYYY*-*MM*-*DD*vue pushed:<2012-07-05?匹配在 2012 年 7 月 5 日之前推送的仓库中含有 "vue" 字样的代码。
    <=*YYYY*-*MM*-*DD*vue created:<=2012-07-04?匹配含有 "vue" 字样、在 2012 年 7 月 4 日或之前创建的议题。
    *YYYY*-*MM*-*DD*..*YYYY*-*MM*-*DD*vue pushed:2016-04-30..2016-07-04?匹配含有 "vue" 字样、在 2016 年 4 月末到 7 月之间推送的仓库。
    *YYYY*-*MM*-*DD*..*vue created:2012-04-30..*?匹配在 2012 年 4 月 30 日之后创建、含有 "vue" 字样的议题。
    *..*YYYY*-*MM*-*DD*vue created:*..2012-04-30?匹配在 2012 年 7 月 4 日之前创建、含有 "vue" 字样的议题。

    您也可以在日期后添加可选的时间信息?THH:MM:SS+00:00,以便按小时、分钟和秒进行搜索。 这是?T,随后是?HH:MM:SS(时-分-秒)和 UTC 偏移 (+00:00)。

    查询示例
    *YYYY*-*MM*-*DD*T*HH*:*MM*:*SS*+*00*:*00*vue created:2017-01-01T01:00:00+07:00..2017-03-01T15:30:15+07:00?匹配在 2017 年 1 月 1 日凌晨 1 点(UTC 偏移为?07:00)与 2017 年 3 月 1 日下午 3 点(UTC 偏移为?07:00)之间创建的议题。 UTC 偏移量?07:00,2017 年 3 月 1 日下午 3 点。 UTC 偏移量?07:00
    *YYYY*-*MM*-*DD*T*HH*:*MM*:*SS*Zvue created:2016-03-21T14:11:00Z..2016-04-07T20:45:00Z?匹配在 2016 年 3 月 21 日下午 2:11 与 2016 年 4 月 7 日晚上 8:45 之间创建的议题。

    排除特定结果

    您可以使用?NOT?语法排除包含特定字词的结果。?NOT?运算符只能用于字符串关键词, 不适用于数字或日期。

    查询示例
    NOThello NOT world?匹配含有 "hello" 字样但不含有 "world" 字样的仓库。

    缩小搜索结果范围的另一种途径是排除特定的子集。 您可以为任何搜索限定符添加?-?前缀,以排除该限定符匹配的所有结果。

    查询示例
    -*QUALIFIER*vue stars:>10 -language:javascript?匹配含有 "vue" 字样、有超过 10 个星号但并非以 JavaScript 编写的仓库。
    mentions:biaochenxuying -org:github?匹配提及 @biaochenxuying 且不在 GitHub 组织仓库中的议题

    对带有空格的查询使用引号

    如果搜索含有空格的查询,您需要用引号将其括起来。 例如:

    某些非字母数字符号(例如空格)会从引号内的代码搜索查询中删除,因此结果可能出乎意料。

    使用用户名的查询

    如果搜索查询包含需要用户名的限定符,例如?useractor?或?assignee,您可以使用任何 GitHub 用户名指定特定人员,或使用?@me?指定当前用户。

    查询示例
    QUALIFIER:USERNAMEauthor:biaochenxuying?匹配 @biaochenxuying 创作的提交。
    QUALIFIER:@meis:issue assignee:@me?匹配已分配给结果查看者的议题

    @me?只能与限定符一起使用,而不能用作搜索词,例如?@me main.workflow

    高级的搜索

    按仓库名称、说明或自述文件内容搜索

    通过?in?限定符,您可以将搜索限制为仓库名称、仓库说明、自述文件内容或这些的任意组合。

    如果省略此限定符,则只搜索仓库名称和说明。

    限定符示例
    in:namevue in:name?匹配其名称中含有 "jquery" 的仓库。
    in:descriptionvue in:name,description?匹配其名称或说明中含有 "vue" 的仓库。
    in:readmevue in:readme?匹配其自述文件中提及 "vue" 的仓库。
    repo:owner/namerepo:biaochenxuying/blog?匹配特定仓库名称,比如:用户为 biaochenxuying 的 blog 项目。

    在用户或组织的仓库内搜索

    要在 特定用户或组织 拥有的所有仓库中搜索,您可以使用?user?或?org?限定符。

    限定符示例
    user:*USERNAME*user:biaochenxuying forks:>=100?匹配来自 @biaochenxuying、拥有超过 100 复刻的仓库。
    org:*ORGNAME*org:github?匹配来自 GitHub 的仓库。

    按仓库大小搜索

    size?限定符使用 大于、小于和范围限定符 查找匹配特定大小(以千字节为单位)的仓库。

    限定符示例
    size:*n*size:1000?匹配恰好为 1 MB 的仓库。
    size:>=30000?匹配至少为 30 MB 的仓库。
    size:<50?匹配小于 50 KB 的仓库。
    size:50..120?匹配介于 50 KB 与 120 KB 之间的仓库。

    按关注者数量搜索

    您可以使用?followers?限定符以及大于、小于和范围限定符基于仓库拥有的关注者数量过滤仓库。

    限定符示例
    followers:*n*node followers:>=10000?匹配有 10,000 或更多关注者提及文字 "node" 的仓库。
    styleguide linter followers:1..10?匹配拥有 1 到 10 个关注者并且提及 "styleguide linter" 一词的的仓库。

    按复刻数量搜索

    forks?限定符使用大于、小于和范围限定符指定仓库应具有的复刻数量。

    限定符示例
    forks:*n*forks:5?匹配只有 5 个复刻的仓库。
    forks:>=205?匹配具有至少 205 个复刻的仓库。
    forks:<90?匹配具有少于 90 个复刻的仓库。
    forks:10..20?匹配具有 10 到 20 个复刻的仓库。

    按星号数量搜索

    您可以使用 大于、小于和范围限定符 基于仓库具有的 星标 数量搜索仓库

    限定符示例
    stars:*n*stars:500?匹配恰好具有 500 个星号的仓库。
    stars:10..20?匹配具有 10 到 20 个星号、小于 1000 KB 的仓库。
    stars:>=500 fork:true language:vue?匹配具有至少 500 个星号,包括复刻的星号(以 vue 编写)的仓库。

    按仓库创建或上次更新时间搜索

    你可以基于创建时间或上次更新时间过滤仓库。

    • 对于仓库创建,您可以使用?created?限定符;
    • 要了解仓库上次更新的时间,您要使用?pushed?限定符。?pushed?限定符将返回仓库列表,按仓库中任意分支上最近进行的提交排序。

    两者均采用日期作为参数。 日期格式必须遵循?ISO8601 标准,即?YYYY-MM-DD(年-月-日)。

    也可以在日期后添加可选的时间信息?THH:MM:SS+00:00,以便按小时、分钟和秒进行搜索。 这是?T,随后是?HH:MM:SS(时-分-秒)和 UTC 偏移 (+00:00)。

    日期支持 大于、小于和范围限定符

    限定符示例
    created:*YYYY-MM-DD*vue created:<2020-01-01?匹配具有 "vue" 字样、在 2020 年之前创建的仓库。
    pushed:*YYYY-MM-DD*css pushed:>2020-02-01?匹配具有 "css" 字样、在 2020 年 1 月之后收到推送的仓库。
    vue pushed:>=2020-03-06 fork:only?匹配具有 "vue" 字样、在 2020 年 3 月 6 日或之后收到推送并且作为复刻的仓库。

    按语言搜索

    您可以基于其编写采用的主要语言搜索仓库。

    限定符示例
    language:*LANGUAGE*vue language:javascript?匹配具有 "vue" 字样、以 JavaScript 编写的仓库。

    按主题搜索

    您可以查找归类为特定 主题 的所有仓库。

    限定符示例
    topic:*TOPIC*topic:algorithm 匹配已归类为 "algorithm" 主题的仓库。

    估计又有很多人不知道 GitHub 上有话题一说的吧。

    按主题数量搜索

    您可以使用?topics?限定符以及 大于、小于和范围限定符 按应用于仓库的 主题 数量搜索仓库。

    限定符示例
    topics:*n*topics:5?匹配具有五个主题的仓库。
    topics:>3?匹配超过三个主题的仓库。

    使用可视界面搜索

    还可以使用?search?page 或?advanced search?page 搜索 GitHub 哦。

    这种搜索方式,估计就更少人知道了吧。

    advanced search?page 提供用于构建搜索查询的可视界面。

    您可以按各种因素过滤搜索,例如仓库具有的星标数或复刻数。 在填写高级搜索字段时,您的查询将在顶部搜索栏中自动构建。

    高级搜索

    按许可搜索

    您可以按其许可搜索仓库。 您必须使用许可关键词按特定许可或许可系列过滤仓库。

    限定符示例
    license:*LICENSE_KEYWORD*license:apache-2.0?匹配根据 Apache License 2.0 授权的仓库。

    按公共或私有仓库搜索

    您可以基于仓库是公共还是私有来过滤搜索。

    限定符示例
    is:publicis:public org:github?匹配 GitHub 拥有的公共仓库。
    is:privateis:private pages?匹配您有访问权限且包含 "pages" 字样的私有仓库。

    按公共或私有仓库搜索

    您可以根据仓库是否为镜像以及托管于其他位置托管来搜索它们。

    限定符示例
    mirror:truemirror:true GNOME?匹配是镜像且包含 "GNOME" 字样的仓库。
    mirror:falsemirror:false GNOME?匹配并非镜像且包含 "GNOME" 字样的仓库。

    基于仓库是否已存档搜索

    你可以基于仓库是否已存档来搜索仓库。

    限定符示例
    archived:truearchived:true GNOME?匹配已存档且包含 "GNOME" 字样的仓库。
    archived:falsearchived:false GNOME?匹配未存档且包含 "GNOME" 字样的仓库。

    基于具有标签的议题数量搜索

    您可以使用限定符?help-wanted-issues:>n?和?good-first-issues:>n?搜索具有最少数量标签为?help-wanted?或?good-first-issue?议题的仓库。

    限定符示例
    good-first-issues:>ngood-first-issues:>2 javascript?匹配具有超过两个标签为?good-first-issue?的议题且包含 "javascript" 字样的仓库。
    help-wanted-issues:>nhelp-wanted-issues:>4 react?匹配具有超过四个标签为?help-wanted?的议题且包含 "React" 字样的仓库。

    学习

    其实,以上很多内容的都是来自于 GitHub 的官方文档,如果你还想学习更多技巧,请看

    GitHub 官方文档 : https://docs.github.com/cn

    如果你还不了解或者不会使用 GitHub ,可以看看这一章节:

    Git 和 GitHub 学习资源https://docs.github.com/cn/fr...

    最后

    [前端GitHub] 地址:https://github.com/biaochenxu...

    平时如何发现好的开源项目,可以看看这篇文章:GitHub 上能挖矿的神仙技巧 - 如何发现优秀开源项目

    觉得有用 ?喜欢就收藏,顺便点个赞吧,你的支持是我最大的鼓励!

    在公众号后台回复:电子书 ,可以获得 160 本前端精华书籍哦。

    往期精文

    查看原文

    赞 12 收藏 7 评论 0

    夜尽天明 发布了文章 · 11月2日

    GitHub上最火的、最值得前端学习的几个数据结构与算法项目!没有之一!


    Hello,大家好,我是你们的 前端章鱼猫。

    简介

    前端章鱼猫从 2016 年加入 GitHub,到现在的 2020 年,快整整 5 个年头了。

    相信很多人都没有逛 GitHub 的习惯,因此总会有开源信息的不对称,有哪些优秀的前端开源项目值得学习的也不知道。

    从 2018 年开始,我就养成了每天逛 GitHub 的习惯,一般在早上上班前或者中午午休的时候都会逛一下。

    看看每天都开源了哪些好的前端项目,还有用到的主流前端技术栈又是哪些,值得我去学习的。

    因此也收藏了不少好的开源项目,在此推荐给大家,每周会有一到三篇的文章推送。

    希望你在浏览、学习了前端章鱼猫推荐的这些开源项目的过程中,你能学习到更多编程知识、提高编程技巧、找到编程的乐趣。

    【前端GitHub】,专注于挖掘 GitHub 上优秀的前端开源项目,抹平你的前端信息不对称,涵盖 JavaScript、Vue、React、Node、小程序、Flutter、Deno、HTML、CSS、数据结构与算法 等等。

    以下为【前端GitHub】的第二期内容。

    前言

    算法为王。

    想学好前端,先练好内功,内功不行,就算招式练的再花哨,终究成不了高手;只有内功深厚者,前端之路才会走得更远。

    本文推荐几个 GitHub 上值得前端学习的数据结构与算法项目,包含 gif 图的演示过程与视频讲解。

    数据结构与算法

    关于数据结构与算法的 GitHub 项目,star 数由高到低排序。

    javascript-algorithms

    https://github.com/trekhleb/javascript-algorithms

    该仓库包含了多种基于 JavaScript 的算法与数据结构。

    每种算法和数据结构都有自己的 README,包含相关说明和链接,以便进一步阅读 (还有 YouTube 视频) 。

    数据结构包含了 链表、双向链表、队列、栈、哈希表(散列)、堆、优先队列、字典树、树、优先队列、二叉查找树、AVL 树、红黑树、线段树、树状数组、图、并查集、布隆过滤器

    算法包含了 算法主题 和 算法范式。

    其中算法主题又包含了:数学、集合、字符串、搜索、排序、链表、树、图、加密、机器学习。

    算法范式:算法范式是一种通用方法,基于一类算法的设计。这是比算法更高的抽象,就像算法是比计算机程序更高的抽象。

    算法范式包含了:BF 算法、贪心法、分治法、动态编程、回溯法、Branch & Bound 等等。

    这项目还出了对应的教学视频,总共 81 个视频讲解,每个视频大概 5 - 10分钟左右,还能学习英语哦 ??

    youtube 的教学视频:https://www.youtube.com/playl...

    前端章鱼猫之前学习算法的时候,也在这个项目中收益良多呢!

    而且这个项目还一直有维护和更新内容哦!真的非常不错的一个项目!


    algorithm-visualizer

    https://github.com/algorithm-visualizer/algorithm-visualizer

    算法可视化工具是一个交互式的在线平台,可以从代码中可视化算法。

    通过可视化方法学习算法变得容易得多。

    Algorithm Visualizer 是一款有趣的在线开源工具,内含多种算法并进行了直观可视化呈现, 让学习算法和数据结构更加直观。

    目前支持的算法包括回溯法、加密算法、动态规划、图搜索、贪婪算法、搜索算法、排序算法等。

    Algorithm Visualizer 的目录区,选择任何算法,中间就会动态演示,日志输出区记录每次搜索的过程。

    该算法可视化工具是一个用 React 编写的 web 应用程序。它包含 UI 组件并将命令解释为可视化。

    如果你是算法初学者,强烈推荐这个「算法可视化」工具 Algorithm Visualizer,很清晰地绘制了每一个基础算法的原理和运作流程。

    算法可视化工具


    algo

    algo: https://github.com/wangzheng0822/algo

    数据结构和算法必知必会的 50 个代码实现。

    包含数组、链表、栈、队列、递归、排序、二分查找、散列表、字符串、二叉树、堆、图、回溯、分治、动态规划 等。

    每个代码实现有解释,测试用例。

    // 选择排序
    const selectionSort = (arr) => {
        if (arr.length <= 1) return
        // 需要注意这里的边界, 因为需要在内层进行 i+1后的循环,所以外层需要 数组长度-1
        for (let i = 0; i < arr.length - 1; i++) {
            let minIndex = i
            for (let j = i + 1; j < arr.length; j++) {
                if (arr[j] < arr[minIndex]) {
                    minIndex = j // 找到整个数组的最小值
                }
            }
            const temp = arr[i]
            arr[i] = arr[minIndex]
            arr[minIndex] = temp
        }
        console.log(arr)
    }
    
    const test = [4, 5, 6, 3, 2, 1]
    bubbleSort(test)
    const testSort = [4, 1, 6, 3, 2, 1]
    insertionSort(testSort)
    const testSelect = [4, 8, 6, 3, 2, 1, 0, 12]
    selectionSort(testSelect)

    该仓库是《数据结构和算法之美》《设计模式之美》专栏作者创建的,前端章鱼猫也学习过他的《数据结构和算法之美》,非常不错的学习教程。


    awesome-algorithms

    https://github.com/mgechev/javascript-algorithms

    此存储库包含不同著名计算机科学算法的 javascript 实现。

    该仓库是不错的,不方便学习的地方就是需要安装依赖并运行才能看到效果及文档。

    Call:
    
    npm install
    
    To setup repository with documentation
    
    npm run doc
    
    This will build the documentation and open it in your browser.

    JS-Sorting-Algorithm

    https://github.com/hustcc/JS-Sorting-Algorithm

    一本关于排序算法的 GitBook 在线书籍 《十大经典排序算法》,使用 JavaScript & Python & Go & Java 实现。

    包含冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、计数排序、桶排序、基数排序。

    该仓库的文章有定义有解释、有代码实现、还有动态图,入门十大经典排序算法是个不错的教程。


    JavaScript 数据结构与算法之美

    https://github.com/biaochenxu...

    包含了 十大经典排序算法 的思想、代码实现、一些例子、复杂度分析、动画、还有算法可视化工具。

    这是比较精简的 JavaScript 数据结构与算法 的讲解。

    该仓库总共写了 10 篇算法入门的文章

    1. 时间和空间复杂度
    2. 线性表(数组、队列、栈、链表)
    3. 实现一个前端路由,如何实现浏览器的前进与后退 ?
    4. 栈内存与堆内存 、浅拷贝与深拷贝
    5. 递归
    6. 非线性表(树、堆)
    7. 冒泡排序、选择排序、插入排序
    8. 归并排序、快速排序、希尔排序、堆排序
    9. 计数排序、桶排序、基数排序
    10. 十大经典排序算法汇总
    11. GitHub 上 170K+ Star 的前端学习的数据结构与算法项目

    也是非常不错的数据结构与算法的入门学习资料。


    daily-algorithms

    https://github.com/barretlee/...

    算法,每日练习的一个项目。

    • ★ 表示 easy,★★ 表示 medium,★★★ 表示 hard;
    • 题目主要来自 leetcode,可能会适当变换题设,改变难度;
    • 对于 ★ 和 ★★ 难度的题目,每天的量会随机出现 1~5 个,尤其是 ★ 的题目,比较简单。

    白天出题,尽量晚上给出参考答案。

    项目也不错,是以参与讨论的形式与大家一起学习数据结构与算法的。

    就是内容积累还不够多,还不够火。


    JavaScript 更多 ...

    https://github.com/search?l=JavaScript&o=desc&q=algo&s=stars&type=Repositories

    还想知道更多好的数据结构与算法项目,可以点击上面的链接进行搜索。


    最后

    Star 数最多,但是并不代表该项目就最好并适合你哦,因为有些项目早于几年前就不再更新与维护了。

    本文推荐的都是一些真的实用并还在更新的开源仓库,估计都比较适合前端学习。

    平时如何发现好的开源项目,可以看看这篇文章:GitHub 上能挖矿的神仙技巧 - 如何发现优秀开源项目

    本文原文 GitHub 地址:https://github.com/biaochenxu...

    觉得有用 ?喜欢就收藏,顺便点个赞吧,你的支持是我最大的鼓励!

    在公众号后台回复:电子书 ,可以获得160本前端精华书籍哦。

    查看原文

    赞 28 收藏 21 评论 0

    夜尽天明 发布了文章 · 10月27日

    全球最火的WEB开发学习路线!没有之一!3 天就在GitHub收获了接近 1w 点赞

    Hello,大家好,我是你们的 前端章鱼猫。

    简介

    前端章鱼猫从 2016 年加入 GitHub,到现在的 2020 年,快整整 5 个年头了。

    相信很多人都没有逛 GitHub 的习惯,因此总会有开源信息的不对称,有哪些优秀的前端开源项目值得学习的也不知道。

    从 2018 年开始,我就养成了每天逛 GitHub 的习惯,一般在早上上班前或者中午午休的时候都会逛一下。

    看看每天都开源了哪些好的前端项目,还有用到的主流前端技术栈又是哪些,值得我去学习的。

    因此也收藏了不少好的开源项目,以后会在公众号【前端GitHub】上推荐给大家,每周会有一到三篇的文章推送。

    希望你在浏览、学习了前端章鱼猫推荐的这些开源项目的过程中,你能学习到更多编程知识、提高编程技巧、找到编程的乐趣。

    【前端GitHub】,专注于挖掘 GitHub 上优秀的前端开源项目,抹平你的前端信息不对称,涵盖 JavaScript、Vue、React、Node、小程序、Flutter、Deno、HTML、CSS 等。

    以下为【前端GitHub】的第 1 期内容。

    前言

    Web 开发是一个不断变化的领域 - 我们今天构建网站的方式与几年前的方式完全不同。

    随着大量工具的出现以及新工具的层出不穷,大多数时候开发人员发现对于自己该怎么选择感到困惑。

    如果你是一个刚刚踏入 WEB 开发的初学者,这里有一份修炼图谱给你。

    如果你是一个早已入门的高级开发者,那 2020 即将过去了,你的技术都学对了吗 ?

    快来检验一下吧!

    前端

    frontend-map.png

    后端

    backend-map.png

    运维

    devops-map.png

    最后

    平时如何发现好的开源项目,可以看看这篇文章:GitHub 上能挖矿的神仙技巧 - 如何发现优秀开源项目

    文章中的技术图片均来自如下开源项目:

    【开发人员路线图】: 循序渐进的指南和路径,以学习不同的工具或技术。

    GitHub 中文地址:https://github.com/kamranahme...

    对了,新一年的 WEB开发路线图 会在每年的年初进行更新,各位看官到时可以留意一下哦。

    当然 前端章鱼猫 也会关注的,到时出了新的技术图谱,也会发出来的哦。

    本文原文地址:https://github.com/biaochenxu...

    在公众号后台回复:电子书 ,可以获得160本高分技术电子书哦。

    查看原文

    赞 17 收藏 16 评论 0

    夜尽天明 发布了文章 · 10月9日

    2020 - 2021 年 Web 前端最新导航 - 前端学习资源分享&前端面试资源汇总

    国庆这几天,我收集了大量可以显著提升开发效率的前端导航链接。

    这些导航链接对我很有帮助,希望对你也是如此。

    这些好用的导航链接都已经部署到下面的网站上了,在那里食用更美味哦。

    Web 前端最新导航?https://www.kwgg2020.com/
    笔者博客地址:https://github.com/biaochenxu...

    JavaScript

    CSS

    算法

    前端面试

    技术社区

    博客团队

    GitHub 统计

    构建

    部署

    • GitHub Pages GitHub 提供的免费静态网站托管服务
    • Netlify 30 秒内部署你的网站
    • Vercel 快速部署你的网站
    • Surge 只需一个命令就可以发布你的网站
    • Heroku 在云端构建、运行你的应用

    静态站点搭建工具

    前端代码规范?

    调试抓包

    开发工具

    在线工具

  • 前端大会

    图标

    色彩

    插画

    图片

    • Unsplash 可供免费使用的图片
    • Pexels 精美的免费图片和视频
    • Burst 免费高分辨率图片,可用于网站和商业用途
    • ISO Republic 使用 CC0 许可的免费高分辨率图片和视频
    • Pixabay 令人惊叹的免费(公共领域)图片和视频站点
    • StockSnap.io 精美的免费图片,同样使用 CC0 许可
    • Photopea 在线图片编辑工具,支持大量高级功能
    • Online Image Compressor 在线图片压缩工具,一次可以压缩多达 20 张图片
    • Bulk Resize Photos 最快的在线图片缩放工具(图片缩放和压缩在本地完成,无需上传到服务器)

    其他

    设计工具

    前端导航网站地址: https://www.kwgg2020.com

    笔者博客地址:https://github.com/biaochenxu...

    推荐阅读:

    支持一下下??

    查看原文

    赞 67 收藏 54 评论 3

    夜尽天明 发布了文章 · 9月15日

    推荐一个学习的网站,学习、资源、工具、电子书、影视、资讯、还有强大的搜索!

    哈喽,大家好,我是你们的小乖乖!

    今天给大家带来的是一个资源网站的导航。

    网站里面,资源、工具、电子书、影视、资讯、学习 的资源这里的都有,非常实用!

    学习 主要是以实用的网站为主,娱乐主要是以 B 站有趣的频道为主。

    这个网站的风格非常极客、简结并且漂亮,而且完全没有广告哦!

    网站地址: https://www.kwgg2020.com/

    搜索

    该网站最强大的是它的搜索功能,是一个聚合型搜索功能,包括 搜索、网盘、软件、书籍、其他。

    不得不提的是联想词,会根据输入的关键字出现相关的联想词。

    比如搜索 “穷爸爸富爸爸” 会出现很多联想词,而且这些词是调用的百度的联想的 api 来的,所以都是热门的联想词,可以点击相应的导航来搜索。

    还可以在某网盘里面搜索

    搜索到资源之后,直接下载即可,非常方便!

    学习

    分别是学习、资源、工具、读书、影视、资讯。

    在资讯类目主要用来查看互联网最新的资讯,其中人人都是产品经历和增长黑盒的文章很值得一看,而知微事见很适合来做热点新闻的数据分析。

    学习类目主要是各种网络课程,有少部分以文章和网页游戏的形式来呈现,适合自学某些技能。

    资源类目主要是提供内容制作的素材,包含图片、声音、视频、文献以及软件资源等,其中图片和视频均为无版权素材,可以商用。

    除了自有的网站资源提供外,可以通过搜索和字典查找的方式来获取更多的资源。

    工具类目主要是进行内容制作的一些工具,包括海报、logo、视频以及声音制作,此外还有相关PDF、视频以及图片的格式转换工具、视频下载以及内容的数据分析工具等。

    读书类目分为书籍网站和书籍搜索,书籍网站主要以网站的形式呈现,可以进行电子书的查找和免费下载,书籍搜索则通过搜索的方式来获取电子书资源进行下载或阅读。

    最后影视类目主要是纪录片、电影以及动漫的观看网站和资源搜索网站,其中zzzFun动漫网经常用,里面有很多 B 站会员才能看的动漫,直接在线免费观看。

    IT学习

    外语学习

    综合学习

    思想开拓

    创意设计

    视频素材

    声音素材

    图片素材

    文献资源

    搜索查找

    字典查找

    历史文献

    数据报告

    生活技巧

    软件资源

    设计创作

    文件格式转换

    网络安全

    办公常用

    视频下载

    数据分析

    书籍网站

    书籍搜索

    关于影视

    其他推荐

    推荐

    资讯阅读

    娱乐

    资讯视频主要是 B站 几个官方站,可以查看到B站的一些官方消息和 up 主资讯。

    学习视频主要是有剪辑以及常用办公软件的使用技巧学习,兴趣学习以开拓视野为主,综合视频里更多的是赏课,娱乐视频里主要是电影解说和图书评论。

    其他视频里是一些有鲜明特色的up主。

    最后有趣的网站主要收录了一些奇奇怪怪但是很有趣味的网站,可以作为消遣使用。

    资讯视频

    软件学习

    语言学习

    技能学习

    兴趣学习

    纪录片

    科普片

    人文片

    g

    读书视频

    影视解说

    其他视频

    有趣网站

    过程与计划

    过程

    这网站其实是小乖乖用业余时间做的,花费了很多时间去搜寻了这么多的网站资源。

    搜索资源的过程用了好几天,搭建的整个过程又用了好几天,上上周的两天周末就是在搭建这个网站,申请域名备案的过程又等待了一周,所以整个过程下来就都大半过月了。

    所以最近一直没更新文章 ??

    网站其实在一周之前就做好了,只是平时工作加班比较严重,加上上周末的两天都在做工作上的技术调研,所以没空写文章,所以等到了今天才写好。

    实用的话,大家就支持一下小乖乖吧。

    网站地址: https://www.kwgg2020.com/

    网站地址收藏起来!

    计划

    未来将添加更多实用的网站,删除一些失效的网站。

    网站支持评论功能哦,欢迎大家在网站的评论里提供更多实用的网站哦。

    成长的路上,我们一起进步。

    欢迎大家提供更多的建议,欢迎在下方讨论哦。

    查看原文

    赞 6 收藏 3 评论 0

    认证与成就

    • 获得 3089 次点赞
    • 获得 26 枚徽章 获得 2 枚金徽章, 获得 7 枚银徽章, 获得 17 枚铜徽章

    擅长技能
    编辑

    开源项目 & 著作
    编辑

    • blog

      个人原创技术文章地址。

    • blog-vue-typescript

      vue + typescript + element-ui 支持 markdown 渲染的博客前台展示

    • blog-react

      react + Ant Design + 支持 markdown 的博客展示项目

    • blog-react-admin

      基于 pro.ant.design 的 react + Ant Design 的博客管理后台项目

    • blog-node

      基于 node + express + mongodb 的博客网站后台

    • vue-family-mindmap

      一张思维导图辅助你深入了解 Vue | Vue-Router | Vuex 源码与架构。

    • route

      原生 js 实现的轻量级路由

    • split

      js 实现上下拖动改变父 div 的高度,左右上下拖动动态分割孩子的宽高。

    • progress

      原生 js 实现一个有动画效果的进度条 progress 插件。

    注册于 2018-07-05
    个人主页被 12.8k 人浏览

    bt365体育投注