概述

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. DBUtils (30)

    DBUtils是java编程中的数据库操作实用工具,小巧简单实用. DBUtils封装了对JDBC的操作,简化了JDBC操作,可以少写代码. Dbutils三个核心功能介绍 一.  QueryRunn ...

  2. c# 类的知识

    在英语中类(class)是分类(classification)的根词.设计类的过程就是对信息进行分类,将相关信息放到有意义的实体中. 封装的目的: 封装就是定义类的重要原则.中心思想是:使用类的程序不 ...

  3. 新浪微博 [异常问题] 414 Request-URL Too Large

    新浪微博 [异常问题] 414 Request-URL Too Large 浏览器上打开新浪微博,或则日志是返回结果提示:414 Request-URL Too Large原因:因同IP访问微博页面过 ...

  4. tomcat tomcat-user.xml被还原

    问题:把tomcat——conf中的tomcat-user.xml中的角色.密码修改之后,在eclipse重启Tomcat,设置的Tomcat用户名和密码失效. 解决问题:同时修改tomcat——co ...

  5. CAN学习网站

    百度搜索:Controller Area Network http://www.esd-electronics-usa.com/Controller-Area-Network-CAN-Introduc ...

  6. bootstrapValidator验证表单后清除当次验证的方法

    用bootstrapValidator的resetForm()方法: <!-- // create server begin --> <div class="modal f ...

  7. How to use CAR FANS C800 Diagnostic Scan Tool to do diagnosis operation

    How to use Heavy Duty Diagnostic CAR FANS C800 Diagnostic Scan Tool to do diagnosis operation Here i ...

  8. 介绍python中运算符优先级

    下面这个表给出Python的运算符优先级,从最低的优先级(最松散地结合)到最高的优先级(最紧密地结合).这意味着在一个表达式中,Python会首先计算表中较下面的运算符,然后在计算列在表上部的运算符. ...

  9. 关于treeMap

    https://www.cnblogs.com/skywang12345/p/3310928.html

  10. Eloquent JavaScript #04# Objects and Arrays

    要点索引: JSON More ... 练习 1.补:js字符串的表达方式有三种: "" 和 '' 没什么区别,唯一区别在于 "" 中写 "要转义字符 ...