Hello 大家好!
今年三月,我经历了一次职业转折------被公司裁员了。工作了这么久,确实感觉有些疲惫,也萌生了转型的想法。正如那句老话所说:"大丈夫生于天地之间,岂能郁郁久居人下?"是时候为自己创造点什么了。
虽然一时之间有些迷茫,不确定该从何处着手,但我决定从一个简单的工具网站开始。我总结了自己日常工作中对工具的需求,发现最频繁的场景就是图片压缩和格式转换。于是,一个图片转换器项目就这样诞生了!
Limgx:我的图片转换神器
我为这款产品起名为 Limgx。
- L 代表 local(本地处理)
- img 代表 图片
- X 则寓意着转换功能
一个简单直接,又充满力量的名字!
欢迎访问我的作品:limgx.com
撸起袖子写代码!
实现方案:FFmpeg.WASM 的惊喜发现
在构思实现方案时,我最初考虑的是传统的前端 Canvas 本地处理 或搭建服务器进行转换 。但在调研过程中,我意外发现了一个令人兴奋的黑科技:FFmpeg 竟然有 WASM 版本 !ffmpegwasm.netlify.app/
虽然 WASM 版本在性能上可能不及本地原生 FFmpeg,但它绝对比 Canvas 转换快得多!唯一的"缺点"是 WASM 包体积达到了 30MB。不过,通过精心优化用户体验和浏览器缓存机制,我认为这并不是一个大问题。
FFmpeg.wasm 的使用方法非常直观,就像在命令行中拼接参数一样简单:
JavaScript
javascript
const transcode = async () => {
const ffmpeg = ffmpegRef.current;
// 写入输入文件
await ffmpeg.writeFile('input.webm', await fetchFile('https://raw.githubusercontent.com/ffmpegwasm/testdata/master/Big_Buck_Bunny_180_10s.webm'));
// 执行转换命令
await ffmpeg.exec(['-i', 'input.webm', 'output.mp4']);
// 读取输出结果
const data = await ffmpeg.readFile('output.mp4');
}
为了让用户能灵活选择输入输出质量,我们需要将这些参数动态传入。由于不同的图片格式需要不同的编解码器和参数,为了保持代码的整洁和可维护性,我采用了策略模式。以下是一个处理 WebP 转换的策略示例:
JavaScript
typescript
/**
* WebP转换策略
* 处理WebP格式的图像转换与压缩
*/
export class WebPConversionStrategy implements ConversionStrategy {
getArgs(inputFileName: string, outputName: string, quality: number, width?: number, height?: number): string[] {
const args = ['-i', inputFileName];
// 分辨率缩放
if (width || height) {
let scaleArg = 'scale=';
scaleArg += width ? `${width}:` : '-1:';
scaleArg += height ? `${height}` : '-1';
args.push('-vf', scaleArg);
}
// 明确指定使用libwebp编码器
args.push('-c:v', 'libwebp');
// WebP质量控制(直接使用0-100的质量值)
args.push('-quality', String(quality));
// 确保使用有损压缩
args.push('-lossless', '0');
// 使用最佳压缩方法
args.push('-method', '6');
args.push(outputName);
return args;
}
}
FFmpeg 的强大之处远不止于此,除了图片转换,它还能轻松扩展到 WebP 或 GIF 动图生成器等更多有趣的应用场景。
技术栈选择与考量
方案敲定后,我开始选择合适的技术栈。最终,我选择了 Next.js + Tailwind CSS + Shadcn UI + next-intl + ffmpeg.wasm 的组合。
在部署平台方面,我选择了 Cloudflare 。虽然 Next.js 与 Vercel 的搭配更为"官方",但 Cloudflare 的无限免费流量对我来说极具吸引力,并且它还集成了域名管理等功能,让我的运维工作能统一在 Cloudflare 平台上进行。
SEO:网站流量的生命线
对于个人搭建的网站,很大一部分流量都来源于 SEO(搜索引擎优化) ,因此它成为了重中之重。
- 服务端渲染 (SSR): 为了 SEO 考虑,我的框架必须支持 SSR。我选择了 Next.js。但如果现在重新开始,我可能会更倾向于使用 SolidStart。原因很简单:我的网站对 React 生态的依赖不多,而 Solid.js 页面的性能指标(如 TTFB 和 TTI)在某些情况下可能会优于 React 页面,这有助于我在 SEO 排名中获得更高的位置。
- 国际化 (i18n): 我使用了 next-intl 这个库来实现国际化。它支持 i18n 路由,能够根据语言动态生成带有翻译的元数据(metadata),这对全球用户和搜索引擎都非常友好。
样式与设计:兼顾美观与效率
我选择了 Shadcn UI 和 Tailwind CSS 的组合。Shadcn UI 提供了一套独特的设计风格和可复用的组件,同时又允许我根据需要进行深度定制。
至于网站的整体设计,我尝试了借助 AI 来辅助。虽然结果有时比较随机,但最终的效果我个人感觉还不错!
总结一下
目前网站流量较少,推测可能因 Google 尚未抓取到新内容。新站提交 Sitemap 后需一定时间生效,计划先观察一个月。
想请问各位是否有优化建议?