概述

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>&nbsp;
<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 导出效率更高效的更多相关文章

  1. [书籍翻译] 《JavaScript并发编程》第五章 使用Web Workers

    本文是我翻译<JavaScript Concurrency>书籍的第五章 使用Web Workers,该书主要以Promises.Generator.Web workers等技术来讲解Ja ...

  2. JavaScript是如何工作的:Web Workers的构建块 + 5个使用他们的场景

    摘要: 理解Web Workers. 原文:JavaScript是如何工作的:Web Workers的构建块 + 5个使用他们的场景 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 这 ...

  3. Web开发技术发展历史

    Web开发技术发展历史   来自:天码营 原文:http://www.tianmaying.com/tutorial/web-history Web的诞生 提到Web,不得不提一个词就是"互 ...

  4. 3D拓扑自动布局之Web Workers篇

    2D拓扑的应用在电信网管和电力SCADA领域早已习以为常了,随着OpenGL特别是WebGL技术的普及,3D方式的数据可视化也慢慢从佛殿神堂步入了寻常百姓家,似乎和最近高档会所被整改为普通茶馆是一样的 ...

  5. Web挖掘技术

      一.数据挖掘 数据挖掘是运用计算机及信息技术,从大量的.不全然的数据集中获取隐含在当中的实用知识的高级过程.Web 数据挖掘是从数据挖掘发展而来,是数据挖掘技术在Web 技术中的应用.Web 数据 ...

  6. Ajax、Comet、HTML 5 Web Sockets技术比较分析

    最近因为考虑研究B/S结构网站即时消息处理 参考了 JAVA怎么样实现即时消息提醒http://bbs.csdn.net/topics/330015611http://www.ibm.com/deve ...

  7. C#技术分享【PDF转换成图片——13种方案】(2013-07-25重新整理)

    原文:C#技术分享[PDF转换成图片--13种方案](2013-07-25重新整理) 重要说明:本博已迁移到 石佳劼的博客,有疑问请到 文章新地址 留言!!! 写在最前面:为了节约大家时间,撸主把最常 ...

  8. 转:Spine.JS+Rails重客户端Web应用技术选型思路:『风车』架构设计

    原文来自于:http://www.infoq.com/cn/articles/fengche-co-architecture 风车这个项目开始于 2011 年 11 月份,之前叫做 Pragmatic ...

  9. HTML5 Web Workers来加速您的移动Web应用

    一直以来,Web 应用程序被局限在一个单线程世界中.这的确限制了开发人员在他们的代码中的作为,因为任何太复杂的东西都存在冻结应用程序 UI 的风险.通过将多线程引入 Web 应用程… 在本文中,您将使 ...

随机推荐

  1. linux环境下安装qt过程

    linux(虚拟机fedora9)环境下安装qt的过程主要是按照下面几网页上的教程完成的. http://mobile.51cto.com/symbian-272869.htm http://www. ...

  2. element ui里dialog关闭后清除验证条件

    //vue <!--添加用户dialog begin--> <el-dialog title="编辑用户" :visible.sync="dialogF ...

  3. 获取select被选中的option的值

    <select id="select">      <option>绥江</option>      <option>西江</ ...

  4. 计算概论(A)/基础编程练习2(8题)/7:整数的个数

    #include<stdio.h> int main() { ] = {}; // 输入k个正整数 scanf("%d",&k); // 循环读入和进行算术 w ...

  5. ES6知识整理(4)--数组的扩展

    最近工作比较忙,基本每天都会加班到很晚.处理一些客户端兼容问题以及提升用户体验的优化.也将近一周没更文了,现在继续es6的学习总结. 上篇回顾 ES6知识整理(三)--函数的扩展 扩展运算符 形式是3 ...

  6. 2019/3/25 wen 包,对象的行为

  7. Eloquent JavaScript #02# program_structure

    第一章中作者介绍了各种值,但是这些独立的值是没有意义的,只有当值放在更大的框架的时候才会彰显它们的价值.所以第二章开始介绍程序结构. 1.var VS. let 以及 const 作者推荐用 let ...

  8. ansible中的playbook详解

    首先简单说明一下playbook,playbook是什么呢?根本上说playbook和shell脚本没有任何的区别,playbook就像shell一样,也是把一堆的命令组合起来,然后加入对应条件判断等 ...

  9. PostgreSQL 10首个测试版本发布

    mysql 从5.7到8.0,pg从9.6到10,干起来了.. PostgreSQL 10 的首个测试版发布了,此版本包含 PostgreSQL 10 最终将提供的所有功能的预览.当然,有些细节将在最 ...

  10. 苹果笔记本充不进电怎么办_macbook充不进电解决办法

    使用苹果Macbook的用户可能会遇到这种情况,使用一段时间后自己的苹果笔记本充不进电了,虽然充电器指示灯依然亮着,但是电池电脑一直充不进去,断开充电器后就直接关机的情况.通常碰到这种情况,很多用户都 ...