1. 静态资源处理
- 图片优化:
- 使用现代图片格式如WebP,它通常比JPEG和PNG有更好的压缩比。可以通过构建工具(如Vite,Qwik常用构建工具)配置自动将图片转换为WebP格式。
- 对于不同设备分辨率,使用
srcset
属性提供多个不同分辨率的图片版本,浏览器会根据设备像素比自动选择合适的图片,减少不必要的带宽浪费。
- 字体优化:
- 子集化字体,只包含应用中实际使用到的字符,减小字体文件大小。例如,如果应用只使用英文字符,就无需包含整个中文字体集。
- 采用
font-display
属性控制字体加载和显示策略。比如设置为font-display: swap
,让浏览器尽快显示文本,然后在后台加载字体,避免文本闪烁。
2. 代码分割
- 基于路由的代码分割:
- Qwik应用通常基于路由构建。利用Qwik的路由系统,将不同路由对应的组件代码进行分割。这样,当用户访问特定路由时,才会加载该路由对应的组件代码,而不是一次性加载整个应用的代码。例如,一个电商应用中,商品列表页和商品详情页的代码可以分别在用户访问相应页面时加载。
- 可以通过Qwik的路由配置语法,如
import { component$ } from '@builder.io/qwik';
来实现路由组件的动态导入。
- 组件级代码分割:
- 对于大型组件,将其拆分为更小的子组件,并对这些子组件进行代码分割。比如一个复杂的表单组件,可拆分为输入框、下拉框等子组件,只有在需要渲染这些子组件时才加载其代码。
- 使用动态
import()
语法在组件内部进行子组件的懒加载。例如:
const MySubComponent = () => {
const [SubComponent] = useLoader(() => import('./MySubComponent.qwik'));
return <SubComponent />;
};
3. 组件渲染优化
- 减少不必要的重渲染:
- 使用
@qwik/core
中的useMemo
和useCallback
钩子。useMemo
用于缓存计算结果,避免在组件每次渲染时都重新计算。例如,如果一个组件依赖一个复杂的计算值,可使用useMemo
缓存该计算结果:
const expensiveValue = useMemo(() => {
// 复杂计算
return result;
}, []);
- `useCallback`用于缓存函数,防止函数在组件每次渲染时都重新创建,从而避免子组件因父组件传递的函数引用变化而不必要的重渲染。
- 优化组件嵌套结构:
- 尽量扁平化组件结构,避免过深的嵌套层次。过深的嵌套可能导致不必要的渲染开销。例如,可以将一些中间层组件进行合并或简化。
- 对于一些频繁更新但不影响整体布局的子组件,可以考虑使用
Fragment
包裹,避免额外的DOM节点创建和销毁带来的性能开销。
- SSR(服务器端渲染)与SSG(静态站点生成):
- 如果应用场景适合,利用Qwik的SSR能力。在服务器端渲染页面的初始HTML,可以显著提高页面的首次加载速度。服务器可以将已经渲染好的HTML发送给客户端,客户端只需进行少量的 hydration(将静态HTML转换为可交互的应用)操作。
- 对于内容相对固定的部分,使用SSG生成静态页面。例如,博客应用的文章页面可以在构建时生成静态HTML文件,直接提供给用户,进一步加快加载速度。
4. 数据获取优化
- 缓存数据:
- 使用浏览器本地缓存(如
localStorage
或sessionStorage
)来缓存一些不经常变化的数据。例如,用户的设置信息、一些基础配置数据等。在组件需要这些数据时,优先从本地缓存读取,减少网络请求。
- 对于通过API获取的数据,可以在应用层实现简单的缓存机制。例如,使用一个全局的缓存对象,在每次请求数据前先检查缓存中是否有对应的数据,如果有则直接使用,避免重复请求。
- 批量数据请求:
- 如果组件需要从多个API获取数据,尽量将这些请求合并为一个或少量的请求。例如,使用
Promise.all
来同时发起多个相关的API请求,减少网络请求次数,提高数据获取效率。