javascript初始化-新的 JavaScript 框架 Qwik:通过独特的可恢复性方法加速 Web 应用程序

2023-08-24 0 1,737 百度已收录

作者|布鲁诺·库里奥尔

译者| 马可伟

策划|丁晓云

AngularJS 的创建者 Misko Hevery 近日宣布推出新的 Web 框架 Qwik 测试版,声称无论应用有多大javascript初始化,Qwik 也能快速构建。 在大多数情况下,Qwik 将首先下载 1KB 的 JavaScript,并在需要时延迟加载或预处理程序和应用程序代码。

在题为“如何从主线程中删除 99% 的 JavaScript”的演讲中,Hevery 解释了 Qwik 背后的基本原理。

Qwik 的目标很简单,确保即使是复杂的网站也能在 Microsoft 页面速度得分上获得 100/100 的分数……归根结底,这一切都是为了尽可能缩短交互时间。

正如你所看到的,业界大多数框架都擅长优化图像和 CSS,但不擅长优化 JavaScript。 由于这对于互联网上的每个人来说都是一个系统性问题,因此我的观点是问题在于工具而不是开发人员。

Qwik 关注的是优化 JavaScript 交付率的工具。

Misko 将 JavaScript 在交互时间指标上的负面表现归因于水合作用。 从服务器渲染时会发生水合作用。 服务器收到客户端的页面请求后,进行相应的查询来填充接口,并将结果返回给客户端。 看来对于用户来说,服务器端渲染页面的速度一般比客户端渲染页面要快(比如首个内容渲染更快),但是页面并不是立即交互的,需要客户端下载并执行页面. 上的 JavaScript 脚本

在大多数框架中,协调第一个交付的 HTML 与应用程序的 JavaScript 的过程称为水化。 在水化过程中,Web 应用程序框架将 Storm 处理程序与 DOM 元素结合起来并初始化应用程序状态。 然后,风暴处理程序捕获用户操作,从而使页面具有交互性。

Qwik 通过在服务器上运行应用程序来保留服务器端渲染以防止水合。 它序列化所有相关的状态信息,并将页面内容和序列化状态以 HTML 形式发送到客户端。 相关状态信息包括storm bug、内部数据结构和应用程序状态。 使用序列化状态,客户端可以中继服务器未完成的任务。

默认情况下,用于处理交互性的 JavaScript 加载会被延迟,通常直到用户实际使用交互时才加载,也就是说,最迟在用户单击按钮时可以加载按钮处理程序。 这些即时的 JavaScript 获取加上预取策略,借助浏览器的本地能力,在不影响页面交互性的情况下完成文件的加载。

Qwik文档中有详细介绍:

Qwik 只会预取当前页面所需的代码,并避免下载与静态组件相关的代码。 在最坏的情况下,Qwik 预取与现有框架的最佳情况相同数量的代码,并且在大多数情况下,Qwik 只会预取比现有框架更少的代码。

主线程以外的线程都可以进行代码预取,大多数浏览器甚至支持主线程以外的代码的AST句型预分析。

如果用户在预取完成之前开始交互,浏览器将手动优先考虑交互模块而不是其他预取模块。

Qwik 可以将应用程序分解为多个部分,并且可以按照用户交互的概率的顺序下载这些部分。

Qwik 网站为开发人员提供教程、示例以及学习和尝试 Qwik 的在线平台。 以一个简单的计数器为例,它由一个按钮和一个显示按钮点击次数的文本框组成。 实现如下:

import { component$, useStore } from '@builder.io/qwik';
export const App = component$(() => { const store = useStore({ count: 0 });
return (

Count: {store.count}

);});

开发者可以通过Qwik的component$API创建可恢复的组件,有状态组件可以通过useStoreAPI显示其对某种状态的依赖。 将 $ 字符附加到处理程序名称将创建一个可恢复的事件处理程序(如上例中的 onclick$)。 通过这种自动提示,Qwik可以对应用程序文件进行打包,以实现和优化JavaScript的延迟加载。 上述计数器程序的服务器端渲染 HTML 如下:

<html  q:container="paused"  q:version="0.11.1"  q:render="ssr"  q:base="/repl/21kry8ac4hl/build/">            Tutorial                    

Count: 0

<button on:click="app_component_div_p_button_onclick_8dwua0cjar4.js#App_component_div_p_button_onClick_8dWUa0cJAr4[0]" q:id="2" > Click

{"ctx":{"#2":{"r":"0!"}},"objs":[{"count":"1"},0],"subs":[["2 #0 0 #1 data count"]]} ((e,t)=>{const n="__q_context__",o=window,r=new Set,i=t=>e.querySelectorAll(t),s=(e,t,n=t.type)=>{i("[on"+e+"\:"+n+"]").forEach((o=>l(o,e,t,n)))},a=(e,t)=>new CustomEvent(e,{detail:t}),c=(t,n)=>(t=t.closest("[q\:container]"),new URL(n,new URL(t.getAttribute("q:base"),e.baseURI))),l=async(t,o,r,i=r.type)=>{const s="on"+o+":"+i;t.hasAttribute("preventdefault:"+i)&&r.preventDefault();const a=t._qc_,l=null==a?void 0:a.li.filter((e=>e[0]===s));if(l&&l.length>0){for(const e of l)await e[1].getFn([t,r],(()=>t.isConnected))(r,t);return}const d=t.getAttribute(s);if(d)for(const o of d.split("n")){const i=c(t,o),s=b(i),a=performance.now(),l=u(await import(i.href.split("#")[0]),s),d=e[n];if(t.isConnected)try{e[n]=[t,r,i],f("qsymbol",{symbol:s,element:t,reqTime:a}),await l(r,t)}finally{e[n]=d}}},f=(t,n)=>{e.dispatchEvent(a(t,n))},u=(e,t)=>{if(t in e)return e[t];for(const n of Object.values(e))if("object"==typeof n&&n&&t in n)return n[t]},b=e=>e.hash.replace(/^#?([^?[|]*).*$/,"$1")||"default",d=e=>e.replace(/([A-Z])/g,(e=>"-"+e.toLowerCase())),p=async e=>{let t=d(e.type),n=e.target;for(s("-document",e,t);n&&n.getAttribute;)await l(n,"",e,t),n=e.bubbles&&!0!==e.cancelBubble?n.parentElement:null},v=e=>{s("-window",e,d(e.type))},w=()=>{var n;const s=e.readyState;if(!t&&("interactive"==s||"complete"==s)&&(t=1,f("qinit"),(null!=(n=o.requestIdleCallback)?n:o.setTimeout).bind(o)((()=>f("qidle"))),r.has("qvisible"))){const e=i("[on\:qvisible]"),t=new IntersectionObserver((e=>{for(const n of e)n.isIntersecting&&(t.unobserve(n.target),l(n.target,"",a("qvisible",n)))}));e.forEach((e=>t.observe(e)))}},q=(e,t,n,o=!1)=>e.addEventListener(t,n,{capture:o}),y=t=>{for(const n of t)r.has(n)||(q(e,n,p,!0),q(o,n,v),r.add(n))};if(!e.qR){const t=o.qwikevents;Array.isArray(t)&&y(t),o.qwikevents={push:(...e)=>y(e)},q(e,"readystatechange",w),w()}})(document); window.qwikevents.push("click")

请注意,HTML 文件通过以下方法得到增强。

Qwik的在线代码运行平台可以让开发者了解程序代码是如何切割和打包的。 以上面的计数器为例,客户端的打包方法如下:

如屏幕截图所示,计数器应用程序分为三个脚本。 当用户单击按钮时,将动态下载并执行两个脚本(Qwik 运行时和单击事件处理程序的代码)。

有关实现以及代码分割的工作原理,请参阅 Qwik 文档。 Qwik 的网站提供了大量信息,包括教程、示例和演示,以及交互式在线代码执行平台。 Qwik社区里还有一个非常简单的电子商务例子。 通常,对于电商厂商来说,页面加载率的提高也会降低收入。

Qwik 团队目前由 AngularJS 的创建者 Miško Hevery、基于 Go 的 Web 框架 Gin 的创建者 Manu Almeida 和 Web 组件编译器 Stencil 的创建者 Adam Bradley 组成。

目前javascript初始化,Qwik 已推出测试版,并在 MIT 许可下开源。 欢迎您在遵守 Qwik 行为准则的前提下贡献代码。

原文链接:

新的QwikJavaScript框架寻求更快的Web应用程序和独特的方法:可恢复性

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 javascript javascript初始化-新的 JavaScript 框架 Qwik:通过独特的可恢复性方法加速 Web 应用程序 https://www.wkzy.net/game/150036.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务