译者 | 李睿
审校 | 孙淑娟
Astro是当前JavaScript热潮中的一种新方法:从响应式前端获得更多性能。它是由创建Snowpack构建工具的同一团队开发的。
已经有一些尝试通过避免昂贵的预取和引导来提高性能,这些操作已经影响了类似于React的框架。
Astro采用了一种有趣而新颖的方法。它是一个构建系统,可以让用户使用任何想要的框架(React、Svelte、Vue等),然后找到最适合使用JavaScript延迟加载的地方。可以将其视为捆绑时应用于应用程序的一种智能代码拆分。
因此,用户可以使用熟悉的框架,但也可以获得潜在的巨大性能优势。
Astro提出的Web架构有时被称为孤岛架构。其核心思想是这些孤岛是交互式、依赖于JavaScript的组件,被纯HTML/CSS标记包围。
通过以这种方式分割应用程序,可以将所有HTML直接发送到浏览器,因此用户可以与之交互,而依赖于JavaScript的部分只能在需要时加载。甚至可以告诉Astro推迟JavaScript,直到组件对用户可见为止。
可以通过使用在线沙盒来熟悉Astro。点击这个链接(https://astro.build/play)打开它。
这个链接将显示名称为Page.astro的简单页面,并带有时间戳。需要注意页面(清单1)是如何分成两个部分的。第一部分由第一个点划线(---)表示,包含将在构建时而不是运行时在服务器上执行的代码。第二部分由第二个点划线表示,包含要在运行时交付的标记。
---
import {format} from 'date-fns';
// Welcome to Astro!
// Write JavaScript & TypeScript here, in the "component script."
// This will run during the build, but never in the final output.
// Use these variables in the HTML template below.
//
// Full Syntax:
// https://docs.astro.build/core-concepts/astro-components/
const builtAt: Date = new Date();
const builtAtFormatted = format(builtAt, 'MMMM dd, yyyy -- H:mm:ss.SSS');
---
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Astro Playground</title>
<style>
header {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
margin-top: 15vh;
font-family: Arial;
}
.note {
margin: 0;
padding: 1rem;
border-radius: 8px;
background: #E4E5E6;
border: 1px solid #BBB;
}
</style>
</head>
<body>
<header>
<img width="60" height="80" src="https://bestofjs.org/logos/astro.svg" alt="Astro logo">
<h1>Hello, Astro!</h1>
<p class="note">
<strong>RENDERED AT:</strong><br/>
{builtAtFormatted}
</p>
</header>
</body>
</html>需要注意{builtAtFormatter}如何用于在标记中引用构建时变量。
现在添加一个组件。单击顶部文件栏中的加号图标,如图1所示。

图1.添加组件
用户的新组件将收到一个默认名称(Component1.astro)和内容,如清单2所示。
---
const name = "Component"
---
<h1>Hello {name}</h1>这里又有一个简单的变量赋值和显示,可以利用主页中的组件。
返回到Page.astro。需要注意的是,系统已将导入插入到JavaScript段中:
import Component from '@/Component.astro';可以通过将<Component/>插入标记来使用这一组件。执行这个操作,将在预览窗口中看到子组件的输出。
Astro的超级能力是它对各种其他框架的支持。它通过在构建过程中使用渲染引擎来实现这一点,并将它们编译成组件“孤岛”实现这一点。以下了解下这是如何工作的。
如果打开这个链接,将看到一个运行Svelte组件的Astro应用程序(https://stackblitz.com/edit/github-5jbyfh?file=astro.config.mjs中的示例演示了几个显示引擎)。
在上面链接的Svelte演示中,首先要注意的是astro.config.mjs文件。该文件的内容类似于清单3。
export default /** @type {import('astro').AstroUserConfig} */ ({
// Enable the Svelte renderer to support Svelte components.
renderers: ['@astrojs/renderer-svelte'],
});清单3展示了如何启用Svelte,因此引擎将理解Svelte组件。现在可以将Svelte文件直接导入Astro文件。例如,将这一行添加到/pages/index.astro:
import Counter from '../components/Counter.svelte现在可以在Astro中使用Svelte中的Counter,如清单4所示。
<Counter client:visible>
<h1>Hello, Svelte!</h1>
</Counter>尽管这是Svelte的典型用法,但需要注意Counter上有一个特定于Astro的属性:client:visible。这意味着组件不会被加载到客户端,除非它在页面上可见。因此,它以最少的努力实现了一些细粒度的延迟加载。
Astro支持Svelte、React、Vue、Solid、Preact和Lit。使用它们的过程就像使用Svelte一样。事实上,可以启用多个显示引擎并在Astro应用程序中并排使用它们。
除了集成之外,Astro还提供了几个主题和启动器。
人们已经看到了client:visible指令的作用。还有其他可用的。在每种情况下,该指令首先告诉Astro在客户端上呈现组件及其附带的JavaScript,而不是执行服务器显示并发送HTML。然后,它会告诉Astro如何为组件进行水合。
Astro的客户端指令控制页面上组件的水合方式。
<MyComponent client:load/>:在页面加载时水合组件。
<MyComponent client:idle/>:一旦主线程空闲(使用requestIdleCallback()),就会水合组件。
<MyComponent client:visible/>:元素进入视口后立即水合组件(使用Intersection Observer)。适用于页面下方的内容。
<MyComponent client:media={QUERY}/>:一旦浏览器匹配给定的媒体查询(使用matchMedia),就会水合组件。对于侧边栏切换或仅应在移动或桌面设备上显示的其他元素很有用。
<MyComponent client:only={string}/>:在页面加载时水合组件,仅在客户端上呈现。将组件的框架作为字符串(例如,“svelte”)。由于Astro本质上是一个构建工具,它可以完全控制最终发送到用户浏览器的内容。这意味着除了使用延迟加载的JavaScrip做一些事情之外,Astro还可以处理它如何交付其他资产,例如CSS。
此外,Astro的目标是将尽可能多的JavaScript提取为直接的HTML,这意味着更少的网络数据、更少的浏览器流失和更快的交互时间。
总体而言,尽管Astro更适合静态网站,但它是一种有前途的创新方法,也是一个非常活跃的项目,在GitHub上有将近16000颗星。
原文标题:Intro to Astro: Clever lazy loading for JavaScript,作者:Matthew Tyson
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co
我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty
Region是HBase数据管理的基本单位,region有一点像关系型数据的分区。region中存储这用户的真实数据,而为了管理这些数据,HBase使用了RegionSever来管理region。Region的结构hbaseregion的大小设置默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动进行拆分。刚拆分时,两个子Region都位于当前的RegionServer,但处于负载均衡的考虑,HMaster有可能会将某个Region转移给其他的RegionServer。RegionSplit时机:当1个region中的某个Store下所有StoreFile
是否可以在所有delayed_job任务之前运行一个方法?基本上,我们试图确保每个运行delayed_job的服务器都有我们代码的最新实例,所以我们想运行一个方法来在每个作业运行之前检查它。(我们已经有了“check”方法并在别处使用它。问题只是关于如何从delayed_job中调用它。) 最佳答案 现在有一种官方方法可以通过插件来做到这一点。这篇博文通过示例清楚地描述了如何执行此操作http://www.salsify.com/blog/delayed-jobs-callbacks-and-hooks-in-rails(本文中描述
我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的
如何只加载map边界内的标记gmaps4rails?当然,在平移和/或缩放后加载新的。与此直接相关的是,如何获取map的当前边界和缩放级别? 最佳答案 我是这样做的,我只在用户完成平移或缩放后替换标记,如果您需要不同的行为,请使用不同的事件监听器:在你看来(index.html.erb):{"zoom"=>15,"auto_adjust"=>false,"detect_location"=>true,"center_on_user"=>true}},false,true)%>在View的底部添加:functiongmaps4rail
我需要做这样的事情classUser'User',:foreign_key=>'abuser_id'belongs_to:gameendclassGame['JOINabuse_reportsONusers.id=abuse_reports.abuser_id','JOINgamesONgames.id=abuse_reports.game_id'],:group=>'users.id',:select=>'users.*,count(distinctgames.id)ASgame_count,count(abuse_reports.id)asabuse_report_count',:
我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan