gwt格式_GWT的渐进式Web应用程序配方

gwt格式

渐进或不渐进…

如果您已经设计或开发Web应用程序已有一段时间,那么您可能会遇到无数次“渐进式Web应用程序”一词,并且可能会在未来几年内使用。 您可能想知道PWA的确切定义是什么,如何识别PWA,以及如何构建PWA。 根据字典,渐进一词是指可以改善或变得更好的东西,但是这与Web应用程序有什么关系呢? 我们真的不知道。 PWA似乎是Google引起人们兴趣的流行语,与PWA的真正含义并没有真正的关系。 Alex Russel将PWA定义为“摄取正确维生素的网站”。 为简单起见,让我们首先说说PWA是经过优化以适合其环境的Web应用程序:在移动设备或平板电脑上,它们可以扮演移动本机应用程序的角色,而在PC上,它们可以扮演普通Web应用程序的角色。

PWA的基本原理:

PWA是具有常规Web应用程序以及用于不同移动平台的捆绑应用程序的替代方法。 维护和升级所有这些程序可能会花费很大,尤其是在应用程序频繁更改的情况下。 使用PWA,只有一个适用于所有平台的应用程序,可以通过浏览器中的链接进行访问。 PWA旨在使用“移动优先”方法进行设计。 可以安装它们,但它们也可以作为常规网站正常工作。 Google为PWA创建了一个专用网站 ,并介绍了通过将应用程序/网站转换为PWA而受益的公司的不同案例。

PWA的特征:

Google的开发倡导者Rob Dodson在他的演讲中强调了Web应用程序的不同特征:
–React灵敏:适应设备
–快速加载:优化以快速绘制或渲染 –脱机工作:使用服务人员来缓存内容,以允许脱机使用或慢速网络连接的应用程序 –可安装:可以在主屏幕中安装应用程序(例如本机应用程序) –参与度:通过推送通知使用户了解情况

既然我们知道了渐进式Web应用程序的外观,我们就可以开始研究可以帮助我们使GWT应用程序渐进式的各种工具。

用于PWA的GWT食谱:

    • #1响应式:

为了使您的GWT应用程序具有响应能力,GWT用户有几个选项。 如果您具有设计技能,则可以使用自定义代码和CSS使应用程序具有响应能力。 否则,您可以依赖其他框架。 GWT的Bootstrap( https://github.com/gwtbootstrap3/gwtbootstrap3 )是我想到的第一件事。 它提供了著名的Twitter框架的所有组件。 另一种选择是GWTMaterialDesign( https://github.com/GwtMaterialDesign/gwt-material )。 它提供了具有响应性的材料设计,可以随时为您的应用程序使用元素。 最后, gwt-polymer-element是GWT的Polymer包装材料,它还提供了随时可用的响应式Web组件,并且可以在设计构建响应式应用程序时派上用场。 我们在之前的一篇文章中提供了Polymer的新手指南。

    • #2快速加载:

为了减少第一次喷涂的时间,可以做很多事情。 首先,可以使用代码拆分来减少gwt模块文件的大小。 它基本上将模块分成多个片段,从而使GWT模块在启动时仅下载所需的片段。 其次,可以将PWA 准则指定的应用程序外壳方法应用于GWT应用程序。 这可以通过从应用程序Java代码中提取静态元素和数据并将其直接放入.html入口点来完成。 例如:

GWT用户的常见做法是将.html的正文留空,并以编程方式从应用程序添加其视图:

<body>     
</body>
//....AppMainView view = AppMainView();RootPanel.get().add(view);

尽管这种做法没有错,但是由于.js模块文件将包含更多指令,因此它可能会延长应用程序的加载时间,因此执行起来将花费更多时间。 作为解决方法,我们可以尝试识别视图中的所有静态元素并将其放入.html中,然后可以从入口点加载单个视图:

<div id="appShell"><img src="logo.png" alt="" />
<div id="menu"></div>
<div id="mainContent"></div>
//...
MenuView menu = new MenuMeview();
ContentView content = new ContentView();RootPanel.get("menu").add(menu);
RootPanel.get("mainContent").add(content);

为了说明的目的,这当然是简化的示例。 到目前为止,我们已经看到了代码拆分和应用程序外壳如何减少呈现应用程序的时间。 还有HTML5的async脚本属性,该属性并非真正专用于GWT。 例如:

<!-- Inside HEAD --!>
<script src="polymerstarter/polymerstarter.nocache.js" async="" type="text/javascript">

这将指示浏览器不要阻止解析,并在可用时尽快加载我们的应用脚本。

另一种选择是将应用程序脚本放入正文中。

    • #3离线工作:

这主要可以使用服务人员来完成。 没有官方的GWT库与服务人员进行交互。 甚至gwt-polymer-elements都不包装Platinum Elements,Platinum Elements是用于与浏览器的服务人员交互的Polymer元素。 GWT用户将不得不手动编写一些Javascript来实现应用程序资产的缓存机制。 JSNI或Jsinterop可用于与浏览器进行交互并调用服务工作者服务。 定义缓存事件的服务工作者脚本需要在单独的脚本上,因此,目前,将服务工作者代码和GWT应用程序模块代码混合在同一.js文件中有点复杂。 GWT唯一可以完成的任务是注册服务工作者。 我们将在下一节的后面进行演示。 另请注意,并非所有浏览器都支持服务工作者,您可以在Mozilla的API文档页面中找到有关此服务的更多详细信息。

有关如何使用Service Worker缓存应用程序数据和资产的更多详细信息,Google提供了一些有用的指南。

    • #4无法安装:

此收据也不特定于GWT。 要使Web应用程序可安装,您需要添加一个名为app manifest的json文件,并将其链接到.html入口点:

<link rel="manifest" href="manifest.json">

有关如何编写清单文件的指南,请参考W3C的指南: https : //www.w3.org/TR/appmanifest/ 。 您也可以使用此在线工具: http : //brucelawson.github.io/manifest/ ,该工具可以为您生成清单,但是您的应用程序必须已经在线。 您可以使用标语要求用户安装该应用程序,也可以让他从浏览器的选项中手动进行操作。

    • #5参与:

再次没有正式的GWT推送通知库。 这可能是呼吁GWT社区填补这一空白。 在此之前,GWT用户可以使用JSNI或Jsinterop与浏览器进行交互并订阅推送通知。

演示应用

为了说明上述特征,我们使用gwt-polymer-elements和gwty-leaflet构建了一个地图应用程序。 该应用程序显示用户的收藏夹地图。

来源: https : //github.com/gwidgets/gwt-pwa-demo
直播: https : //gwt-pwa-demo.herokuapp.com/pwademo.html/

使用Polymer,我们的应用程序默认情况下是响应式的,因此此步骤已完成。

为了使应用程序快速加载,我们首先移除所有静态html,然后将其放入.html入口点文件: https : //github.com/gwidgets/gwt-pwa-demo/blob/master/src/main /webapp/pwademo.html

我们使用聚合物元素与dom元素进行交互。 例如:

PaperMenuLEement paperMenu = (PaperMenuElement) Polymer.getDocument().getElementById("paperMenu");paperMenu.select("paris");

我们还使应用脚本异步加载:

<script type="text/javascript" language="javascript" src="pwademo/pwademo.nocache.js" async></script>

并且我们引入了一些代码拆分方法,因为每个部分只有一个地图,因此我们只需要在加载页面时在显示的部分上加载地图。

loadStartupMap();//Maps are not loaded on start up, but only when iron selector selects a new map
ironPages.addEventListener("iron-select", e -> {if(ironPages.getSelected().equals("london") && !londonMapInitialized){//Some code splitting to reduce initial module sizeGWT.runAsync(new RunAsyncCallback(){@Overridepublic void onFailure(Throwable reason) {Document.get().getElementById("londonMap").setInnerHTML("Could not load this map, please try again later");}@Overridepublic void onSuccess() {Maps.initializeLondonMap();	}});londonMapInitialized = true;}
});

我们还添加了一个应用程序清单,以允许手动安装该应用程序

{"name": "Favorite Maps PWA","short_name": "Favorite Maps PWA","icons": [{"src": "image/mapicon.png","sizes": "144x144","type": "image/png"}],"start_url": "/pwademo.html","display": "standalone","background_color": "#3E4EB8","theme_color": "#2E3AA1"
}

最后,我们添加了JsInterop类来注册服务工作者。

if (Navigator.serviceWorker != null) {Navigator.serviceWorker.register("sw.js").then(new Function<JavaScriptObject, JavaScriptObject>() {@Overridepublic JavaScriptObject call(JavaScriptObject arg) {GWT.log("registred service worker successfully");return null;}});} else {GWT.log("service worker unavailable in this browser");}

我们创建了一个名为sw.js的服务工作者脚本,并将其添加到应用程序的资源中。

var cacheName = 'GWT-PWA';  
var filesToCache = [  '/gwt-pwa/pwademo.html',  '/gwt-pwa/pwademo.css',  '/gwt-pwa/styles/app-theme.html',  '/gwt-pwa/styles/shared-styles.html',  '/gwt-pwa/leaflet/leaflet.js',  '/gwt-pwa/leaflet/leaflet.css','/gwt-pwa/image/mapicon.png','/gwt-pwa/pwademo/pwademo.nocache.js'];self.addEventListener('install', function(e) {  console.log('[ServiceWorker] Install');  e.waitUntil(  caches.open(cacheName).then(function(cache) {  console.log('[ServiceWorker] Caching app shell');  return cache.addAll(filesToCache);  })  );  
});self.addEventListener('activate', function(e) {  console.log('[ServiceWorker] Activate');  e.waitUntil(  caches.keys().then(function(keyList) {  return Promise.all(keyList.map(function(key) {  console.log('[ServiceWorker] Removing old cache', key);  if (key !== cacheName) {  return caches.delete(key);  }  }));  })  );  });self.addEventListener('fetch', function(e) {  console.log('[ServiceWorker] Fetch', e.request.url);  e.respondWith(  caches.match(e.request).then(function(response) {  return response || fetch(e.request);  })  );  });

该脚本将安装并激活服务工作者。 它还允许服务工作者预订获取事件,该事件在每次请求资源时触发。 然后,服务工作者根据其当前状态决定是使用本地缓存还是从网络中获取资源。

加载应用程序后,我们可以在Google chrome的缓存存储中找到我们的资产:

http://www.g-widgets.com/wp-content/uploads/2016/08/cacheChrome.png

如果我们在Google Chrome浏览器上禁用了网络并尝试运行该应用程序,则会得到类似的信息(由于未缓存地图,因此未渲染):

该应用程序即使没有网络也可以提供服务。 如果我们看一下Chrome开发工具中的网络请求,就会注意到服务工作者正在提供应用程序资源:

由于这是一个演示应用程序,因此我们没有添加任何推送通知,因为它需要设置推送服务器。

我们已从Android手机将应用程序安装到主屏幕,并且得到了类似以下内容:

结论

在Web开发领域,PWA仍然是新事物。 一些人预测他们将在未来几年接管本地应用程序。 我们知道,GWT开发人员一直在使用Phonegap将其Web应用程序转换为移动本机应用程序,也许有了PWA,他们将不再需要这样做。 我们已经在本教程中看到了如何使用诸如Polymer之类的库将GWT用于构建PWA。 到目前为止,还没有GWT库可以与浏览器服务工作者进行交互,因此GWT社区需要填补这一空白。

有趣的链接

Addy Osmani初学者指南: https : //addyosmani.com/blog/getting-started-with-progressive-web-apps/

2016年SpringIO关于PWA和Spring Boot的讨论: https : //www.youtube.com/watch?v= zAZQeQ0CRpQ

来自Web开发在线代理商https://skilled.co/的PWA用例摘要图表:


由Skilled.co提出

翻译自: https://www.javacodegeeks.com/2017/07/progressive-web-apps-recipes-gwt.html

gwt格式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/335150.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

光学定位与追踪技术_如何为射线光学仿真创建复杂的透镜几何结构

“射线光学模块”扩展了 COMSOL Multiphysics 软件的建模功能,允许用户引入射线追踪仿真。有了该模块&#xff0c;在集成软件环境中对复杂光学系统的热性能、结构及其他方面进行高阶研究不再是一个难题。创建几何模型是仿真成功的第一步。本文以 Petzval 透镜为例&#xff0c;探…

琥珀ai_琥珀项目:Java的未来暴露

琥珀ai如果一切按计划进行&#xff08;我们正在研究Jigsaw项目&#xff09;&#xff0c;那么Java 9将在不到100天的时间内启动。 您可以在此处加入倒计时以发布它。 它将包含一长串新功能和升级功能&#xff0c;其中一些我们迫不及待想要看到实际应用。 但是&#xff0c;有些功…

MySQL的存储过程和函数简单写法

什么是存储过程 简单的说&#xff0c;就是一组SQL语句集&#xff0c;功能强大&#xff0c;可以实现一些比较复杂的逻辑功能&#xff0c;类似于JAVA语言中的方法&#xff1b; ps:存储过程跟触发器有点类似&#xff0c;都是一组SQL集&#xff0c;但是存储过程是主动调用的&#…

python对excel求和_Python 两个Excel文件对应位置求和并存储

最近~老板给我的工作一直都有对大量的Excel的操作比如两Excel对应位置求和&#xff0c;并存储。(两Excel表格的第一列和第一行是一毛一样的&#xff0c;不需要求和&#xff0c;原样保存&#xff01;)本着能躺着就不坐着的原则&#xff0c;只想快点躺着&#xff0c;果断放弃了手…

zdal配置文件_Autofac的基本使用---4、使用Config配置

准备使用的表是Student&#xff0c;创建相关的IDAL、DAL、IBLL、BLL层。使用EF&#xff0c;创建一个Model层&#xff0c;存放edmx文件。创建一个Infrastructure层&#xff0c;基础设施项目&#xff0c;使用泛型类型。普通类型的使用1.APP.Config 配置信息此处有个需要注意的地方…

判断选择语句switch...case

switch(被检测量){ case 常量1: 语句1; break; case 常量2: 语句2; break; ... deault: 语句N; break; }被检测量的数据类型 基本数据类型&#xff1a;byte、short、int、char引用数据类型&#xff1a;String、enum 穿透 int num 2; switch(num){ case 1: System.out.print…

Java与Python:哪一个最适合您? [信息图]

通过从您的应用程序学习企业APM产品&#xff0c;发现更快&#xff0c;更有效的性能监控。 参加AppDynamics APM导览&#xff01; 在软件开发中&#xff0c;很少有问题比选择编程语言更具分裂性或部落性。 软件开发人员经常以自己选择的工具来强烈地认同自己&#xff0c;将客观…

怎么把php查询到的值显示到下拉框中_RazorSQL for Mac(数据库工具查询)8.5.3

razorsql mac版更新日志变化 查询结果&#xff1a;如果有多个查询结果选项卡&#xff0c;则从查询结果选项卡中选择比较查询结果选项将填充比较工具中的两个查询 漏洞修补 不需要重新启动razorsql才能生效的首选项需要重新启动 自动更新程序不适用于Windows计算机 缺少HBase连接…

docker删除es数据_木杉入门Elasticsearch(4):安装ES

木杉入门本系列的目标是在本地搭建一个Elasticsearch的服务集群&#xff0c;通过在阿里云服务器搭建FRP通道对外提供服务&#xff0c;为小规模应用提供一种高性价比的解决思路。系列内容&#xff1a;木杉入门Elasticsearch(1)&#xff1a;ESXI虚拟机安装CentOS木杉入门Elastics…

MySQL数据库常用命令_常用SQL语句及命令_MySQL常用语句

文章目录一、常用的 SQL 语句&#xff08;一&#xff09;查看当前登录用户&#xff08;二&#xff09;查看当前数据库&#xff08;三&#xff09;如何查看全部用户&#xff1f;&#xff08;四&#xff09;创建数据库&#xff08;五&#xff09;选择要操作的数据库&#xff08;六…

spock_在扩展Spock时输出给定值

spockSpock是一个Java测试框架&#xff0c;由GradleWare的软件工程师Peter Niederwieser于2008年创建&#xff0c;它可以促进BDD的发展。 利用这个 例如 &#xff0c;一个故事可以定义为&#xff1a; Story: Returns go to stockAs a store owner In order to keep track of …

将serversocket 写在按钮事件中连接不上_Java服务器的模型—TCP连接/流量优化

本文很长哦&#xff0c;但请给我一点时间。通常&#xff0c;我们的应用程序不需要并行处理成千上万的用户&#xff0c;也不需要在一秒钟内处理成千上万的消息。我们只需要应付数十或数百个并发连接的用户&#xff0c;就可以在内部应用程序或某些微服务应用程序中承受如此大的负…

ios 开发设置左滑退出_苹果铃声怎么设置自己的歌?教你用手机快速搞定!

苹果手机铃声怎么设置为自己喜欢的歌曲&#xff1f;由于iOS系统的封闭性&#xff0c;想要给苹果手机更换铃声不像在安卓手机一样那么方便&#xff0c;看到网上很多教程也是需要使用电脑才能完成铃声的设置&#xff0c;有没有不复杂的方法来直接帮我们更换手机铃声&#xff1f;别…

dp括号匹配 网易面试题_面试题:大括号验证

dp括号匹配 网易面试题这是较容易的编码任务之一&#xff0c;但是您仍然可以在一些初步的技术筛选中达到目标。 问题看起来像这样&#xff1a; 给定仅包含字符( &#xff0c; ) &#xff0c; { &#xff0c; } &#xff0c; [和]的字符串&#xff0c;请确定输入字符串是否有效…

MySQL如何删除有外键约束的数据

在数据库中查看外键是否有效,值为1表示外键有效 mysql> select foreign_key_checks; ---------------------- | foreign_key_checks | ---------------------- | 1 | ---------------------- 1 row in set (0.00 sec)将外键的值设置为0&#xff0c;此时…

python绘制动画示例_Python使用matplotlib绘制动画的方法

本文实例讲述了Python使用matplotlib绘制动画的方法。分享给大家供大家参考。具体分析如下&#xff1a;matplotlib从1.1.0版本以后就开始支持绘制动画下面是几个的示例&#xff1a;第一个例子使用generator&#xff0c;每隔两秒&#xff0c;就运行函数data_gen&#xff1a;# -*…

基于单片机步进电机ppt答辩_基于MCU和DSP的步进电机控制技术分析

来源 | 控制与传动步进电机已经渗透入我们生活的方方面面&#xff0c;本文介绍了一些重要的步进电机相关技术&#xff0c;为开发人员基本了解步进电机的工作原理提供了足够的信息&#xff0c;同时也介绍了用微控制器或数字信号处理器控制步进电机的方法。步进电机也叫步进器&am…

拼图登陆拼图二维码验证_另一个拼图观点

拼图登陆拼图二维码验证在过去的几周中&#xff0c;围绕Java 9即将发布及其最著名的功能&#xff1a;Java平台模块系统JPMS进行了激烈的辩论。 –以其项目名称Jigsaw更为人所知。 模块系统以正式规范过程的形式引入Java生态系统 – JSR –需要由专家组以最终形式批准。 在该专…

【C++】多线程(四)

这是多线程的最后一篇文章。 std::promise promise 的作用很简单&#xff0c;在一个线程t1中保存一个类型typename T的值&#xff0c;可供相绑定的std::future对象在另一线程t2中获取。事实上&#xff0c;它与future基本是成对出现的。来看下面的例子&#xff1a; //声明一个…

广告设计师如何使用python_设计师必看!高效率工具,30分钟完成别人一天的工作!...

原标题&#xff1a;设计师必看&#xff01;高效率工具&#xff0c;30分钟完成别人一天的工作&#xff01;世界上只有两种物质&#xff1a;高效率和低效率&#xff1b;世界上只有两种人&#xff1a;高效率的人和低效率的人。—— 萧伯纳今天这篇文章主要想和大家分享一个效率工具…