WijmoJS 使用Web Workers技术,让前端 PDF 导出效率更高效
概述
Web Workers是一种Web标准技术,允许在后台线程中执行脚本处理。 WijmoJS 的2018v3版本引入了Web Workers技术,以便在生成PDF时提高应用程序的运行速度。
一般来说,JavaScript脚本在主线程中执行,由同一个线程处理UI呈现。因此繁重的JavaScript处理可能会阻止UI呈现,轻者会导致用户无法与屏幕交互; 在最严重的情况下,UI绘图过程停止太长时间,浏览器会抛出异常警告。
传统方式:在没有Web Worker的情况下处理PDF
在下面的动画中,您将看到我们以传统方式将100,000行数据保存到PDF。 主线程运行了很长时间,同时,UI冻结,我们看到了异常警告提示。(这段动画是以4倍的速度播放的)
在这种情况下,用户无法取消PDF的生成过程。 此外,只要UI被冻结,我们就无法更改按钮的状态或显示其他有用的信息,比如进度情况。 用户只能等待很长时间,造成不满意的用户体验。
全新方式:利用Web Workers改善用户体验
Web Workers解决了上述问题。 以下是Web Workers在处理相同数据量的表现:
虽然繁重的数据处理仍然需要很长时间,但用户可以随时取消处理(从而避免异常警告)。 此外,我们可以更改按钮状态并显示当前进度,为用户提供重要的反馈。
Web Workers示例
让我们看看下面的示例,该应用程序将压缩100,000个表格数据到3,500页的PDF 中 - 这是一个体积庞大的文档。 (我建议在Chrome上运行它。)
要正常执行Web Worker,请创建一个定义Web Worker进程的JavaScript文件。 然后读取JS文件,并执行Web Worker。 为了更好地体验,请务必在WijmoJS 2018 v3中下载本示例。
HTML:
<div class="container">
<h1>Web Worker</h1>
<p>Generate PDF documents in the background.</p>
<p>By using Web Workers, we can generate PDF documents in a separate thread from the UI thread. This allows the application to be usable while the PDF is generated in the background. Otherwise, the application would freeze until the PDF is generated. For large documents, this could be a minute or even longer.</p>
<label for="rowCount">Number of Rows</label>
<select id="rowCount">
<option value="10000">10,000</option>
<option value="100000">100,000</option>
</select><br>
<button id="saveButton1" class="btn btn-default">Create PDF(using Web Worker)</button>
<button id="saveButton2" class="btn btn-default">Create PDF(without Web Worker)</button><br>
<div id="progressGauge"></div>
<span id="progressText">0</span>% Done
<div id="flexGrid"></div>
</div>
JavaScript:
var productNames = "Chai,Chang,Guaraná Fantástica,Sasquatch Ale,Steeleye Stout,Côte de Blaye,Chartreuse verte,Ipoh Coffee,Laughing Lumberjack Lager,Outback Lager,Rhönbräu Klosterbier,Lakkalikööri,Aniseed Syrup,Chef Anton's Cajun Seasoning,Chef Anton's Gumbo Mix,Grandma's Boysenberry Spread,Northwoods Cranberry Sauce,Genen Shouyu,Gula Malacca,Sirop d'érable,Vegie-spread,Louisiana Fiery Hot Pepper Sauce,Louisiana Hot Spiced Okra,Original Frankfurter grüne Soße,Pavlova,Teatime Chocolate Biscuits,Sir Rodney's Marmalade,Sir Rodney's Scones,NuNuCa Nuß-Nougat-Creme,Gumbär Gummibärchen,Schoggi Schokolade,Zaanse koeken,Chocolade,Maxilaku,Valkoinen suklaa,Tarte au sucre,Scottish Longbreads,Queso Cabrales,Queso Manchego La Pastora,Gorgonzola Telino,Mascarpone Fabioli,Geitost,Raclette Courdavault,Camembert Pierrot,Gudbrandsdalsost,Fløtemysost,Mozzarella di Giovanni,Gustaf's Knäckebröd,Tunnbröd,Singaporean Hokkien Fried Mee,Filo Mix,Gnocchi di nonna Alice,Ravioli Angelo,Wimmers gute Semmelknödel,Mishi Kobe Niku,Alice Mutton,Thüringer Rostbratwurst,Perth Pasties,Tourtière,Pâté chinois,Uncle Bob's Organic Dried Pears,Tofu,Rössle Sauerkraut,Manjimup Dried Apples,Longlife Tofu,Ikura,Konbu,Carnarvon Tigers,Nord-Ost Matjeshering,Inlagd Sill,Gravad lax,Boston Crab Meat,Jack's New England Clam Chowder,Røgede sild,Spegesild,Escargots de Bourgogne,Röd Kaviar".split(",");
var rowCount = document.getElementById('rowCount');
var saveButton1 = document.getElementById('saveButton1');
var saveButton2 = document.getElementById('saveButton2');
var progressGauge = new wijmo.gauge.LinearGauge('#progressGauge', {
value: 0
});
var progressText = document.getElementById('progressText');
var isExporting = false;
var flexGrid = new wijmo.grid.FlexGrid('#flexGrid', {
itemsSource: orders(rowCount.value)
});
flexGrid.columns[1].width = 200;
rowCount.addEventListener('change', function() {
flexGrid.collectionView.sourceCollection = orders(rowCount.value);
});
// Create web worker
var cdn = 'https://demo.grapecity.com/wijmo/beta/controls/';
var script =
"importScripts('" + cdn + "wijmo.min.js');" +
"importScripts('" + cdn + "wijmo.pdf.min.js');" +
"importScripts('" + cdn + "wijmo.grid.pdf.min.js');" +
"wijmo.grid.pdf.PdfWebWorker.initExportGrid();";
var blob = new Blob([script], { type:'text/javascript' });
var worker;
// Create PDF using Web Worker
saveButton1.addEventListener('click', function() {
if (!isExporting) {
// Execute PDF generation processing
isExporting = true;
saveButton1.innerText = 'Cancel';
saveButton2.disabled = true;
worker = new Worker(URL.createObjectURL(blob));
wijmo.grid.pdf.PdfWebWorkerClient.exportGrid(worker, flexGrid, 'FlexGrid.pdf', null, done, progress);
} else {
// Cancel PDF generation process
worker.terminate();
progress(0);
isExporting = false;
saveButton1.innerText = 'Create PDF(using Web Worker)';
saveButton2.disabled = false;
}
});
// Callback function executed when PDF creation is completed
function done() {
isExporting = false;
saveButton1.innerText = 'Create PDF(using Web Worker)';
saveButton2.disabled = false;
}
// Callback function executed during PDF creation
function progress(value) {
value = Math.floor((value * 100));
progressText.innerText = value;
progressGauge.value = value;
}
// Create PDF without using Web Worker
saveButton2.addEventListener('click', function() {
saveButton1.disabled = true;
saveButton2.innerText = 'Cancel';
wijmo.grid.pdf.FlexGridPdfConverter.export(flexGrid, 'FlexGrid.pdf');
saveButton1.disabled = false;
saveButton2.innerText = 'Create PDF(without Web Worker)';
});
function orders(length) {
var orders = [];
var _years = 4;
for (var i = 0; i < length; i++) {
var date = new Date((new Date()).getFullYear() - _years, 3, 1);
orders.push({
id: i,
product: productNames[random(productNames.length)],
date: wijmo.DateTime.addDays(date, random(365 * _years)),
amount: random(200, 10),
discount: random(3) == 0
});
}
return orders;
}
function random(max, min) {
if (!min) min = 0;
return Math.floor(Math.random() * (max - min)) + min;
}
CSS:
#flexGrid {
height: 300px;
margin-top: 20px;
}
#progressGauge {
width: 400px;
display: inline-block;
vertical-align: middle;
}
#progressText {
width: 30px;
display: inline-block;
text-align: right;
}
#saveButton1, #saveButton2 {
width: 230px;
}
</style>
<link rel="stylesheet" href="https://demo.grapecity.com/wijmo/beta/styles/wijmo.min.css" />
<script src="https://demo.grapecity.com/wijmo/beta/controls/wijmo.min.js"></script>
<script src="https://demo.grapecity.com/wijmo/beta/controls/wijmo.pdf.min.js"></script>
<script src="https://demo.grapecity.com/wijmo/beta/controls/wijmo.grid.min.js"></script>
<script src="https://demo.grapecity.com/wijmo/beta/controls/wijmo.grid.pdf.min.js"></script>
<style>
Result:
Web Worker 对于 JavaScript应用程序的重要作用
当JavaScript执行繁重的处理时,用户体验可能会大大减少,但是对于Web Workers来说,时间的感觉通过得更快。 使用Web Workers对于在Web应用程序中执行繁重的处理至关重要。现在WijmoJS 已经将这项技术引入,请大家免费试用!
WijmoJS | 下载试用
快如闪电,触控优先。纯前端控件集 WijmoJS,为您的企业应用提供更加灵活的操作体验,在全球率先支持 AngularJS,并提供性能卓越、零依赖的 FlexGrid 和金融图表等多个控件,为您提供易用、轻松的操作体验,全面满足开发所需。
您对WijmoJS产品的任何技术问题,都有技术支持工程师提供1对1专业解答,点击此处即可发帖提问>>
WijmoJS 使用Web Workers技术,让前端 PDF 导出效率更高效的更多相关文章
- [书籍翻译] 《JavaScript并发编程》第五章 使用Web Workers
本文是我翻译<JavaScript Concurrency>书籍的第五章 使用Web Workers,该书主要以Promises.Generator.Web workers等技术来讲解Ja ...
- JavaScript是如何工作的:Web Workers的构建块 + 5个使用他们的场景
摘要: 理解Web Workers. 原文:JavaScript是如何工作的:Web Workers的构建块 + 5个使用他们的场景 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 这 ...
- Web开发技术发展历史
Web开发技术发展历史 来自:天码营 原文:http://www.tianmaying.com/tutorial/web-history Web的诞生 提到Web,不得不提一个词就是"互 ...
- 3D拓扑自动布局之Web Workers篇
2D拓扑的应用在电信网管和电力SCADA领域早已习以为常了,随着OpenGL特别是WebGL技术的普及,3D方式的数据可视化也慢慢从佛殿神堂步入了寻常百姓家,似乎和最近高档会所被整改为普通茶馆是一样的 ...
- Web挖掘技术
一.数据挖掘 数据挖掘是运用计算机及信息技术,从大量的.不全然的数据集中获取隐含在当中的实用知识的高级过程.Web 数据挖掘是从数据挖掘发展而来,是数据挖掘技术在Web 技术中的应用.Web 数据 ...
- Ajax、Comet、HTML 5 Web Sockets技术比较分析
最近因为考虑研究B/S结构网站即时消息处理 参考了 JAVA怎么样实现即时消息提醒http://bbs.csdn.net/topics/330015611http://www.ibm.com/deve ...
- C#技术分享【PDF转换成图片——13种方案】(2013-07-25重新整理)
原文:C#技术分享[PDF转换成图片--13种方案](2013-07-25重新整理) 重要说明:本博已迁移到 石佳劼的博客,有疑问请到 文章新地址 留言!!! 写在最前面:为了节约大家时间,撸主把最常 ...
- 转:Spine.JS+Rails重客户端Web应用技术选型思路:『风车』架构设计
原文来自于:http://www.infoq.com/cn/articles/fengche-co-architecture 风车这个项目开始于 2011 年 11 月份,之前叫做 Pragmatic ...
- HTML5 Web Workers来加速您的移动Web应用
一直以来,Web 应用程序被局限在一个单线程世界中.这的确限制了开发人员在他们的代码中的作为,因为任何太复杂的东西都存在冻结应用程序 UI 的风险.通过将多线程引入 Web 应用程… 在本文中,您将使 ...
随机推荐
- 【Scala学习之二】 Scala 集合 Trait Actor
环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk1.8 scala-2.10.4(依赖jdk1.8) spark ...
- 【CDH学习之一】CDH简介
环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk8 zookeeper-3.4.11 一.CDH在商业应用中,对 ...
- Python 构造一个可接受任意数量参数的函数
为了能让一个函数接受任意数量的位置参数,可以使用一个* 参数 在这个例子中,rest 是由所有其他位置参数组成的元组.然后我们在代码中把它当成了一个序列来进行后续的计算
- JustOj 1994: P1001
题目描述 给定一个长度为N(0< n< =10000)的序列,保证每一个序列中的数字a[i]是小于maxlongint的非负整数 ,编程要求求出整个序列中第k大的数字减去 ...
- Cheerleaders UVA - 11806
题目大意是: 在一个m行n列的矩形网格中放置k个相同的石子,问有多少种方法?每个格子最多放一个石子,所有石子都要用完,并且第一行.最后一行.第一列.最后一列都要有石子. 容斥原理.如果只是n * m放 ...
- 为什么要使用yocto
作为灵活多变且经济高效的解决方案,嵌入式 Linux展现了巨大的价值,并广泛应用于消费电子设备.网络设备.零售点和行业应用程序.然而,广泛的应用也意味着多样化的业务需求,嵌入式解决方案开发人员必须构建 ...
- P2147 [SDOI2008]洞穴勘测(LCT)
P2147 [SDOI2008]洞穴勘测 裸的LCT. #include<iostream> #include<cstdio> #include<cstring> ...
- tcp编程 示例
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <net ...
- windows下常用linux对应工具
tail 可从http://files.cnblogs.com/hantianwei/tail.zip下载,解压后exe,如下: e:\>tail -fn 300 tool-slow.logus ...
- 前端基础小标签3 H5新标签
第二部分H5的新标签一.<!-- mark标签 1.用于显示页面中需要重点关注的内容,就像看书需要用荧光笔划重点一样 2.浏览器通常会用黄色显示m ...