菜单

Vue笔记六:Vue项指标习性优化之路

2019年9月16日 - JavaScript

XCel 项目总括:Electron 与 Vue 的质量优化

2017/03/01 · 基本功本领 ·
Javascript,
算法

本文我: 伯乐在线
刘健超-J.c
。未经小编许可,禁止转发!
应接参加伯乐在线 专辑作者

XCEL 是由京东客户体验设计部凹凸实验室推出的一个 Excel
数据清洗工具,其通过可视化的议程让客商轻易地对 Excel 数据开展筛选。

XCEL 基于 Electron 和 Vue 2.x,它不但跨平台(windows 7+、Mac 和
Linux),并且丰裕利用 Electron 多进度职分管理等职能,使其质量突出。

落地页:https://xcel.aotu.io/ ✨✨✨
体系地址:https://github.com/o2team/xcel ✨✨✨

Vue笔记六:Vue项指标特性优化之路

作者近年也平时面试外包同事。面试的时候,总会有个难点,“你说一下质量优化的一手”。十分八的人都会说,压缩js和css之类的。分明这么些都以必须做的,并且早就根本不是非常重要的天性优化的关键点。假设您只会说这一个,只可以证实您是个过时的前端技术员。

个性优化进度中,大家须求直面包车型大巴越来越多是DMS深入分析进度,服务器缓存和浏览器缓存机制。

品种背景

顾客探讨的定量商讨和轻量级数据管理中,均需对数码实行清洗处理,以剔除万分数据,保险数据结果的信度和效度。近日因应用商量数据和轻量级数据的多变性,对轻量级数据洗涤往往利用人工洗刷,缺乏统一、标准的洗濯流程,但对于调查商量和轻量级的多少往往是急需保险数据牢固性的,因而,在对数码举办洗濯时最佳有标准的洗刷情势。

gzip压缩

在装有的web前端项目,静态财富为主都坐落cdn上,gzip的回降是特别须求的,它直接更动了js文件的大小,收缩两到三倍。

参考加速nginx:
开启gzip和缓存
,nginx的gzip配置特别轻易,在您对号入座的域名底下,加多上面包车型地铁布置,重启服务就可以。gzip_comp_level的值抢先2的时候并不明了,建议安装在1照旧2以内。

# 开启gzip
gzip on;
# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
# gzip 压缩级别,1-10,数字越大压缩的越好,也越占用CPU时间,后面会有详细说明
gzip_comp_level 2;
# 进行压缩的文件类型。javascript有多种形式。其中的值可以在 mime.types 文件中找到。
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
# 是否在http header中添加Vary: Accept-Encoding,建议开启
gzip_vary on;
# 禁用IE 6 gzip
gzip_disable "MSIE [1-6]\.";

特征一览

服务器缓存

为了增长服务器获取数据的快慢,nginx缓存着静态能源是拾分须要的。假诺是测量检验服务器对html应该不设置缓存,而js等静态财富条件因为文件尾巴部分会加上二个hash值,这足以有效落实缓存的主宰。

location ~* ^.+\.(ico|gif|jpg|jpeg|png)$ { 
  access_log   off; 
  expires      30d;
}
location ~* ^.+\.(css|js|txt|xml|swf|wav)$ {
  access_log   off;
  expires      24h;
}
location ~* ^.+\.(html|htm)$ {
  expires      1h;
}

思路与落到实处

依照用研组的需要,利用 Electron 和 Vue 的表征对该工具进行支付。

浏览器缓存

浏览器缓存是透过html的头文件中的meta来决定。http-equiv是三个极其针对http的头文件,能够向浏览器传回一些可行的新闻。与之对应的content,是逐条参数的变量值。

技能选型

HTTP 1.0

在HTTP1.0中通过Pragma垄断(monopoly)页面缓存,能够安装为Pragmano-cache。在不让浏览器或中等缓存服务器缓存页面包车型大巴气象下,平时设置的值为no-cache,不过那个值不这么保证,平日还增多Expires置为0来达到指标。Expires能够用来设定网页的到期时间。一旦网页过期,必得到服务器上再度传输获取新的页面音信。PS:内容必需运用放线菌壮观素T的时间格式。

<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">

达成思路

  1. 透过 js-xlsx 将 Excel 文件分析为 JSON 数据
  2. 依照筛选规范对 JSON 数据开展筛选过滤
  3. 将过滤后的 JSON 数据转变到 js-xlsx 内定的数据结构
  4. 行使 js-xlsx 对转移后的数据生成 Excel 文件

纸上得来终觉浅,绝知那事要躬行

HTTP 1.1

在HTTP1.1中通过Cache-Control调节页面缓存,能够设置为no-cacheprivateno-storemax-agemust-revalidate等,默认为private。

<meta http-equiv="Cache-Control" content="no-cache">

有关本领

一经对某项本事相比熟识,则可略读/跳过。

Last-Modified和Etags

Last-Modified服务器端文件响应头,描述最终修改时间。当浏览器再一次开展呼吁时,会向服务器传送If-Modified-Since报头,询问时间点之后财富是还是不是被涂改过,进而区分200和304的央浼状态码,304则接纳浏览器缓存。

Etags差别的是,ETag是依靠实体内容生成一段hash字符串,是标志财富的情状。它由服务端发生来推断文件是不是有更新。

参谋资料:

Electron

JS分包

前方说的两片段都能够说是偏后端的活,要是真的在此之前端方面思索,大家大概会蕴藏入手。正因为vue的脚手架搭建的类型,webpack的配置个中就含有了压缩js,css和html的滑坡。所以,当大家的单页面越做越大的情况下,主要的一步正是包括。

vue官方称gzip压缩后唯有20kb,不过你平凡的打包方式也会有100kb,再加上你自身的逻辑代码,全部包的体量也挺大的。直接影响首屏页面加载的功效。下边介绍一下三种含有的主意:

Electron 是什么?

Electron 是二个方可用 JavaScript、HTML 和 CSS
构建桌面应用程序的。那个应用程序能打包到 Mac、Windows 和 Linux
系统上运营,也能上架到 Mac 和 Windows 的 App Store。

vue,vuex和vue-router

在webpack配置文件中external设置,把那多少个场用包排除那么些操作,首倘若把这多少个包从vendor.js分开。

谈到底当然要求在html标签上增加上额外cdn的link或然script。

为什么它如此首要?

平时来说,各类操作系统的桌面应用都由各自的原生语言举办编辑,那意味需要3 个团体分别为该应用编写相应版本。而 Electron 则允许你用 Web
语言编写壹遍就能够。

DLL打包

这种打包方式极度援用webpack官方的DllPluginDllReferencePlugin。DllPlugin会生成二个dll包的代码指纹manifest,管理额外的包裹。而在项目转移的长河中,DllReferencePlugin会参考manifest的剧情去打包。额外生成的js文件应当被放置在vue项目标公文个中的static文件夹底下,以便于代码计划。

参考PaicFE/vue-multi中的配置文件webpack.dll.config.js的写法。

它由哪些组成?

Electron 结合了 ChromiumNode.js 和用于调用操作系统本地效能的
API(如展开文件窗口、公告、Logo等)。

图片 1

预加载

预加载手艺(prefetch)是在客商必要前我们就将所需的能源加载完结,不是享有浏览器都援救,首假诺Chrome浏览器。

DNS prefetch
剖析这些页面需求的能源随处的域名,浏览器空闲时提前将那些域名转化为 IP
地址,真正诉求财富时就幸免了上述那几个进度的岁月。—-HTML5
prefetch

是因为域名调换来为IP的经过是不行耗费时间的一个进程,DNS
prefetch能够减掉那有个别的光阴。

<meta http-equiv='x-dns-prefetch-control' content='on'>
<link rel='dns-prefetch' href='http://g-ecx.images-amazon.com'>
<link rel='dns-prefetch' href='http://z-ecx.images-amazon.com'>
<link rel='dns-prefetch' href='http://ecx.images-amazon.com'>
<link rel='dns-prefetch' href='http://completion.amazon.com'>
<link rel='dns-prefetch' href='http://fls-na.amazon.com'>

预加载也得以对某些静态能源起到特其余职能。

<link rel='subresource' href='libs.js'>

预渲染(pre-rendering)是其一页面会提前加载好客商将在访谈的下二个页面。

<link rel='prerender' href='http://www.pagetoprerender.com'>

付出体验如何?

依赖 Electron 的支出就疑似在付出网页,况且能够无缝地 使用
Node
。可能说:在创设叁个 Node 应用的还要,通过 HTML 和 CSS
营造分界面。另外,你只需为三个浏览器(最新的
Chrome
)进行规划(即不要求思考包容性等)。

vue组件keep-alive

万一你做用一个巨型web的spa的时候,你有这几个router,对应的是成都百货上千个页面。在页面包车型大巴短平快切换中,为了确定保障页面加载的效用,除了缓存机制之外,vue的keep-alive组件能够帮的上忙。

它会把组件保存在浏览器内部存款和储蓄器个中,方便你飞快切换。

百度的lavas项目中就在vue-router其中使用keep-alive的零件,用它包裹着router-view。使用了keep-alive的组件内的多寡将会保留,“是或不是须求再行联合数据”能够在vue-router的钩中路由所带的参数实践判定。

八个进程(入眼)

Electron
有两种进度:『主进度』和『渲染进程』。部分模块只好在双边之一上运维,而有个别则无界定。主进度更加多地充当幕后剧中人物,而渲染进程则是应用程序的逐个窗口。

注:可由此任务管理器(PC)/活动监视器(Mac)查看进度的连锁新闻。

Promise请求

es6的内部一个特色就是原生支持promise。在此地,小编先不说异步编制程序里的generatoraync/await的性质。它们效能的兑现都以依据promise。

Promise的性状在于:

此地非常讲一下,ES6在品质优化上能够利用promise或然async/await去减少诉求时间。在过去,相当多jquery的页面在调用接口央浼都以八个接口等另一个接口,串行实行全部须求,最终在成就最后的回调函数,如此类推。那样的写法会直接形成“回调地狱”。即便你用vue-resource,作者也review到不行多的“回调鬼世界”的情形。为了从根本上解决这么些标题并抓牢开垦作用,笔者建议优先选择promise。(async/await不急着投入使用),考虑到还可能有好多同事还在高速地开辟业务代码。

现在的vue-resource曾经支撑promise的写法,为了更加好地让手艺向后发展,小编提议将pagekit/vue-resource轮换称为mzabriskie/axioswebmodules/jsonpaxios是可以并且满意服务端和浏览器端,同构的写法有利于未来将技巧栈往SSXC90(服务端渲染)发展。jsonp那些库则是为了包容jsonp的央求须要,须要对它举行了promise的包裹。

export function getJsonp(urlHost, key, data, _params) {
  return new Promise((resolve, reject) => {
    let url = urlHost + key;
    if (data) url += `?${querystring.stringify({ ...data, temp: new Date().getTime() })}`;
    const params = _params || { timeout: 15000 };
    if (!params.timeout) params.timeout = 15000;
    jsonp(url, params, (err, res) => {
      if (err) {
        reject(err);
      } else {
        resolve(res);
      }
    });
  });
}

Promise的施用须求防止以下的写法,

promise.then(function(value) {
  // success
}, function(error) {
  // failure
});

尽心竭力选取链式写法,

promise.then(function(value) {
  // step1
}).then(function(value){
  // step2
}).catch(function(value){
  // failure
})

相互的操作首假诺Promise.all(),它能够将Promise操作的数组并行推行达成然后在进展串行的操作。Promise.race()则是回到并行央浼中最早回到的哀求的相当结果。它们的应用能够有效地压缩数量获得的日子。

主进程

主进度,平常是一个命名称叫 main.js 的文件,该公文是每一种 Electron
应用的入口。它调控了采纳的生命周期(从张开到关闭)。它不只能调用原生成分,也能成立新的(八个)渲染进度。别的,Node
API 是停放个中的。

图片 2

推而广之阅读

转发,请阐明出处。总目录前段搜罗器

渲染进度

渲染进程是选用的二个浏览器窗口。与主进度不一样,它能存在多个(注:一个Electron
应用只能存在二个主进度)何况互相之间独立(它也能是隐藏的)。主窗口一般被取名字为
index.html。它们似乎超人的 HTML 文件,但 Electron 赋予了它们完整的
Node API。因而,那也是它与浏览器的分别。

图片 3

把它们想象成那样

Chrome(或其余浏览器)的每种标签页(tab)及其页面,就好比 Electron
中的二个独立渲染进度。纵然关闭全数标签页,Chrome 照旧留存。那好比
Electron 的主进度,能开采新的窗口或关闭那个利用。

注:在 Chrome
浏览器中,二个标签页(tab)中的页面(即除去浏览器本人部分,如寻找框、工具栏等)正是四个渲染进程。

图片 4

互相通信

鉴于主进度和渲染进度各自承担不一致的天职,而对于急需一块达成的职责,它们要求相互通信。IPC就为此而生,它提供了经过间的报导。但它不得不在主进度与渲染进程之间传递音讯(即渲染进度之间不能够打开直接通信)。

图片 5

汇成一句话

Electron 应用仿佛 Node 应用,它也依据二个 package.json
文件。该文件定义了哪个文件作为主进度,并据此让 Electron
知道从何运营应用。然后主进度能创造渲染进度,并能使用 IPC
让相互间进行音信传递。

图片 6

于今,Electron
的基础部分介绍实现。该有的是依靠我在此以前翻译的一篇作品《Essential
Electron》
,译文可点击
这里


Vue 全家桶

该工具使用了 Vue、Vuex、Vuex-router。在工具基本定型阶段,由 1.x 进级到了
2.x。

何以选用 Vue

对此作者来讲:

Vue 1.x -> Vue 2.0 的本子迁移用
vue-migration-helper
就可以深入分析出大部分供给改换的地点。

网阳春有相当的多有关 Vue 的科目,故在此不再赘言。至此,Vue 部分介绍完结。


js-xlsx

该库扶助各样石英手表格格式的分析与转移。它由 JavaScript 完成,适用于后边贰个和
Node。详情>>

脚下支撑读入的格式有(不断更新):

支撑写出的格式有:

前段时间该库提供的 sheet_to_json 方法能将读入的 Excel 数据转为 JSON
格式。而对此导出操作,大家须要为 js-xlsx 提供钦点的 JSON 格式。

越来越多关于 Excel 在 JavaScript
中管理的学问可查看凹凸实验室的《Node读写Excel文件商讨实施》。但该作品存在两处难点(均在
js-xlsx 实战的导出表格部分):

  1. 扭转底部时,Excel 的列音信轻便地通过 String.fromCharCode(65+j)
    生成。当列大于 26 时会出现难题。那么些标题会在末端章节中付出施工方案;
  2. 转变到 worksheet
    须求的构造处,出现逻辑性错误,并且会促成严重的性格难点。逻辑难题在此不陈诉,大家看看质量难点:
    随着 ECMAScript 的不断更新,JavaScript
    变得进一步强有力和易用。固然如此,大家依旧要完结『物尽所用』,而不要『大材小用』,不然大概会拿走“反效果”。这里导致品质难点的难为
    Object.assign()
    方法,该方式能够把自由多少个源对象的可枚举属性拷贝至指标对象,并回到指标对象。由于该办法本人的贯彻机制,会在此案例中发出多量的冗余操作。在该案例中,单元格音讯是独一的,所以直接通过
    forEach 为贰个空对象赋值就可以。升高 N
    倍质量的还要,也把逻辑性错误化解了。

原来的:

JavaScript

var result = 某数组.reduce((prev, next) => Object.assign({}, prev,
{[next.position]: {v: next.v}}), {});

1
2
var result = 某数组.reduce((prev, next) =&gt; Object.assign({}, prev, {[next.position]: {v: next.v}}), {});
 

改为:

JavaScript

var result = 某数组.forEach((v, i) => data[v.position]= {v: v.v})

1
2
var result = 某数组.forEach((v, i) =&gt; data[v.position]= {v: v.v})
 

举行是检察真理的独一标准

在知情上述知识后,下边就谈谈在该类型推行中计算出来的本事、难题和首要性

CSS、JavaScript 和 Electron 相关的文化和技巧

高亮 table 的列

Excel 单元格选择 table 标签展现。在 Excel
中,被选中的单元格会高亮相应的『行』和『列』,以指示客户。在该利用中也会有做相应的拍卖,横向高亮接纳
tr:hover 达成,而纵向呢?这里所采取的多个本事是:

一经 HTML 结构如下:

JavaScript

div.container table tr td

1
2
3
4
5
div.container
  table
    tr
      td
 

CSS 代码如下:

JavaScript

.container { overflow:hidden; } td { position: relative; }
td:hover::after { position: absolute; left: 0; right: 0; top: -1个亿px;
// 小指标达成,可是是负的😭 bottom: -1个亿px; z-index: -1; //
制止遮住小编和同列 td 的内容、border 等 }

1
2
3
4
5
6
7
8
9
10
11
.container { overflow:hidden; }
td { position: relative; }
td:hover::after {
  position: absolute;
  left: 0;
  right: 0;
  top: -1个亿px; // 小目标达成,不过是负的&#x1f62d;
  bottom: -1个亿px;
  z-index: -1; // 避免遮住自身和同列 td 的内容、border 等
}
 

斜分水岭

如图:图片 7

分界线能够透过 ::after/::before 伪类成分完结一条直线,然后经过
transform:rotate();
旋转特定角度完毕。但这种完成的贰个标题是:由于宽度是不定的,由此须求通过
JavaScript 运算手艺博得可相信的对角分水线。

为此,这里能够透过 CSS 线性渐变
linear-gradient(to top right, transparent, transparent calc(50% - .5px), #d3d6db calc(50% - .5px), #d3d6db calc(50% + .5px), transparent calc(50% + .5px))
完成。无论宽高怎样变,依旧妥妥地自适应。

Excel 的列转变

JavaScript

// 将盛传的当然数转换为26进制表示。映射关系:[0-25] -> [A-Z]。
function getCharCol(n) { let temCol = ”, s = ”, m = 0 while (n >=
0) { m = n % 26 + 1 s = String.fromCharCode(m + 64) + s n = (n – m) / 26
} return s }

1
2
3
4
5
6
7
8
9
10
11
12
13
// 将传入的自然数转换为26进制表示。映射关系:[0-25] -&gt; [A-Z]。
function getCharCol(n) {
  let temCol = ”,
    s = ”,
    m = 0
  while (n &gt;= 0) {
    m = n % 26 + 1
    s = String.fromCharCode(m + 64) + s
    n = (n – m) / 26
  }
  return s
}
 

JavaScript

// 将盛传的26进制调换为自然数。映射关系:[A-Z] ->[0-25]。
function getNumCol(s) { if (!s) return 0 let n = 0 for (let i = s.length

1
2
3
4
5
6
7
8
9
10
11
12
// 将传入的26进制转换为自然数。映射关系:[A-Z] -&gt;[0-25]。
function getNumCol(s) {
  if (!s) return 0
  let n = 0
  for (let i = s.length – 1, j = 1; i &gt;= 0; i–, j *= 26) {
    let c = s[i].toUpperCase()
    if (c &lt; ‘A’ || c &gt; ‘Z’) return 0
    n += (c.charCodeAt() – 64) * j
  }
  return n – 1
}
 

为 DOM 的 File 对象扩展了 path 属性

Electron 为 File 对象额外增了 path
属性,该属性可收获文件在文件系统上的忠实路线。由此,你能够采用 Node
作威作福。应用场景有:拖拽文件后,通过 Node 提供的 File API
读取文件等。

支撑周围的编纂功效,如粘贴和复制

Electron 应用在 MacOS
中私下认可不协理『复制』『粘贴』等科学普及编辑功能,因而要求为 MacOS
显式地安装复制粘贴等编写制定成效的菜单栏,并为此设置相应的飞速键。

JavaScript

// darwin 就是 MacOS if (process.platform === ‘darwin’) { var template =
[{ label: ‘FromScratch’, submenu: [{ label: ‘Quit’, accelerator:
‘CmdOrCtrl+Q’, click: function() { app.quit(); } }] }, { label: ‘Edit’,
submenu: [{ label: ‘Undo’, accelerator: ‘CmdOrCtrl+Z’, selector:
‘undo:’ }, { label: ‘Redo’, accelerator: ‘Shift+CmdOrCtrl+Z’, selector:
‘redo:’ }, { type: ‘separator’ }, { label: ‘Cut’, accelerator:
‘CmdOrCtrl+X’, selector: ‘cut:’ }, { label: ‘Copy’, accelerator:
‘CmdOrCtrl+C’, selector: ‘copy:’ }, { label: ‘Paste’, accelerator:
‘CmdOrCtrl+V’, selector: ‘paste:’ }, { label: ‘Select All’, accelerator:
‘CmdOrCtrl+A’, selector: ‘selectAll:’ }] }]; var osxMenu =
menu.buildFromTemplate(template); menu.setApplicationMenu(osxMenu); }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// darwin 就是 MacOS
if (process.platform === ‘darwin’) {
    var template = [{
      label: ‘FromScratch’,
      submenu: [{
        label: ‘Quit’,
        accelerator: ‘CmdOrCtrl+Q’,
        click: function() { app.quit(); }
      }]
    }, {
      label: ‘Edit’,
      submenu: [{
        label: ‘Undo’,
        accelerator: ‘CmdOrCtrl+Z’,
        selector: ‘undo:’
      }, {
        label: ‘Redo’,
        accelerator: ‘Shift+CmdOrCtrl+Z’,
        selector: ‘redo:’
      }, {
        type: ‘separator’
      }, {
        label: ‘Cut’,
        accelerator: ‘CmdOrCtrl+X’,
        selector: ‘cut:’
      }, {
        label: ‘Copy’,
        accelerator: ‘CmdOrCtrl+C’,
        selector: ‘copy:’
      }, {
        label: ‘Paste’,
        accelerator: ‘CmdOrCtrl+V’,
        selector: ‘paste:’
      }, {
        label: ‘Select All’,
        accelerator: ‘CmdOrCtrl+A’,
        selector: ‘selectAll:’
      }]
    }];
    var osxMenu = menu.buildFromTemplate(template);
    menu.setApplicationMenu(osxMenu);
}
 

更贴近原生应用

Electron
的一个短处是:即便你的选拔是叁个总结的石英钟,但它也只可以富含完整的根底设备(如
Chromium、Node
等)。由此,一般景色下,打包后的程序至少会高达几十兆(依照系统项目实行转换)。当你的使用越复杂,就越能够忽略文件容积难点。

明朗,页面包车型客车渲染难免会导致『白屏』,并且这里运用了 Vue
那类框架,情状就特别不佳了。别的,Electron
应用也制止不了『先开垦浏览器,再渲染页面』的步子。上边提供三种形式来减轻这种状态,以让程序更邻近原生应用。

  1. 钦定 BrowserWindow 的背景颜色;
  2. 先掩盖窗口,直到页面加载后再凸显;
  3. 封存窗口的尺码和岗位,以让程序后一次被张开时,照旧保留的同样大小和产出在平等的职位上。

对此第一点,若选择的背景不是黄色(#fff)的,那么可钦命窗口的背景颜色与其同一,防止止渲染后的急转直下。

JavaScript

mainWindow = new BrowserWindow({ title: ‘XCel’, backgroundColor:
‘#f5f5f5’, };

1
2
3
4
5
mainWindow = new BrowserWindow({
    title: ‘XCel’,
    backgroundColor: ‘#f5f5f5’,
};
 

对此第二点,由于 Electron
本质是多个浏览器,必要加载非网页部分的能源。因而,大家得以先遮盖窗口。

JavaScript

var mainWindow = new BrowserWindow({ title: ‘ElectronApp’, show: false,
};

1
2
3
4
5
var mainWindow = new BrowserWindow({
    title: ‘ElectronApp’,
    show: false,
};
 

等到渲染进度开端渲染页面包车型的士那一刻,在 ready-to-show
的回调函数中显得窗口。

JavaScript

mainWindow.on(‘ready-to-show’, function() { mainWindow.show();
mainWindow.focus(); });

1
2
3
4
5
mainWindow.on(‘ready-to-show’, function() {
    mainWindow.show();
    mainWindow.focus();
});
 

对此第三点,作者并不曾兑现,原因如下:

  1. 顾客一般是基于当时的情形对前后相继的尺码和岗位举办调度,即视情状而定。
  2. 以上是自己个人臆断,重如若本人懒。

其达成格局,可参照《4 must-know tips for building cross platform
Electron
apps》

什么在渲染进度调用原生弹框?

在渲染进程中调用原来专项于主进度中的 API (如弹框)的方式有三种:

  1. IPC 通讯模块:先在主进度通过 ipcMain 进行监听,然后在渲染过程经过
    ipcRenderer 实行接触;
  2. remote 模块:该模块为渲染进度和主进度之间提供了迅猛的简报情势。

对于第二种方法,在渲染进度中,运行以下代码就能够:

JavaScript

const remote = require(‘electron’).remote remote.dialog.showMessageBox({
type: ‘question’, buttons: [‘不报告你’, ‘未有梦想’], defaultId: 0,
title: ‘XCel’, message: ‘你的企盼是何等?’ }

1
2
3
4
5
6
7
8
9
10
const remote = require(‘electron’).remote
 
remote.dialog.showMessageBox({
  type: ‘question’,
  buttons: [‘不告诉你’, ‘没有梦想’],
  defaultId: 0,
  title: ‘XCel’,
  message: ‘你的梦想是什么?’
}
 

自动更新

假诺 Electron
应用尚未提供自动更新作用,那么就象征顾客想体验新开垦的成效或用上修复
Bug
后的新本子,只可以靠客户自身主动地去官方网站下载,那确实是倒霉的体会。Electron
提供的 autoUpdater
模块可完毕自动更新作用,该模块提供了第三方框架
Squirrel 的接口,但 Electron 最近只内置了
Squirrel.Mac,且它与
Squirrel.Windows(需要额外引入)的管理格局也区别样(在客商端与劳动器端双方面)。因而一旦对该模块不熟谙,处理起来会相对相比较麻烦。具体能够参见我的另一篇译文《Electron
自动更新的全部教程(Windows 和
OSX)》

脚下 Electron 的 autoUpdater 模块不支持 Linux 系统。

别的,XCel 近年来并未运用 autoUpdater 模块实现自动更新效用,而是利用
Electron 的
DownloadItem
模块达成,而服务器端则使用了 Nuts

为 Electron 应用生成 Windows 安装包

通过 electron-builder 可径直扭转常见的
MacOS 安装包,但它生成的 Windows 的安装包却略显简洁(暗许选项时)。

图片 8
Mac 常见的安装方式,将“左侧的接纳图标”拖拽到“右边的 Applications”就能够

经过 electron-builder 生成的 Windows 安装包与大家在 Windows
上常见的软件安装分界面不太一致,它并未有设置向导和点击“下一步”的开关,独有一个安装时的
gif 动画(私下认可的 gif 动画如下图,当然你也足以钦点特定的 gif
动画),由此也就停业了客户选取设置路径等权利。

图片 9
Windows 安装时 暗中认可展现的 gif
动画

一旦您想为打包后的 Electron 应用(即由此electron-packager/electron-builder
生成的,可直接运转的次序目录)生成具备一些击“下一步”开关和可让顾客指虞升卿装路线的宽林芝装包,能够尝试
NSIS 程序,具体可看那篇教程 《[教學]只要10分鐘學會使用 NSIS
包裝您的桌面軟體–安裝程式打包。完全免費。》

注:electron-builder
也提供了转移安装包的配备项,切切实实查看>>

NSIS(Nullsoft Scriptable Install System)是多少个开源的 Windows
系统下安装程序制作程序。它提供了设置、卸载、系统装置、文件解压缩等效能。正如其名字所汇报的那么,NSIS
是经过它的脚本语言来陈说安装程序的一言一动和逻辑的。NSIS
的脚本语言和普及的编制程序语言有近似的布局和语法,但它是为安装程序那类应用所布置的。

由来,CSS、JavaScript 和 Electron 相关的知识和本领部分演说实现。


属性优化

上边谈谈『品质优化』,那有些关联到运作功效内部存储器占用量
注:以下内容均基于 Excel 样例文件(数据量为:一九一二 行 x 180
列)得出的定论。

推行效能和渲染的优化

Vue 品质真的好?

Vue 平昔标榜着本人品质卓越,但当数据量上涨到一定量级时(如 一九一四 x 180 ≈
34 万个数据单元),会产出严重的属性难题(未做相应优化的前提下)。

如直接通过列表渲染 v-for 渲染数据时,会招致程序卡死。
答:通过翻占星关资料可得, v-for
在第一渲染时,须求对各种子项进行开头化(如数据绑定等操作,以便具备更加快的翻新速度),这对于数据量很大时,无疑会促成严重的品质难题。

随即,笔者想开了二种缓慢解决思路:

  1. Vue 是数量驱动视图的,对数码分段 push,将在三个庞然大物的职分分割为 N
    份。
  2. 团结拼接 HTML 字符串,再通过 innerHTML 叁遍性插入。

末段,笔者选用了第二条,理由是:

  1. 品质最棒,因为每回推行多少过滤时,Vue 都要开展 diff,品质不好。
  2. 更合乎当下使用的要求:纯体现且不要求动画过渡等。
  3. 贯彻更简约

将原先繁重的 DOM 操作(Vue)转变为 JavaScript
的拼接字符串后,品质获得了异常的大进级(不会招致程序卡死而渲染不出视图)。这种优化措施难道不便是Vue、React
等框架消除的主题材料之一吧?只但是框架思考的现象更广,有些地点需求大家温馨依据实际景况张开优化而已。

在浏览器当中,JavaScript 的演算在现代的引擎中不慢,但 DOM
本人是非常缓慢的东西。当您调用原生 DOM API 的时候,浏览器须要在
JavaScript 引擎的语境下去接触原生的 DOM
的兑现,那么些历程有一定的性质损耗。所以,本质的勘查是,要把耗时的操作尽量放在纯粹的测算中去做,保障最后总结出来的内需实际接触实际
DOM 的操作是最少的。 —— 《Vue
2.0——渐进式前端建设方案》

自然,由于 JavaScript
天生单线程,就算实行数速度再快,也难免会导致页面有短暂的年华不容客商的输入。此时可通过
Web Worker 或任何情势减轻,那也将是大家一连讲到的主题素材。

也是有网络基友提供了优化一大波列表的法子:https://clusterize.js.org/。但在本案例中小编并不曾使用此方法。

强大的 GPU 加速

将拼接的字符串插入 DOM
后,出现了另外叁个主题素材:滚动会很卡。猜想那是渲染难题,终归 34
万个单元格同一时候存在于分界面中。

添加 transform: translate3d(0, 0, 0) / translateZ(0) 属性运维 GPU
渲染,就可以解决这几个渲染品质难题。再一次惊讶该属性的精锐。

新兴,考虑到客户并不要求查看全部数码,只需出示部分数据让用户张开参照他事他说加以考察就能够。大家对此只渲染前
30/50 行数据。这样就可以提高客户体验,也能更加的优化质量。

纪念关闭 Vuex 的严苛形式

别的,由于投机学艺不精和疏于,忘记在生养条件关闭 Vuex
的『严俊方式』。

Vuex 的严加情势要在生产情况中关闭,不然会对 state 树进行一个深观望(deep
watch),产生不必要的个性损耗。恐怕在数据量少时,不会注意到那几个标题。

复苏当时的光景:导入 Excel 数据后,再开展相互(涉及 Vuex
的读写操作),须求等几秒才会响应,而平素通过纯 DOM
监听的平地风波则无此难点。由此,剖断出是 Vuex 难题。

JavaScript

const store = new Vuex.Store({ // … strict: process.env.NODE_ENV !==
‘production’ })

1
2
3
4
5
const store = new Vuex.Store({
  // …
  strict: process.env.NODE_ENV !== ‘production’
})
 

多进程!!!

前面说道,JavaScript
天生单线程,纵然再快,对于数据量相当的大时,也会油然则生拒绝响应的难题。因而须求Web Worker 或近似的方案去消除。

在此地自身不选拔 Web worker 的原由有如下几点:

  1. 有别的更加好的代表方案:二个主进度能创制八个渲染进度,通过 IPC
    就可以进展多少交互;
  2. Electron 不援救 Web
    Worker!(当然,恐怕会在新本子支持,最新信息请关心官方)

Electron 作者在 2016.11.7 在《state of web worker support?》 issue
中还原了以下这一段:

Node integration doesn’t work in web workers, and there is no plan to
do. Workers in Chromium are implemented by starting a new thread, and
Node is not thread safe. Back in past we had tried to add node
integration to web workers in Atom, but it crashed too easily so we
gave up on it.

就此,大家最后利用了成立四个新的渲染进度 background process
进行拍卖数量。由 Electron 章节可知,每种 Electron
渲染进程是独立的,由此它们不会相互影响。但那也推动了贰个难点:它们不可能相互通讯?

错!下边有 3 种格局实行广播发表:

  1. Storage
    API
    :对有些标签页的
    localStorage/sessionStorage 对象举行增删改时,别的标签页能由此window.storage 事件监听到。
  2. IndexedDB:IndexedDB
    是一个为了能够在顾客端存款和储蓄可观数额的结构化数据,况兼在这几个数量上应用索引进行高质量检索的
    API。
  3. 通过主进程作为中间转播站:设主分界面包车型大巴渲染进程是 A,background process
    是 B,那么 A 先将 Excel 数据传递到主进度,然后主进度再倒车到 B。B
    管理完后再原路重返,具体如下图。当然,也能够将数据存款和储蓄在主进度中,然后在多个渲染进度中应用
    remote 模块来寻访它。

该工具采用了第三种办法的第一种情况:
图片 10

1、主页面渲染进度 A 的代码如下:

JavaScript

//① ipcRenderer.send(‘filter-start’, { filterTagList:
this.filterTagList, filterWay: this.filterWay, curActiveSheetName:
this.activeSheet.name }) // ⑥ 在某处接收 filter-response 事件
ipcRenderer.on(“filter-response”, (arg) => { // 得随地理数据 })

1
2
3
4
5
6
7
8
9
10
11
12
//①
ipcRenderer.send(‘filter-start’, {
    filterTagList: this.filterTagList,
    filterWay: this.filterWay,
    curActiveSheetName: this.activeSheet.name
})
 
// ⑥ 在某处接收 filter-response 事件
ipcRenderer.on("filter-response", (arg) =&gt; {
    // 得到处理数据
})
 

2、作为中间转播站的主进度的代码如下:

JavaScript

//② ipcMain.on(“filter-start”, (event, arg) => { // webContents
用于渲染和垄断(monopoly) web page
backgroundWindow.webContents.send(“filter-start”, arg) }) // ⑤
用于收纳重返事件 ipcMain.on(“filter-response”, (event, arg) => {
mainWindow.webContents.send(“filter-response”, arg) })

1
2
3
4
5
6
7
8
9
10
11
//②
ipcMain.on("filter-start", (event, arg) =&gt; {
    // webContents 用于渲染和控制 web page
    backgroundWindow.webContents.send("filter-start", arg)
})
 
// ⑤ 用于接收返回事件
ipcMain.on("filter-response", (event, arg) =&gt; {
    mainWindow.webContents.send("filter-response", arg)
})
 

3、管理繁重数据的 background process 渲染进度 B 的代码如下:

JavaScript

// ③ ipcRenderer.on(‘filter-start’, (event, arg) => { // 举办演算 …
// ④ 运算完成后,再经过 IPC 原路重返。主进度和渲染进程 A
也要建构相应的监听事件 ipcRenderer.send(‘filter-response’, { filRow:
tempFilRow }) })

1
2
3
4
5
6
7
8
9
10
11
// ③
ipcRenderer.on(‘filter-start’, (event, arg) =&gt; {
    // 进行运算
    …
 
    // ④ 运算完毕后,再通过 IPC 原路返回。主进程和渲染进程 A 也要建立相应的监听事件
    ipcRenderer.send(‘filter-response’, {
        filRow: tempFilRow
    })
})
 

迄今结束,大家将『读取文件』、『过滤数据』和『导出文件』三大耗费时间的数量操作均转移到了
background process 中处理。

此间,大家只创设了贰个
background process,假设想要做得更极致,我们能够新建『CPU 线程数- 1 』
个的 background process
同偶尔间对数据开展管理,然后在主进程对拍卖后数据举行拼接,最后再将拼接后的数据再次回到到主页面包车型客车渲染进程。那样就能够足够榨干
CPU 了。当然,在此作者不会议及展览开这么些优化。

决不为了优化而优化,不然轻重颠倒。 —— 某网络朋友

内部存款和储蓄器据有量过大

化解了推行功效和渲染难点后,开采也设有内部存储器占用量过大的主题素材。当时疑心是以下多少个原因:

  1. 三大耗费时间操作均放置在 background process
    管理。在简报传递数据的长河中,由于不是分享内部存款和储蓄器(因为 IPC 是依照Socket
    的),导致出现多份数据别本(在写那篇作品时才有了那相对方便的答案)。
  2. Vuex
    是以三个大局单例的形式进行保管,但它会是不是对数据做了一点封装,而招致质量的损耗呢?
  3. 鉴于 JavaScript
    近来不具备积极回收财富的手艺,所以只可以积极对闲置对象设置为
    null,然后等待 GC 回收。

出于 Chromium 选取多进程架构,由此会提到到进度间通讯难点。Browser
进度在起步 Render 进程的经过中会建设构造贰个以 UNIX Socket 为底蕴的 IPC
通道。有了 IPC 通道之后,接下去 Browser 进度与 Render
进度就以音信的样式开展通讯。咱们将这种音信称为 IPC
音信,以分别于线程音信循环中的音信。
——《Chromium的IPC音信发送、接收和分发机制剖判》

概念:为了轻巧明白,以下『Excel 数据』均指 Excel 的成套使得单元格转为
JSON 格式后的数目。

最轻易管理的实地是第三点,手动将不再供给的变量及时安装为
null,但功效并不分明。

后来,通过操作系统的『活动监视器』(Windows
上是任务管理器)对该工具的每阶段(展开时、导入文本时、筛选时和导出时)举行简单的内部存款和储蓄器解析,获得以下报告:

—————- S:报告分水岭 —————-
经观望,首要耗内部存款和储蓄器的是页面渲染进度。上边通过截图评释:
PID 15243 是主进程
PID 15246 是页面渲染进度
PID 15248 是 background 渲染进度

a、第三回开发银行程序时(第 4 行是主进程;第 1 行是页面渲染进度;第 3 行是
background 渲染进程 )

图片 11

b、导入文本(第 5 行是主进度;第 2 行是页面渲染进度;第 4 行是
background 渲染进程 )
图片 12

c、筛选数据(第 4 行是主进度;第 1 行是页面渲染进度;第 3 行是
background 渲染进度 )
图片 13

鉴于 JavaScript 方今不持有积极回收财富的法力,所以不得不积极将指标设置为
null,然后等待 GC 回收。

于是,经过一段时间等待后,内部存款和储蓄器占用如下:
d、一段时间后(第 4 行是主进度;第 1 行是页面渲染进度;第 3 行是
background 渲染进度 )
图片 14

由上述可得,页面渲染进度由于页面成分和 Vue 等 UI
相关财富是定点的,占用内部存款和储蓄器异常的大且不可能回收。主进程占用资源也不能够获得很好释放,一时半刻不知晓源委,而
background 渲染进程则较好地释放财富。

—————- E:报告分水线 —————-

听他们说报告,先导得出的定论是 Vue 和通信时占用财富十分大。

依附该工具的实际上选取场景:Excel
数据只在『导入』和『过滤后』三个阶段需求出示,况且突显的是由此JavaScript 拼接的 HTML 字符串所结合的 DOM 而已。由此将表格数据放置在
Vuex 中,有一点滥用财富的可疑。

另外,在 background process 中也可以有存有一份 Excel
数据副本。因而,索性只在 background process 存款和储蓄一份 Excel
数据,然后每当数据变动时,通过 IPC 让 background process 再次来到拼接好的
HTML
字符串就能够。那样一来,内部存款和储蓄器占领量立即跌落大多。别的,那也是贰个一举多得的优化:

  1. 字符串拼接操作也转移到了
    background process,页面渲染进度进一步回降低消耗费时间的操作;
  2. 内部存款和储蓄器据有量大大减小,响应速度也博得了进级。

实在,那也许有一点点像 Vuex 的『全局单例格局管理』,一份数据就好。

本来,对于 Excel 的主旨音讯,如行列数、SheetName、标题组等均照旧保留在
Vuex。

优化后的内部存款和储蓄器占领量如下图。与上述报告的第三张图比较(同一品级),内存据有量下落了
44.419%: 图片 15
其它,对于不必要响应的数据,可通过 Object.freeze()
冻结起来。那也是一种优化花招。但该工具近日并从未运用到。

迄今截至,优化部分也解说实现了!


该工具近年来是开源的,应接我们使用或引入给用研组等有亟待的人。

你们的举报(可提交 issues /
pull
request
)能让这么些工具在使用和作用上不断完善。

最后,感谢 LV
在成品设计、分界面设计和优化上的武力帮忙。全文完!

打赏扶助笔者写出越多好小说,感激!


打赏笔者

打赏协助小编写出愈来愈多好作品,感激!

任选一种支付办法

图片 16
图片 17

1 赞 2 收藏
评论

关于笔者:刘健超-J.c

图片 18

前端,在路上…http://jchehe.github.io
个人主页
·
作者的小说
·
19
·
    

图片 19

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图