-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathread_v8_blog.html
1 lines (1 loc) · 38.8 KB
/
read_v8_blog.html
1
<!doctype html><html lang="zh-CN" class="night"><head><meta charset="utf-8"><meta content="width=device-width,initial-scale=1,maximum-scale=4,user-scalable=0" name="viewport"><title>Ede's Blog</title><meta name="description" content="Try to be a qualified programmer"><meta property="og:type" content="website"><meta property="og:description" content="Try to be a qualified programmer"><meta property="og:title" content="Ede's Blog"><meta property="og:site_name" content="Ede's Blog"><meta property="og:url" content="https://ede.ink"><meta property="og:image" content="https://edeity.oss-cn-shenzhen.aliyuncs.com/public/edeity_o.png"><link rel="shortcut icon" href="/favicon.ico" type="image/x-icon"><link rel="mainfest" href="/mainfest.json"><link rel="stylesheet" href="/public/css/common.css"><link rel="stylesheet" href="//at.alicdn.com/t/font_707055_4b9og9sc5lx.css"><script>!function(){var e=-1!==window.location.search.indexOf("theme=night")||"night"===window.localStorage.getItem("edeity-theme_theme"),t=-1!==window.location.search.indexOf("theme=light")||"light"===window.localStorage.getItem("edeity-theme_theme");(new Date).getHours();var n=document.querySelector("html");e?n.classList.add("night"):t?n.classList.remove("night"):n.classList.add("night")}(),document.addEventListener("DOMContentLoaded",function(){null!==document.querySelector("ol.toc")&&(document.querySelector("#nav-bar").style.cssText="display: block")})</script><script async src="https://www.googletagmanager.com/gtag/js?id=G-M3J9QSEE2Z"></script><script>function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","G-M3J9QSEE2Z")</script><meta name="generator" content="Hexo 5.0.0"></head><body><div class="loading"></div><div id="switch" data-switch="{"toc":true,"use_pwa":false}"></div><header class="fullscreen"><div class="toolbar"><i class="iconfont icon-menu"></i></div><h1><a href="/">Ede's Blog</a></h1><div class="head-link"><a class="btn waves" href="/"><span><i class="iconfont icon-home">Home </i></span></a><a class="btn waves" href="/about/index.html"><span><i class="iconfont icon-me">About </i></span></a><a class="btn waves" target="_blank" rel="noopener" href="https://github.com/edeink"><span><i class="iconfont icon-github">Github</i></span></a></div></header><div class="some-link"><a class="btn" id="light-or-not"><i class="iconfont icon-light"></i> </a><a style="display:none" class="btn" id="up-to-top"><i class="iconfont icon-up"></i></a></div><div id="nav-bar" style="display:none"><div class="toc"><ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#V8%E6%8A%80%E6%9C%AF%E7%AE%80%E4%BB%8B"><span class="toc-number">1.</span> <span class="toc-text">V8技术简介</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%89%88%E6%9C%AC%E5%8F%91%E5%B8%83"><span class="toc-number">2.</span> <span class="toc-text">版本发布</span></a></li></ol></div></div><main id="content-main" class="section"><div class="list-item"><h1 class="post-title"><a id="V8 Blog的阅读笔记" class="article-link" href="">V8 Blog的阅读笔记</a></h1><div class="post-meta"><time class="meta published">Sep 17, 2019</time></div><div class="article"><div class="post-excerpt markdown-body"><p>工作以后,接触英文资料较少。平时阅读英文文档,为了效(yan)率(shi),google翻译已三年。三年内,除了对前端知识稍以熟练,其余收获不多。故立小目标,抽空阅读V8的<a target="_blank" rel="noopener" href="https://v8.dev/blog">博客</a> 。<del>尽可能先读原文,后看翻译</del>。</p><p>在我的实践理解中,对前端而言,阅读V8博客,哪怕占用了我下半年大量的空余时间,也是收获甚多。建议细读。<small>(人懒碎事多,导致空闲时间并不多,截止2019.12.31,阅读进度100/100)</small>,</p><p>以下仅为各篇文章摘要,具体内容请自行阅读。</p><h2 id="V8技术简介"><a href="#V8技术简介" class="headerlink" title="V8技术简介"></a>V8技术简介</h2><ol><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/turbofan-jit">Digging into the TurboFan JIT</a>:仅提及V8采用代号了为<code>TurboFan</code>的多层级架构的编译器。</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/code-caching">Code caching</a>:V8采用了代码缓存的技术,用节省切换页面时字节码转化为机器码所需要的时间,<a target="_blank" rel="noopener" href="https://v8docs.nodesource.com/node-4.8/da/da5/classv8_1_1_script_compiler.html#a9419dd32e265bc13507c44d12f2fd261">ScriptCompiler::CompileOptions</a><small>(未展开简述)</small></p></li><li><p>【REC】<a target="_blank" rel="noopener" href="https://v8.dev/blog/free-garbage-collection">Getting garbage collection for free</a>:V8会在浏览器相对空闲时采取GC,其拆分为多个具备执行上限的不同优先级任务。和大多数GC一样,V8也会区分新生代和次世代。新生代采用了<code>semi-space</code>的策略<small>(分为两个半空间,激活一个,用以存放对象,此半空间满时,执行清理,已标记的活跃的对象将移动次世代空间,未被标记的移动到另一个半空间,不活跃的则会被回收,两个半空间空闲状态转化)</small>。次世代则采用<code>mark-and-sweep</code>(标记-扫描)策略,次世代的回收耗时较长,为了避免等待,该标记收集会被拆分成多个执行时间小于5ms的子任务。<small>(该方法也是常用的方法,缺点是执行期间会挂起正常程序,以及多次执行会产生碎片,V8如何克服缺点并没有展开简述)</small></p><ul><li>拓展<small>(<code>semi-space</code>详见1,<code>mark-and-sweep</code>详见2,<code>新生代&次世代</code>详见4)</small></li><li><a target="_blank" rel="noopener" href="https://liujiacai.net/blog/2018/06/15/garbage-collection-intro/">深入浅出垃圾回收(一)简介篇</a></li><li><a target="_blank" rel="noopener" href="https://liujiacai.net/blog/2018/07/08/mark-sweep/">深入浅出垃圾回收(二)Mark-Sweep 详析及其优化</a></li><li><a target="_blank" rel="noopener" href="https://liujiacai.net/blog/2018/08/04/incremental-gc/">深入浅出垃圾回收(三)增量式 GC</a></li><li><a target="_blank" rel="noopener" href="https://liujiacai.net/blog/2018/08/18/generational-gc/">深入浅出垃圾回收(四)分代式 GC</a></li></ul></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/custom-startup-snapshots">Custom startup snapshots</a>:V8采用快照的方式,减少页面初始化时全局对象(正则等)初始化的耗时。每打开一个页面,将创建一份具备独立上下文的快照副本。</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/jank-busters">Jank Busters Part One</a>:交代了导致V8<code>Jank</code>的两个重要原因:<strong>GC跟踪过多的ArrayBuffer</strong>、<strong>V8向Chrome提供过多句柄</strong><small>(允许操作V8数据)</small>。这两个情况常发生在WebGL的渲染上。对这两种情况,V8做了以下优化:对<code>ArrayBuffer</code>剥离原有的GC规则,作针对性检查<small>( per-access checks在原理上增大耗时,但remove redundant checks却实际上减少了jank,V8未进一步交代具体实现,本人想象力缺乏也没有脑补出来)</small>。以及针对这些数据多数只读不写的特性,通过实现<a target="_blank" rel="noopener" href="https://blog.csdn.net/w372426096/article/details/80938788">逃逸分析</a>进行优化。<small>(锁消除 & 标量替换)</small></p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/math-random">There’s <code>Math.random()</code>, and then there’s <code>Math.random()</code></a>:介绍了Math.random从<code>MWC1616</code>到 <a target="_blank" rel="noopener" href="http://vigna.di.unimi.it/ftp/papers/xorshiftplus.pdf">xorshift128+</a>的过程。</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-extras">V8 extras</a>:V8提供<code>extras</code>模式 <a target="_blank" rel="noopener" href="https://docs.google.com/document/d/1AT5-T0aHGp7Lt29vPWFr2-qG8r3l9CByyvKwEuA8Ec0/edit">API</a>,使可以用javascript提供内置通用的全局对象(称为<code>self-hosted</code>),eg:<code>Promise</code>对象。</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/regexp-lookbehind-assertions">RegExp lookbehind assertions</a>:V8支持了正则的<code>后置断言</code></p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/webassembly-experimental">Experimental support for WebAssembly in V8</a>:V8支持<code>WebAssembly</code>(<small>努力学Rust中</small>)</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/orinoco">Jank Busters Part Two: Orinoco</a>:介绍了名为<code>Orinoco</code>的GC优化手段。将对象从新生代转移到次世代的过程中,指针更换的消耗是昂贵的。GC的优化策略:1. 因为指针更换和次世代的压缩没有依赖关系,所以可以并行执行。2. 采用新的<code>remembered set</code>,简化了原RS相互引用的情况,使追踪指针的命令能够并行<small>(没看懂,日后再算)</small> 3. 采用了黑色标记法<small>(因为次世代跟持久,所以可以提前标记其活跃)。</small></p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/modern-javascript">ES2015, ES2016, and beyond</a>:介绍了V8如何健壮地支持ES Next</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/blinkon-6">V8 at the BlinkOn 6 conference</a>:此博客是一些列视频,先Mark</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/ignition-interpreter">Firing up the Ignition interpreter</a>:介绍了V8为移动端定制了新的解析器<code>Ignition</code>,意在减少内存占用。<small>这里用到了底层一点的技术,不是很了解。</small></p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/optimizing-v8-memory">Optimizing V8 memory consumption</a>:介绍了v8垃圾收集的优化,让内存指标可视化、针对不同的场景执行不同的回收策略(比如对一些内存敏感的设备执行更积极的回收)、及早释放解析器、通过合并数据使数据存储更紧凑等。</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/webassembly-browser-preview">WebAssembly browser preview</a>:浏览器支持<code>WebAssembly</code></p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-nodejs">V8 love Node.js</a>:可以在Chromium中调试node、支持<code>async</code>/<code>await</code>…</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/real-world-performance">How V8 measures real-world performance</a>、<a target="_blank" rel="noopener" href="https://benediktmeurer.de/2016/12/16/the-truth-about-traditional-javascript-benchmarks/#a-closer-look-at-octane">拓展</a>:经过比较发现,<a target="_blank" rel="noopener" href="https://browserbench.org/Speedometer/">Speedometer</a>更接近真实的数据。</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/speeding-up-regular-expressions">Speeding up V8 regular expressions</a>:用C++实现正则,为避免变慢,请勿更改Reg的原型</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/heap-size-limit">One small step for Chrome, one giant heap for V8</a>:Chrome DevTools增加一个功能,在内存快耗尽时断点</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/test-the-future">Help us test the future of V8!</a>:求助贴,通过开启实验性功能来测试新的解析器和编译器</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/high-performance-es2015">High-performance ES2015 and beyond</a>:鼓励开发人员使用ES2015+,仅向不支持的浏览器提供编译版本,这通常能提高页面执行速度。<small>(然而自家产品也没有做到,哈哈哈)</small></p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/fast-for-in">Fast for-in in V8</a>:优化了<code>for in</code>:对象是否含有<code>enumCache</code>(缓存),对于没有缓存的情况,引入<code>KeyAccumulator</code>类,来处理一些简单的键值的枚举,此举提升了众多网站4%的执行速度。</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/retiring-octane">Retiring Octane</a>:<code>Octane</code>工具在现阶段已不利于测评具体世界的js运行情况,谋求一个不依赖于浏览器、分类、免费、关键点在于时间的基准测试工具,如<strong>speedometer</strong>。</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/launching-ignition-and-turbofan">Launching Ignition and TurboFan</a>:已发布新的点火(Ignition)和涡轮(TurboFan)</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/hash-flooding">About that hash flooding vulnerability in Node.js</a>:预编译版本的Node,启用快照(加快启动速度)时,因为随机种子固定,可提交有规律的HTTP头进行Hash攻击,从而导致Node服务器拒绝服务。新的解决方法是,在快照反序列化后,重新生成新的随机种子。</p></li><li><p>【REC】<a target="_blank" rel="noopener" href="https://v8.dev/blog/fast-properties"><em>Fast properties</em> in V8</a>:解析V8如何处理对象属性。</p><ul><li><p><em>数组单独存储</em>:因为可以动态删除,会造成存储上<code>有孔</code>(索引没有值)的现象(有标记位标记不存在的属性,索引没有值会触发原型读取)、稀疏的数组将会以字典形式存储</p></li><li><p><em>属性和值可以是数组或字典的形式</em>:因不利于优化,简单对象并不是以字典方式存储,复制对象可能会一字典存储,但将变成慢属性(运行有效的属性删除,但访问速度较慢)</p></li><li><p><em><code>HiddenClass</code>用于描述对象形状:</em>第一个字段即指向形状,第三个字段存储指针位置等,但没有索引计数,添加属性即更改<code>HiddenClass</code></p></li></ul></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/docs/csa-builtins">CodeStubAssembler builtins</a>:介绍<code>CodeStubAssembler</code>,一种定制的,与平台无关的汇编器。可提供接近汇编的性能。</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/elements-kinds"><em>Elements kinds</em> in V8</a>:介绍了V8中不同的数据类型(虽然JS本身不作区分)。这些类型可以在运行中被改变,但只能从特定类型到更一般类型。大类有<code>PACKED</code>和<code>HOLEY</code>(有孔,代表稀疏)。同时针对类型,给出了一些性能优化建议:避免读取超过数组长度的索引,如:不要再循环条件中复制(可以在循环内部)、避免元素种类转换、优先数组而不是类数组、避免多态,包括参数多态(这个建议牺牲了灵活性,<a target="_blank" rel="noopener" href="https://mrale.ph/blog/2015/01/11/whats-up-with-monomorphism.html">拓展</a>)、最好在初始化时声明所有值,或者初始化空值,而后采用<code>push</code>方法(不要new Array,然后根据索引复制)。</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/disabling-escape-analysis">Temporarily disabling escape analysis</a>:暂时停止转义分析(eg:通过语法转换避免避免创建对象)</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/lazy-unlinking">An internship on laziness: lazy unlinking of deoptimized functions</a>:剔除一些潜在的无效代码</p></li><li><p><a href="">Announcing the Web Tooling Benchmark</a>:V8发布了新的基准测试工具,也做出了一些回馈社区的举动</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/csa">Taming architecture complexity in V8 — the CodeStubAssembler</a>:CSA(CodeStubAssembler)入门介绍</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/optimizing-proxies">Optimizing ES2015 proxies in V8</a>:介绍了将<code>Proxy</code>的运行从C++端转移到CSA上,在JS运行时执行从而将语言跳转的次数从4降为0。同时也优化了注入<code>get</code>、<code>has</code>、<code>set</code></p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/orinoco-parallel-scavenger">Orinoco: young generation garbage collection</a>:介绍GC中的对新生代的算法、<em>半空间算法</em>、<em>并行标记法</em>(MS)、<em>并行消除</em>(ME)。参考【3】</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/javascript-code-coverage">JavaScript code coverage</a>:介绍了Chrome的source代码覆盖工具,并分为<em>尽力而为</em>(遍历整个对的活动函数,但可能因GC导致数据丢失)、和<em>精准覆盖</em>(提供计数,且不被GC)</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/speedometer-2">Chrome welcomes Speedometer 2.0!</a>:Speedometer 2.0版本,并基于此加速了React一倍解析执行的速度</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/hash-code">Optimizing hash tables: hiding the hash code</a>:字典存储数据时【参考26】,会生成Hash(会被存储,可能存储在一个对象的属性数组上以节省内存)</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/lazy-deserialization">Lazy deserialization</a>:为了极速启动页签,V8创建快照【参考4】,但也因序列化原因,导致内存消耗变大。因为V8延迟了反序列化时机,仅在用到时反序列化。</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/tracing-js-dom">Tracing from JS to the DOM and back again</a>:使内存泄露调试更容易(eg:添加事件监听但不销毁会导致内存泄露,Menory中的<code>Leak</code>可观察挂载在window对象或事件)</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/background-compilation">Background compilation</a>:新架构将对JS的编译剥离了主线程(Parse、Compile在后台线程Stream Source,execute在主线程)</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/improved-code-caching">Improved code caching</a>:V8缓存并会反序列化编译后的代码</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/bigint">Adding BigInts to V8</a>:考虑提供对大数bigInt的支持</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/concurrent-marking">Concurrent marking in V8</a>:改进三色标记的增量标记【参考3】,支持并发执行</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/embedded-builtins">Embedded builtins</a>:嵌入式函数库(基于CSA)占用了更多的空间(即使开启了反序列化惰性加载)【参考38】。考虑内嵌二进制(由于访问隔离对象和过程消耗大,仅实现内嵌不一定是优化的,文中还给出了一些优化,如全局内置不常用对象等)</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/liftoff">Liftoff: a new baseline compiler for WebAssembly in V8</a>:新的WASM编辑器(前半部分没看懂,后半部分介绍了wasm结合TurboFan的好处,如静态类型可立即生成优化代码、代码可预测而不需要预热,仅liftoff的话,执行的速度可能会较TurboFan慢)</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/10-years">Celebrating 10 years of V8</a>:V8十年历史,虽然在两次大事件中稍微降低(支持ES5、Spectre漏洞),但总的性能还是提升了4倍</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/dataview">Improving <code>DataView</code> performance in V8</a>:改进<code>DataView</code>(一种和<code>TypedArray</code>并列的底层访问数据的结构)。并提到了Torque,一种降低编写CSA难度的语言。</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/array-sort">Getting things sorted in V8</a>:展开描述Array.sort,推荐避免一些写法以实现更好的性能。原排序使用了<em>quickSort</em>(一般Log(n),最坏O(n2)),但后来转变为了<em>TimSort</em>(一般O(n),最坏nlog(n));虽然效率略有降低,但保证每次返回的结果一致。<small>比如<code>sort(sort(A)) === sort(A)</code>、或者<code>[1,2,3,4,5,6,7,8,9,10,11].sort(function(){return 0;}) \> [6, 1, 3, 4, 5, 2, 7, 8, 9, 10, 11]</code>(旧版本,新版本会返回原数组)</small></p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/fast-async">Faster async functions and promises</a>:setTimeout\setImmediate(task),async/promise(microtask)、一般执行顺序<code>Promise > Mutate > setTimeout</code>。<code>await</code>的关键词比较接近<code>Promise.resolve().then()</code>(旧的标准,要求Promise在大部分时间都throwable),新标准只需要一个Promise即可。现阶段,await/async在chrome上已优于手写Promise代码。</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/spread-elements">Speeding up spread elements</a>:优化了<code>[...array]</code>的性能。假设值是array,会比其他对象能更快地析构(因为不需要创建复杂的Iterable)</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/trash-talk">Trash talk: the Orinoco garbage collector</a>:又一次介绍了现阶段的V8GC。GC三阶段:标记、清除、压缩。而V8的GC<code>Orinoco</code>则包含一些特性:并行,增量,并发。</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/jitless">JIT-less V8</a>:某些平台禁止非特权应用程序对可执行内存进行访问,导致V8无法分配修改可执行内存。V8添加无JIT模式的运行。</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/scanner">Blazingly fast parsing, part 1: optimizing the scanner</a>:介绍了V8快速解析JS代码的优化内容、空格扫描、标识符扫描(<a target="_blank" rel="noopener" href="https://en.wikipedia.org/wiki/Perfect_hash_function">Perfect hash function</a>)等。也对开发者给出了优化建议:减少源码、去除不必要空格、尽可能避免使用非ASCII标识符等。</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/code-caching-for-devs">Code caching for JavaScript developers</a>:介绍了V8的代码缓存(字节码级别,【参考41】),并提出了优化建议:若无必要,不要更新代码、请勿更改网址、少用A/B测试、提取公共代码库、分解大文件(eg:1MB)&合并小文件(eg:1Kb)、避免内敛脚本(无法利用缓存)、使用PWA缓存等的。<small>(感觉大多数建议并不实用,因为业务在大多数优先级优于代码性能)</small></p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/preparser">Blazingly fast parsing, part 2: lazy parsing</a>:介绍了V8惰性解析的应用,从而加快启动速度,减少内存开销。</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/spectre">A year with Spectre: a V8 perspective</a>:介绍了spectre漏洞发布后,V8一年的举动。</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/intl">Faster and more feature-rich internationalization APIs</a>:优复了国际性API的错误 以及优化 性能。</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/wasm-code-caching">Code caching for WebAssembly developers</a>:缓存WASM(128kb~150MB)</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/cost-of-javascript-2019">The cost of JavaScript in 2019</a>:介绍了2019V8版本的性能,得益于新的引擎,已大大减少了解析和编译的成本,目前前端瓶颈已经几种在网络下载上。并给出了一些建议:缩短下载时间,避免执行时间过长,避免大型内联脚本(建议1KB以内)。</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/emscripten-llvm-wasm">Emscripten and the LLVM WebAssembly backend</a>:后端将默认使用LLVM而不是fastcomp。(性能更优,大小更小)。emscripten(编译<a target="_blank" rel="noopener" href="https://www.ruanyifeng.com/blog/2017/09/asmjs_emscripten.html">asm.js</a>的工具),将支持编译webassembly,以达到更好的性能。</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/react-cliff">The story of a V8 performance cliff in React</a>:V8切换、弃用形状【参考28】,在React上带来了性能瓶颈。(V8推荐,不要再初始化时将数值字段设置为null,因为这样会放弃字段跟踪)</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-lite">A lighter V8</a>:V8的精简模式(指初始阶段,最终还是会回落到正常的版本),介绍了延迟反馈的实现</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/regexp-tier-up">Improving V8 regular expressions</a>:正则表达的分层策略(对高频使用的正则编译为本地机器码)</p></li><li><p><a target="_blank" rel="noopener" href="https://v8.dev/blog/emscripten-standalone-wasm">Outside the web: standalone WebAssembly binaries using</a>:尝试脱离JS运行<code>wasm</code></p></li></ol><h2 id="版本发布"><a href="#版本发布" class="headerlink" title="版本发布"></a>版本发布</h2><p>因博客中技术简介和发布信息混在一起,发布信息提取于此,顺带了解V8对JS语法的支持进度,以及ES5+语法。</p><p>值得一提,2019年,V8对WebAssembly投入了大量的资源,可以预测在不久的将来,一些对性能有一定要求的程序,也会在浏览器上运行起来。</p><ul><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-45">V8 release v4.5</a><em>(2015.06)</em>:支持了箭头函数<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions">Arrow Function</a>、<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array">Array.From & Array.of</a>、对象赋值<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/assign">Object.assign</a></li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-46">V8 release v4.6</a><em>(2015.08)</em>:支持了<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Spread_syntax">Spread operator</a>(展开)、<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/new.target">new.target</a><small>(没用过,囧,貌似对类的实现有帮助)</small>、避免<code>Jank</code><small>(主程序耗时过多导致界面卡顿,更新不及时)</small>,优化了<code>TypedArray</code></li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-47">V8 release v4.7</a><em>(2015.10)</em>:<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/rest_parameters">rest operator</a>(动态参数)、<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/includes">Array.prototype.includes</a></li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-48">V8 release v4.8</a><em>(2015.11)</em>:<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Symbol/isConcatSpreadable">Symbol.isConcatSpreadable</a>(声明数组concat的规则)、<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Symbol/@@toPrimitive">Symbol.toPrimitive</a>(一个对象的不同返回形式)</li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-49">V8 release v4.9</a><em>(2016.01)</em>:<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">Destructuring</a>(解构,<small>整了好多名词,然而和展开、动态参数都是一回事</small>)、<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy">P(roxies & Reflect</a><small>(<a target="_blank" rel="noopener" href="https://juejin.im/post/5acd0c8a6fb9a028da7cdfaf">Proxy 和 definedPropties不同</a>)</small>、<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-cn/docs/Web/JavaScript/Reference/Functions/Default_parameters">Default Parameters</a>(默认参数)、<a target="_blank" rel="noopener" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky">sticky flag</a>](<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky)%EF%BC%88reg%E7%B4%A2%E5%BC%95%E6%89%80%E5%A4%84%E4%BD%8D%E7%BD%AE%EF%BC%89">https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky)(reg索引所处位置)</a></li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-50">V8 release v5.0</a><em>(2016.03)</em>:Reg Unicode、优化了Object.keys</li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-51">V8 release v5.1</a><em>(2016.04)</em>:<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Symbol/species">Symbol.species</a>(更改对象类型,作用于<code>instanceof</code>)、<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Symbol/hasInstance">Symbol.hasInstance</a>:(拓展<code>instanceof</code>行为)、<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/values">Array.values</a></li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-52">V8 release v5.2</a><em>(2016.06)</em>:Exponentiation operator:求幂运算符(<code>let n = 3**3 // 27</code>)</li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-53">V8 release v5.3</a><em>(2016.07)</em>:优化了GC、启动速度、Promise</li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-54">V8 release v5.4</a><em>(2016.09)</em>:<code>Peak memory</code> & <code>average memory</code>,pm可能导致内存崩溃;同时运用了全局<a target="_blank" rel="noopener" href="https://en.wikipedia.org/wiki/Inline_caching">内联缓存</a>来优化启动性能</li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-55">V8 release v5.5</a><em>(2016.10)</em>:支持<code>sync</code>和<code>await</code></li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-56">V8 release v5.6</a><em>(2016.11)</em>:一些新的语法是构建在新的新的编译渠道</li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-57">V8 release v5.7</a><em>(2017.02)</em>:一系列优化、支持<strong>WebAssembly</strong></li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-58">V8 release v5.8</a><em>(2017.03)</em>:更具新的测量结果优化了代码</li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-59">V8 release v5.9</a><em>(2017.04)</em>:优化了WebAssembly的编译时间</li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-60">V8 release v6.0</a><em>(2017.06)</em>:引入<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer"><code>SharedArrayBuffer</code></a><small>(资料表明,该方法在最新的浏览器上因安全问题,<em>就是大名鼎鼎,导致所有现代计算器性能减少20%的BUG</em>,已被弃用)</small></li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-61">V8 release v6.1</a><em>(2017.08)</em>:优化了<em>Map</em>和<em>Set</em>的<code>forEach</code><small>(具体优化措施在于<a target="_blank" rel="noopener" href="https://benediktmeurer.de/2017/07/14/faster-collection-iterators/">此</a>,原迭代逻辑在C++端迭代,每次迭代都需要JS\C艹过渡,且需要创建迭代对象,优化后已全用JS实现,C艹仅负责GC,不过文章还指出在回调时仍然过渡的性能问题)</small>、<code>isPrototypeOf</code>、<code>Reflect.apply</code>和<code>Reflect.construct</code>、移除Crankshaft编译器从而减少700KB、</li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-62">V8 release v6.2</a><em>(2017.09)</em>:<a target="_blank" rel="noopener" href="https://ponyfoo.com/articles/investigating-performance-object-prototype-to-string-es2015">优化了<code>Object.toString</code></a>(预置标记位,不改动时走快速路径)、<code>String#includes</code></li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-63">V8 release v6.3</a>(2017.10):继续优化ES2015语法</li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-64">V8 release v6.4</a>(2017.11):优化<code>instanceof</code>、<code>WeakMap</code>和<code>WeakSet</code>(CSA),实现<code>import.meta</code>(嵌入式有关)、<code>formatToParts</code>(本地化有关)</li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-65">V8 release v6.5</a>(2018.01):引入<em>不可信代码模式</em>、完成WebAssembly流式编译、优化<code>indexof</code></li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-66">V8版本v6.6</a>(2018.03):<em>Function</em>的<code>toString</code>返回完整代码、catch可选参数、<code>trimStart & trimEnd</code>、实现<strong>冷加载(第一次、无任何缓存)、热负荷(第二次、缓存编译后的代码)、热加载(第三次,读取热负荷缓存的代码)</strong>【参考41】、后台编译、移除<em>AST numbering</em></li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-67">V8 release v6.7</a>(2018.03):默认启用BigInt【参考42】</li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-68">V8 release v6.8</a>(2018.06):减少<code>SFI</code>(类似于多次中间短暂的引用改变,会导致执行时间和内存增加),如<code>var a= b; b=temp; a=temp;</code></li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-69">V8 release v6.9</a>(2018.08):内置对象【参考44】、Liftoff Wasm编译器【参考45】、实现<em>Array.flat & Array.flatMap</em></li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-70">V8版本v7.0</a>(2018.10):嵌入式内置【参考44】、稳定的sort算法【参考48】</li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-71">V8 release v7.1</a>(2018.10):解析器字节码处理内嵌二进制、一些性能优化</li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-72">V8 release v7.2</a>(2018.11.18):增加<a target="_blank" rel="noopener" href="https://v8.dev/features/class-fields">公共字段</a>的支持</li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-73">V8 release v7.3</a>(2019.02):又又又优化了wasm、增加了<a target="_blank" rel="noopener" href="https://v8.dev/features/object-fromentries">Object.fromEntries</a>(需要确保键唯一,否则会有数据丢失)、<code>String.prototype.matchAll</code></li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-74">V8 release v7.4</a>(2019.03):支持无JIT模式【参考52】、支持<code>#</code>私有变量、一些局部优化</li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-75">V8 release v7.5</a>(2019.03):缓存<code>wasm</code>【参考58】、支持大容量内存操作、支持<a target="_blank" rel="noopener" href="https://v8.dev/features/numeric-separators">数字分隔符</a><code>100_000_000</code>。</li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-76">V8 release v7.6</a>(2019.06):新JSON解析器、优化<code>frozen</code>、<a target="_blank" rel="noopener" href="https://v8.dev/features/promise-combinators#promise.allsettled">Promise.allSettled</a>(所有Promise是否已完结)语法等</li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-77">V8 release v7.7</a>(2019.08):延迟反馈【参考62】、Intl.NumberFormat、优化<code>error.stack</code></li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-78">V8 release v7.8</a>(2019.09):尝试在HTML解析完成前,加载并以流的方式解析Js(但还未启用)、Regexp更快返回失败,优化wasm启动速度等</li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-79">V8 release v7.9</a>(2019.10):取消部分形状过渡、未安装IC下也能getter内置函数、OSR缓存(更早识别代码热点)</li><li><a target="_blank" rel="noopener" href="https://v8.dev/blog/v8-release-80">V8 release v8.0</a>(2019.12):压缩指针、<a target="_blank" rel="noopener" href="https://v8.dev/features/optional-chaining"><code>?.</code></a>可选连接语法、<a target="_blank" rel="noopener" href="https://v8.dev/features/nullish-coalescing"><code>??</code></a>语法(判断非false的类型)</li></ul></div></div></div><div class="more section"><div class="pre"><a class="article-link" href="/bey_2019_and_hi_2020.html"><i class="iconfont icon-right"></i> <span>2019年终将过去</span></a></div><div class="next"><a class="article-link" href="/optimize_docs.html">WEB文字性能优化简述 <i class="iconfont icon-right"></i></a></div></div></main></body><footer class="section fullscreen"><div class="footer-desc">Edeink © 2015-2022 · Powered by Hexo</div></footer><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script><script src="/public/js/init.js"></script></html>