概述

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. 使用AJAX技术发送异步请求,HTTP服务端推送

    使用AJAX技术发送异步请求 什么是AJAX AJAX指一步Javascript和XML(Asynchronous JavaScript And XML),它是一些列技术的组合,简单来说AJAX基于X ...

  2. ATM-JAVA程序 //程序有5处相同错误,找不出原因 转账功能没有实现,修改密码来不及实现了

    package JCC;//信1705-3 20173681 靳晨晨import java.io.BufferedReader;import java.io.File;import java.io.F ...

  3. windows环境下 curl 安装和使用

    curl下载地址:https://curl.haxx.se/download.html,拉到页面最底下,选择红色选中的那个CAB的进行下载,如下图所示: 下载完成后,解压. 解决windows控制台c ...

  4. ELKF安装使用教程。elasticsearch+logstash+kibana+filebeta。

    近期因工作需要学习了ELKF的安装和使用.网络上的中文我看大部分也比较老版本了,我想写一下,希望能给他人带来一点帮助.小弟不才,有错位之处,还请大家原谅指点. ELKF就是:elasticsearch ...

  5. Chrome插件消息传递实例

    首先吐槽"360极速浏览器应用开发平台"的开发文档,在消息传递(http://open.chrome.360.cn/extension_dev/messaging.html)一节中 ...

  6. brctl 命令详解

    安装网桥管理工具包:bridge-utile ```# yum install bridge-utils -y``` ```使用brctl命令创建网桥br1```# brctl addbr br1`` ...

  7. java根据图片的url地址下载图片到本地

    package com.daojia.haobo.aicircle.util; import sun.misc.BASE64Encoder; import java.io.*; import java ...

  8. 【js】关于闭包和匿名函数

    关于js闭包.之前我一直以为是匿名函数,以为封闭式的创建即执行销毁就是闭包,其实这是匿名函数,不一样的.也没有闭包的使用经验. 后来去网上查了下才知道,闭包的意思是:函数内部还有函数,返回一个函数,内 ...

  9. log buffer space等待事件

    最近,我们有台服务器在delete操作期间发现一直在等待log buffer space,其他节点就没与这个问题.经查,向重做缓冲区上写入重做记录的进程,为了确保拥有重做缓冲区内必要的空间,需要获得r ...

  10. JSch : channel never closed or EOF 通道未关闭

    最近,我们的项目在开发远程节点管理的时候,使用了jsch库.在测试的时候发现有个节点在cmd执行完成之后,channel.isClosed()一直都是false,导致请求无法返回,但是其它有些节点就没 ...