阅读视图

发现新文章,点击刷新页面。

把墨水屏带到AIPC上很酷,但这可能不是个好主意

自从墨水屏被发明出来,和阅读器就是一对天作之合。

但这显然是一个增长正在放缓的市场,而世界上最大的墨水屏制造商 E Ink 心急如焚,他们想把墨水屏卖到更多的地方——比如学习机,或者盒马超市里的价格标签。

而 E Ink 最新看上的地方,是 AIPC——准确来说,是 AIPC 上的触控板。

7 月 1 日,E Ink 元太科技宣布,要把墨水屏做成笔记本电脑的触控板。这个方案将彩色电子纸与传统触控板结合,声称要为 AIPC带来「全新交互体验」。

但 AIPC真的需要一块墨水屏吗?

▲ E Ink 墨水屏触控板. 图片来自:E Ink

墨水屏触控板确实省电,但这可能不是重点

E Ink 的这个墨水屏触控板方案整合了 Intel Smart Base 技术、Intel Innovation Platform Framework 和 Intel AI Assistant Builder 技术,将彩色电子纸与传统笔电触控板结合——从技术角度看,这套方案确实不是在胡说八道。

最明显的优势是省电。

墨水屏只在内容更新时消耗电力,静态显示时几乎不耗电——这对笔记本续航来说确实是好事。而且墨水屏不发光、无闪烁,长时间使用也不容易眼疲劳。

▲ 墨水屏. 图片来自:E Ink

功能方面听起来也挺丰富:触控板不仅保留了原有的触控操作,还能显示各种 AI 生成的内容。系统可以在上面显示常用快捷键、系统提醒,甚至是 AI 生成的文字摘要、图像内容,或者游戏攻略。用户还能查看天气、便条备忘录、会议记录,笔记本关机时甚至能显示个性化壁纸。

听起来很美好,但问题来了:

有多少人真的需要在触控板上和 AI 对话?看天气预报?

这些功能在手机上、在电脑桌面上不是都能更方便地实现吗?把它们塞进一个几英寸大的触控板里,到底是为了解决问题,还是为了制造问题?

▲ 墨水电子屏. 图片来自:E Ink

笔记本电脑做副屏,很酷但没用

说到笔记本副屏,苹果已经给所有人上了一课。

2016 年,苹果在 MacBook Pro上推出 Touch Bar——用一条 OLED 触摸屏取代传统功能键。苹果声称这是笔记本的「最大变革」,能提供动态快捷键和应用专属功能。

五年后,苹果在 2021 年取消了 Touch Bar,乖乖回到传统功能键——究其原因,还是因为 Touch Bar 实在太难用了,不仅难以盲操,还徒增成本。传统F键闭着眼睛都能按对,Touch Bar 却要低头去看,效率反而下降了。更要命的是,它让笔记本成本增加了不少,却没带来相应的价值——最终,Touch Bar 的软件生态也没有养成,MacBook Pro 轰轰烈烈的副屏革命就这样惨淡收场。

▲ Touch Bar. 图片来自:Apple

不止苹果,许多 Wintel 阵营的厂商也试过水。华硕曾在 ZenBook Pro 系列上推出过 ScreenPad,把标准触控板和高分辨率 LCD 触摸屏合二为一,可以显示数字键盘、应用图标等,看起来很酷,但实际用起来,大部分时间就是个摆设,还影响手感。

其他厂商也有过类似的尝试,但结果都基本都是叫好不叫座。背后的原因确实也不复杂——

这些副屏破坏了笔记本交互的简洁性。用户本来就要处理主屏的信息,现在还得分心去看触控板上的内容。而且这些副屏通常不能独立完成任务,必须配合主屏使用——对于笔记本电脑这样的生产力工具而言,这种设计从根本上就是多余的。

▲ 墨水屏的应用. 图片来自:E Ink

当然,E Ink 做墨水屏触控板的动机倒是能理解。毕竟电子书市场在萎缩,商业公司得找到新的出路。从商业角度看,这种探索精神值得肯定,和 AI 硬件结合也确实是个方向。

但问题是, 和 AIPC 的结合或许真不是个好主意。我们在买笔记本电脑的时候,要的是更好的性能、更长的续航、更合理的价格,而不是一个可能永远用不上的「触控板墨水屏」。

与其在副屏这条死路上继续撞南墙,E Ink 不如把精力放在电子纸已经验证过的场景上——阅读器、价格标签、户外显示,这些才是墨水屏真正发光发热的地方。

#欢迎关注爱范儿官方微信公众号:爱范儿(微信号:ifanr),更多精彩内容第一时间为您奉上。

爱范儿 | 原文链接 · 查看评论 · 新浪微博


大佬们指点一下倒计时有什么问题吗?

看了另外一张帖子,关于倒计时组件的,就自己写了一个,大家帮忙看下,写得怎么样?有什么问题,可以指出来!

<div class="time"></div>
function countdown(time) {
    let lastTime = Date.now();
    let rafId;
    function refresh() {
        const curTime = Date.now();
        const more = curTime - lastTime - 1000;
        if (more > 0) {
            lastTime = curTime + more;
            const nextTime = time--;
            if (nextTime === 0) {
                cancelAnimationFrame(rafId);
                return;
            }
            update(time);
        }
        rafId = requestAnimationFrame(refresh);
    }

    function update(restTime) {
        const h = restTime > 3600 ? Math.floor(restTime / 60) : 0;
        const m = Math.floor((restTime - h * 3600) / 60);
        const s = restTime - h * 3600 - m * 60;
        const dom = document.querySelector('.time');
        dom.innerHTML = `剩余${h}小时${m}分钟${s}秒`;
    }
    refresh();
    update(time);
}
countdown(1000);

深入解析WeUI Uploader组件源码:移动端上传组件实现

最近在研究WeUI的源码,发现Uploader组件的设计真的很有意思。我想分享一下对这个组件的深度解析。

为什么要学习WeUI Uploader?

说实话,uploader组件在大厂面试中出现频率真的很高。不仅仅是因为它功能重要,更是因为它背后蕴含的设计思想和编码技巧。通过研究高质量的源码,我们能学到:

  • 语义化标签的正确使用
  • BEM命名规范的实际应用
  • 弹性布局的巧妙运用
  • CSS预处理器的模块化思维
  • 移动端适配的细节处理

整体架构分析

让我们先看看HTML结构,这里的设计很有讲究:

<div class="weui-cells weui-cells_form">
  <div class="weui-cell weui-cell_uploader">
    <div class="weui-cell__bd">
      <div class="weui-uploader">
        <div class="weui-uploader__hd">
          <p class="weui-uploader__title">图片上传</p>
          <div class="weui-uploader__info">
            <span>0</span> / <span>2</span>
          </div>
        </div>
        <div class="weui-uploader__bd">
          <ul class="weui-uploader__files">
            <!-- 文件列表 -->
          </ul>
        </div>
      </div>
    </div>
  </div>
</div>

这个结构乍看复杂,但仔细分析会发现设计得很巧妙:

  • 最外层 .weui-cells 提供了统一的表单容器
  • 中间层 .weui-cell 作为单个表单项的包装
  • 内层 .weui-uploader 才是真正的上传组件

这种层级设计的好处是什么?复用性和一致性.weui-cells 不仅用于uploader,还能用于其他表单元素,保持了整个UI体系的一致性。

移动端适配的精妙细节

在CSS实现中,有几个细节特别值得关注:

1. 滚动优化

.page {
  overflow: scroll;
  -webkit-overflow-scrolling: touch;
}

这里的 -webkit-overflow-scrolling: touch 是个神奇的属性。它能让移动端的滚动更加顺滑,感知touch事件更敏感。虽然是webkit前缀的实验性属性,但在移动端(iOS和Android都基于webkit内核)使用效果很好。

2. 弹性布局的应用

.weui-uploader__hd {
  display: flex;
  align-items: center;
}
.weui-uploader__title {
  flex: 1;
}

这里用flex布局来处理标题和计数器的对齐,flex: 1 让标题占据剩余空间,计数器自然靠右对齐。简洁而优雅。

3. 伪元素的巧妙运用

.weui-cells::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 1px;
  background-color: #86e98c;
  z-index: 2;
}

用伪元素画分割线,这比直接用border要灵活得多,可以精确控制线条的位置和样式。

Stylus预处理器的威力

项目中使用了Stylus作为CSS预处理器,这里有几个值得学习的技巧:

变量系统

$weui-bg-0 = #6ad8eb
$weui-bg-2 = #fff
$weui-fg-1 = #c177e6 
$weui-fg-2 = #888
$weui-fg-3 = #86e98c

这套变量命名很有规律:bg表示背景色,fg表示前景色,数字表示层级。这种命名方式让主题切换变得非常简单。

嵌套语法的优势

.weui-uploader
  .weui-uploader__hd
    display flex
    .weui-uploader__title
      flex 1
    .weui-uploader__info
      color $weui-fg-2

Stylus的嵌套语法让CSS结构更清晰,配合BEM命名规范,代码可读性大大提升。

float布局的考量

在文件列表的实现中,使用了float布局:

.weui-uploader__file {
  float: left;
  margin-right: 8px;
  margin-bottom: 8px;
  width: 96px;
  height: 96px;
}

可能有人会问:都2024年了,为什么不用grid或flex?

其实这里有几个考虑:

  1. 兼容性:float布局兼容性最好,特别是在一些老旧的webview中
  2. 性能:对于简单的网格布局,float的性能开销更小
  3. 灵活性:float布局在处理不等高元素时更加灵活

BEM命名规范的实践

整个组件严格遵循BEM命名规范:

  • Block(块).weui-uploader
  • Element(元素).weui-uploader__hd.weui-uploader__bd
  • Modifier(修饰符).weui-cell_uploader

这种命名方式的好处是:

  1. 语义明确,一眼就能看出元素的作用
  2. 避免样式冲突
  3. 便于维护和扩展

实际开发中的应用

在实际项目中,我们可以基于这个设计思路来优化自己的组件:

// 编译命令
// stylus -w common.styl -o common.css

这个编译命令告诉我们,项目采用了watch模式,修改styl文件后自动编译成CSS。这种开发方式大大提高了效率。

成果展示(换了颜色)

image.png

总结

通过分析WeUI Uploader组件的源码,我们学到了很多有价值的技巧:

  1. 分层设计思维:通过合理的层级结构提高复用性
  2. 移动端优化:关注细节,提升用户体验
  3. CSS预处理器:变量系统和嵌套语法的合理运用
  4. 命名规范:BEM规范让代码更易维护
  5. 技术选型:根据实际需求选择合适的布局方案

这些技巧不仅适用于组件开发,在日常的前端开发中都很有参考价值。希望这篇分析能帮助大家更好地理解移动端UI组件的设计思路。

最后想说的是,学习源码不是为了炫技,而是为了提升我们的代码质量和设计思维。每一个看似简单的组件背后,都蕴含着开发者的智慧和经验。

✅ Lodash 常用函数精选(按用途分类)

🧩 一、数组处理

函数 功能 示例
_.chunk 将数组拆分成指定大小的块 _.chunk([1,2,3,4], 2) → [[1,2],[3,4]]
_.uniq 去重 _.uniq([1,2,2,3]) → [1,2,3]
_.flatten / _.flattenDeep 扁平化数组 _.flatten([1,[2,[3]]]) → [1,2,[3]]
_.intersection 求交集 _.intersection([1,2],[2,3]) → [2]
_.difference 求差集 _.difference([1,2,3],[2]) → [1,3]
_.zip 多数组按索引组合 _.zip(['a','b'],[1,2]) → [['a',1],['b',2]]

🧱 二、对象操作

函数 功能 示例
_.get 安全取值(避免深层访问报错) _.get(obj, 'a.b.c', '默认')
_.set 安全赋值 _.set(obj, 'a.b.c', 123)
_.merge 深度合并对象 _.merge(obj1, obj2)
_.omit / _.pick 删除/保留指定属性 _.omit(user, ['password'])
_.cloneDeep 深拷贝 _.cloneDeep(obj)

🔧 三、函数工具

函数 功能 示例
_.debounce 防抖 输入框防止频繁触发请求
_.throttle 节流 滚动监听时控制触发频率
_.once 只执行一次 初始化操作
_.memoize 缓存函数调用结果 重复调用节省性能

💡Vue 和 React 中常与防抖节流配合使用!


📊 四、集合处理(对象数组常用)

函数 功能 示例
_.groupBy 按字段分组 _.groupBy(users, 'age')
_.orderBy 排序 _.orderBy(users, ['age'], ['desc'])
_.filter 条件过滤(增强版) _.filter(users, {active: true})
_.map 转换集合 _.map(users, 'name')
_.find / _.findLast 查找符合条件的第一项 _.find(users, {id: 1})

🧠 五、类型判断

函数 功能 示例
_.isArray 判断是否数组 _.isArray([])
_.isEmpty 判断是否为空 _.isEmpty({}) → true
_.isEqual 判断值是否深度相等 _.isEqual(obj1, obj2)
_.isPlainObject 是否普通对象 _.isPlainObject({})

🧪 六、字符串处理

函数 功能 示例
_.camelCase 转驼峰 _.camelCase('hello world') → 'helloWorld'
_.kebabCase 转中划线格式 _.kebabCase('Hello World') → 'hello-world'
_.capitalize 首字母大写 _.capitalize('hello') → 'Hello'
_.trim 去除两端空格 _.trim(' abc ') → 'abc'

📌 推荐使用组合

举个业务中常见的例子:

ts
复制编辑
// 多维对象中取值 + 判断是否为空
if (!_.isEmpty(_.get(userInfo, 'profile.name'))) {
  console.log('用户已填写名称');
}

🧰 快速参考图(Mermaid)

mermaid
复制编辑
graph LR
A[Lodash核心函数] --> B[数组类]
A --> C[对象类]
A --> D[函数类]
A --> E[集合类]
A --> F[类型判断]
A --> G[字符串类]

📚 推荐练习项目

适用水平 项目
初级 在 Vue/React 中封装表格查询功能,使用 _.get/_.merge
中级 实现“标签去重+分组显示”功能
高级 封装数据格式转换器(深层字段映射、字段重命名)

写100个前端效率工具(3):国际化 js 库 yyq-i18n

我们开发前端产品时,有时候会涉及到适应不同国家或者地区,这时候,我们需要根据不同国家或者地区的语言进行国际化处理。

yyq-i18n 是一个很mini的国际化库,可以帮助我们快速实现国际化处理。当然了,需要自行写集成如 Vue、React 等响应绑定处理,很简单的啦。

📦 安装指南

选择你喜欢的包管理器安装:

# npm
npm install yyq-i18n@latest

# yarn
yarn add yyq-i18n@latest

# pnpm
pnpm add yyq-i18n@latest

✨ 核心优势:

  • 轻量级 - 代码体积小,没有外部依赖
  • 框架无关 - 不依赖于任何前端框架,可在任何JavaScript环境中使用
  • 简单直接 - API简洁,容易理解和使用
  • 定制灵活 - 可以根据你想要的,轻松修改和扩展

1、轻量级

除了定义外,核心代码实际上就30行左右,没有外部依赖。

2、框架无关

使用 Typescript 和 ES6 编写,(打包后的代码)可以使用在任何 JavaScript 环境中。

3、简单直接

为什么说简单直接呢,你们往下看看就知道了。

add 方法

如其名,add 就是用来添加语言资源。

import { Locale, add, use, t } from 'yyq-i18n'
const zhCNJson = { lang: '中文简体' }
add('zh-CN', zhCNJson)
use('zh-CN')
console.log('currentLang', Locale.currentLang) // zh-CN
console.log('currentResource', Locale.currentResource) // { lang: '中文简体' }

merge 方法

merge 方法用于合并语言资源。不知道有没有用处,先放着。

import { Locale, add, merge, use, t } from 'yyq-i18n'
const zhCNJson = { lang: '中文简体' }
add('zh-CN', zhCNJson)
use('zh-CN')
console.log('currentResource', Locale.currentResource) // { lang: '中文简体' }

// 扩展
merge('zh-CN', { more: '我是后边来的更多内容' })
console.log('currentResource', Locale.currentResource) // { lang: '中文简体'。 more: '我是后边来的更多内容' }

use 方法

use 方法用于切换语言,比如说自动获取当前所在的语言。

import { Locale, use } from 'yyq-i18n'
console.log('currentLang', Locale.currentLang) // zh-CN

 // 假设返回: zh-TW
const userAgentLang = navigator.language || navigator.userLanguage
use(userAgentLang)
console.log('currentLang', Locale.currentLang) // zh-TW

t 方法

t 方法,根据传入的参数,替换成当前设置的语言所在的翻译文本。支持默认值处理、插值处理。

type funcT = <T extends string>(key: PropertyKey, paramsOrDefaultValue?: Partial<Resource> | T) => ValueOf<Resource> | T
import { Locale, add, use, t } from 'yyq-i18n'
const zhCNJson = { lang: '中文简体', welcome: '你好,{name}', today: '{today}是{date}' }
add('zh-CN', zhCNJson)
use('zh-CN')

console.log(t('lang')) // 中文简体

// 默认值处理
console.log(t('name', '默认值'))

// 插值处理
console.log(t('welcome', { name: '张三' })) // 你好,张三
console.log(t('today', { today: '今天', date: '2025年10月1日' })) // 今天是2025年10月1日

😇 最后

yyq-i18n  希望大家喜欢,求个 star。

面试官:useEffect 为什么总背刺?我:闭包、ref 和依赖数组的三角恋

🧠 系列前言:

面试题千千万,我来帮你挑重点。每天一道,通勤路上、蹲坑时、摸鱼中,技术成长不设限!本系列主打幽默 + 深度 + 面霸必备语录,你只管看,面试场上稳拿 offer!

💬 面试官发问:

“说说你对 useEffect 的理解?依赖项为什么总是填不对?闭包陷阱怎么解?”

哎哟妈呀,这题一出,多少前端人梦回凌晨 2 点 debug 页面逻辑,满脸问号:我明明写对了,怎么又触发了?

🎯 快答区(面霸速记版)

  • useEffect 是一个副作用钩子,默认在组件渲染后执行
  • 依赖项数组控制副作用的触发时机
  • 如果你不理解闭包和引用变化useEffect 就会变身背刺小王子
  • React 的规则是:只要依赖项变了就重新执行

所以填错依赖数组 = 自找 bug

🧬 useEffect 的爱恨情仇

🪝 一、useEffect 到底干嘛的?

在类组件中我们有:

componentDidMount() // 初始化执行一次
componentDidUpdate() // 每次更新都执行
componentWillUnmount() // 组件卸载时执行清理

而在函数组件里,一个 useEffect 全包了:

useEffect(() => {
  console.log('副作用逻辑来咯~')

  return () => {
    console.log('组件卸载 or 依赖变化,清理啦!')
  }
}, [依赖项])

你可以认为:

useEffect = didMount + didUpdate + willUnmount 的组合技。

🎭 二、为什么依赖项这么重要?

你写副作用:

useEffect(() => {
  fetchData(keyword)
}, [])

看起来没毛病吧?但 keyword 改了,页面没更新,debug 一看:

啊这……你把 keyword 忘写进依赖数组了!

React 的机制是:

只要依赖数组里的值发生变化useEffect 就重新执行。

而且还有 ESLint 小助手在旁边耳语:

“你漏了依赖项,要不要加上?”

别不信邪,真不加,等着被 bug 追着打。

🧟‍♂️ 三、闭包 + useEffect = 鬼打墙现场

来看经典误区:

const [count, setCount] = useState(0)

useEffect(() => {
  const timer = setInterval(() => {
    console.log(count) // 👈 永远是 0!
  }, 1000)
}, [])

你以为能打印 count 的实时值?结果它永远是 0。为啥?

闭包记住的是第一次的 count 值,后续不会变。

React 不会每次都重新创建这个函数,它只在第一次 [] 时执行了一次副作用。

✅ 正确解法 1:依赖更新版本

useEffect(() => {
  const timer = setInterval(() => {
    console.log(count)
  }, 1000)

  return () => clearInterval(timer)
}, [count]) // 每次 count 变化都重新注册

但这样每次都清除+重新 setInterval,其实效率不高。

✅ 正确解法 2:使用 ref 保存可变值

const countRef = useRef(count)

useEffect(() => {
  countRef.current = count
}, [count])

useEffect(() => {
  const timer = setInterval(() => {
    console.log(countRef.current) // 永远拿到最新值
  }, 1000)

  return () => clearInterval(timer)
}, [])

完美解决闭包问题,让副作用逻辑始终拿到最新值。

🕳 四、useEffect 执行时机:同步还是异步?

很多人以为 useEffect 是异步的,其实更准确地说是:

useEffect 是 在浏览器完成 paint 之后 执行的副作用,也就是 非阻塞渲染

🎥 补充一个:

  • useEffect页面绘制后执行
  • useLayoutEffectDOM 变更后、页面绘制前同步执行(可能会阻塞渲染)

一般推荐默认用 useEffect,只有你要测量 DOM 或强制修改布局时,才上 useLayoutEffect

🎯 五、React 官方建议怎么写依赖项?

✅ 尽可能声明清晰依赖

useEffect(() => {
  fetchData(keyword)
}, [keyword])

❌ 不推荐写成这样:

useEffect(() => {
  fetchData(keyword)
}, []) // 靠闭包?你会后悔的

✅ 对象依赖,记得 memo

const filter = useMemo(() => ({ name }), [name])

useEffect(() => {
  fetchData(filter)
}, [filter])

避免每次都触发,因为 { name } 每次都是新对象。

🎓 装 X 语录(限时使用)

“useEffect 的本质是响应式副作用收集器,依赖数组的变化驱动副作用重跑。”

“闭包陷阱其实是 JS 的机制,不是 React 的锅。ref 是解决数据脱离组件周期的利器。”

“副作用的清理逻辑相当于生命周期中的 willUnmount,能防止内存泄漏和状态污染。”

说完记得压低语气、语速慢一点,表现你是“老油条 + 热爱原理派”。

✅ 总结一句话

useEffect = 渲染之后的副作用管理器,依赖数组驱动重跑,闭包问题靠 ref 或更新依赖解决

写对它,你是高手;写错它,它就是你项目里的定时炸弹💣。

🔮 明日预告

明天我们聊聊 useCallback 和 useMemo,它们到底是性能优化神器,还是“性能幻想剂”?怎么用才能不白费 CPU?⚙️

📌 点赞 + 收藏 + 关注系列,React Hook 不再“Hook”住你!

自研 M 芯片五周年,苹果站在时代的交界点,和 Intel 挥手道别

当我们谈论 macOS Tahoe 时,我们在谈论什么?

大部分讨论都集中在这个全新的液态玻璃设计,或者消失的启动台,还有那个变来变去的访达图标。

但或许没那么为人所知的是,macOS Tahoe 将会是最后一代支持 Intel 处理器 Mac 的版本,不过苹果承诺,还会为升级 Tahoe 的老 Mac 提供三年的安全更新。

苹果也同时宣布,后年的 macOS 28 将不再包含完整的 Rosetta 2,只包含部分组件,运行那些不会再更新的老应用和游戏。

也就是说,macOS Tahoe 既可以说是苹果全新时代的开始,也是一个旧时代的落幕。

押注 Intel 不如押注自己

现在看来,Mac 从ARM 到 Intel 的过渡走得相当平稳,甚至比当年从 PowerPC 上转移到 Intel 还要更丝滑,并且为苹果带来了丰厚的回报,但在当时,外界并没有那么看好 Mac 自研芯片。

主要原因是两个:从 x86 转变为 ARM,意味着苹果将抛弃 15 年来的应用生态积累;也有不少偏见,认为「ARM」芯片是手机专属,无法处理「桌面级」的繁重任务,x86 芯片依旧是干重活的首选。

并且隔壁家的微软在 Windows ARM 这个概念上可以说屡败屡战,即使联手了移动芯片巨头高通,Surface Pro X 也只能说是差强人意。

但事实证明,不是 ARM 不行,是同行们真的太拉垮。

现在回看,2018-2019 年那个节点,确实是苹果朝 ARM 过渡的最好时机:彼时的 Intel 裹足不前,一直潜心捣鼓14nm,而同期代工苹果 iPhone 和 iPad 处理器的台积电工艺已经来到 7nm,性能也逐渐接近,甚至超越 Intel 处理器。

▲ Intel 和 苹果 A 芯片性能历年对比图,图源:ANANDTECH

不过,M1 诞生的根本原因,不是苹果已经厌烦了关于 Intel Mac 太热性能太差的批评,而是苹果坚持自研芯片的水到渠成,《时代》杂志在 WWDC 后给出这样的评价:

苹果押注自己,可能是自押注 Intel 以来做过最佳的决定。

GPU、CPU 和内存同一封装,以及拉满的自研核心配置,M1 比起传统的电脑处理器,更像是一块超强的 iPhone 处理器,并且兼顾了低功耗和高性能,让全新的 M1 Mac 产品,比搭载 Intel 处理器的老版本都要更好。

M1 过硬的素质,意味着 Mac 的转型之路通向一个光明的未来,但为这条道路扫清障碍的,则是让 ARM 处理器也能运行 x86 应用的 Rosetta 2。

这个转移层的优越之处在于,在 x86 安装后就把大部分 x86 一次性翻译成 ARM 代码,运行时再针对部分代码进行优化。M1 的强大的单核性能以及大缓存也能很好支持 Rosetta 2,并且片本身也为转译设计了硬件加速机制。

▲ 图源:Lo Zarantonello

所以即使是那些第一时间入手了 M1 Mac 的用户,也会发现这台电脑能够正常运行自己老 Mac 上的大部分应用,甚至会更快,整个转移的过程几乎无感无痛。

这可以说是 Apple Silicon 的一个缩影:硬件和软件都抓在自己手里,意味着彼此之间量体裁衣,提供最佳的体验,而行业里几乎只有苹果在手机、电脑上都做到了这点。

但 Rosetta 2 只是一种过渡的措施,无法完美支持一些体量庞大的专业级应用,因此还是需要开发者基于 ARM 原生开发,而苹果再一次展现了对开发者强大的号召力:连微软 Office 都在 M1 Mac 发售当天正式推出了 ARM 版本,也有不少在 Windows on ARM 完全没影的应用,在苹果开完发布会之后就火速官宣在开发 Mac 的 ARM 版本。

一年后的 M1 Pro、M1 Max 以及 M1 Ultra,则在 M1 的基础上,将统一内存、自研核心这些优势发挥到极致,证明 Apple Silicon 不仅有桌面性能,更有专业级性能,苹果也成功在 M2 时代将 Mac Mini 到 Mac Pro 的所有电脑产品线去 Intel 化。

虽然 M1 诞生时,苹果未必能预见到 2 年后的生成式 AI 井喷,但强力 GPU 核心和超大内存统一封装的模式,确实押中了未来行业对芯片的一种全新需要,而苹果也能顺着 M1 确立好的技术路线直接往上迭代,快人一步推出了能本地运行满血 DeepSeek R1 的 M4 Max。

搅动行业的鲶鱼

作为一个发展 50 年之久的品类,个人消费电脑市场,似乎已经步入一个长期稳定的迭代期,Apple Silicon 入局,真的就像一条鲶鱼,搅动了这潭死水。

当然了,自研芯片不会威胁 Windows 几十年的统治地位,但它展示的前景和技术路线,确实正在影响着整个行业,最终让消费者受益。

M1 Mac 产品上市后,比苹果还更早打造 ARM PC 芯片的高通表示:

苹果 M1 的发布,证明我们进入 ARM 架构 PC 市场的决定是可行的。

参与了 M1 的前苹果前工程师 Gerard Williams,以及其独立的芯片初创公司 NUVIA,在 2021 年被高通收购,随后就推出了骁龙 X Elite 处理器,性能大幅领先之前的骁龙 PC 芯片,联手微软让 Windows on ARM 真正走向了「可用」。

即使是 x86 阵营,也从 Apple Silicon 这种高集成的模式中获益匪浅。

被苹果抛弃的 Intel,在 2023 年推出了主打「AI+低功耗」的酷睿 Ultra 系列,第二代也就是大名鼎鼎的「Lunar Lake」,采用了和 Apple Silicon 一样的内存统一封装,实现了堪比 ARM 平台的高能耗比。

而 AMD 今年年初亮相的性能猛兽处理器 Ryzen AI Max,同样集成了多个 GPU 核心和大内存。虽然 AMD 表示自己立项早于苹果,但 Apple Silicon 的成功为他们证明了这种路线的可行性,项目得以落地。

Apple Silicon 的影响不只于单独几款产品,而是推动了整个半导体行业朝高集成、高能耗比的方向加速迈进,更带动了诸如迷你主机、PC 掌机这些小众品类的增长。

回到苹果自身,M 系列处理器不仅仅推了 Mac 一把,也在多个领域遍地开花,Vision Pro 和苹果自己的 AI 服务器中心中也有身影。

在这个算力竞争疯狂加码的时代,有自己的 AI 芯片,有着极大的战略意义。

当然,这也意味着苹果除了每年的 A 芯片的大迭代,还需要负责有四款子系列的 M 芯片设计,并且后来者逐渐赶上,能耗比上的差距逐渐缩小,性能突破幅度也会不断放缓,这些都是选择自研芯片之后的挑战。

并且,ARM 的舒适区在低功耗的移动场景,一旦来到台式机这种功耗墙更高的领域,x86 的潜力能够完全释放出来,Mac Studio、Mac Pro 这些产品就显得不太够看了。

▲ Mac Pro 已经 3 年未更新,M2 Ultra 版口碑一般

毫不夸张地说,Mac 向 ARM 的转型,其实在他们发布 M1 那一刻已经基本可以宣告完成,而剩下的四年时间,更多只是让用户和开发者逐步和 Intel Mac 告别。

五年过去,即使是在 2020 年入手 Intel Mac 的用户也来到了换机周期,而我们 Mac 上大部分应用也都已经是专门为 Apple Silicon 开发或者是通用应用,因此终于到了彻底说再见的时候。

我还记得去年终于将 MacBook Air 从最后一代 Intel 换到 M1 的那种感觉,明明是同年发布,外观也别无二致,但使用体验明显属于两个时代,后者没有噪音,很难发热,很少卡顿,而它已经四岁了。

有意思的是,当我们回看 2020 年那场 WWDC,会发现库克在预告 M1 即将问世之后,还透露苹果内部正在酝酿一些基于 Intel 芯片的全新 mac。

而五年过去,这些神秘的新 Intel Mac 终究没能问世,但这次没有人批评苹果画饼跳票,因为我们真正期待的 Mac,已经都在苹果官网上了,它们配备的是 Apple Silicon。

#欢迎关注爱范儿官方微信公众号:爱范儿(微信号:ifanr),更多精彩内容第一时间为您奉上。

爱范儿 | 原文链接 · 查看评论 · 新浪微博


荣耀 Magic V5 评测:堆料能解决问题,但堆料解决不了所有问题

如果不算华为,荣耀就是 Android 阵营中,上个季度国内市场折叠屏出货量最高的品牌。

说实话,比起每年的直板机旗舰,我更期待荣耀的大折叠新品,能做多轻薄,能塞下多少配置。

荣耀似乎也很懂这种心态,最新发布的荣耀 Magic V5,就是今年大折叠目前为止少见的「水桶机」:不仅创下最轻最薄的纪录,还配备了目前折叠手机唯一一颗满血骁龙 8 Elite。

可以说,能在折叠手机上塞的配置,Magic V5 都给你加上了。

直板机手感,小平板屏幕

荣耀 Magic V5 的手感,给了我还不错的第一印象。

折叠态 9 毫米厚度,总共 222 克的重量,当然还是比我手上的 iPhone 16 Pro 要更厚重一点,但也已经相当接近。

▲ 左:iPhone 16 Pro,右:荣耀 Magic V5

牺牲这点手感换取一个便携大屏,对于我而言已经完全可以接受。

不过 Magic V5 有两个仁者见仁的设计:一是外屏并非对称设计,左右 R 角并不一致;二是内屏的挖孔在右半边屏幕的居中位置而不是角落,竖屏时会处在一个相对怪异的位置。

而展开之后,就来到了荣耀 Magic V5 的统治区:将近 8 英寸的大屏,拿在手里却只有 222 克重量,加上这个只有 4 毫米出头的「薄」度,手感根本不像一台有大量零部件和电池的电子产品,这是我此前使用其他大折叠手机所没有的体验。

更不用提折叠手机的「平替」对手:以 iPad mini 为首的迷你平板,6.1 毫米的厚度和 293 克的重量都远远超越荣耀 Magic V5。

至于折叠屏手机躲不开的折痕,正常角度看 Magic V5 的内屏,折痕其实完全无法感知,但手指划过还是会有比较明显的触感,也是今年各家折叠屏的正常水准。

但荣耀 Magic V5 的机身有一点我不太满意:异常突出的镜头模组,厚度不止超越一众直板机,甚至能看齐影像旗舰 vivo X200 Ultra。

这带来了一个使用上的问题:我习惯将 Magic V5 展开放在桌面,同时看电脑屏幕和手机大屏,而这个硕大的模组不仅无法平放,还会在我划动手机屏幕时,导致整台手机发生旋转。

▲ 很好的镜头,使我的手机旋转

顶级硬件,但软件可以更好

实际上,今年的国产大折叠旗舰,基本上都已经做到了和 Magic V5 同等级的轻薄,零点几毫米和几克之差,对体验的影响微乎其微。

荣耀 Magic V5 的真正竞争力,是这一圈没有明显短板,甚至还是最顶配的配置。

荣耀 Magic V5 搭载的是一颗「满血版」的八核高通骁龙 8 Elite 处理器,截止目前也是唯一一台搭载这个处理器的大折叠手机。

实测《王者荣耀》压力不大,能稳定 120 帧,我们直接上《原神》。游戏模式下,30 分钟平均帧率能来到 59.8 帧,极少会出现波动,机身发热情况也比较理性。不过需要指出的是,用内屏玩《原神》,极高画质实际渲染像素点数相当于常规直板机的 720P。

荣耀 Magic V5 的发热情况和前代一样,主要集中在有摄像头模组和 USB-C 接口的那一面,因此横屏玩游戏时,可以握住外屏的一面,手指就不会感受到太多温度。

就性能方面,荣耀 Magic V5 绝对算得上今年目前的大折叠中的第一梯队。只是有点可惜的是,「唯一一台满血骁龙大折叠」这个地位只有一周的保质期,下周三星也将发布满血骁龙芯的大折叠旗舰。

不止性能表现,这颗硕大无比的镜头模组,也带来了大折叠中堪称优秀的影像素质。

70mm 的潜望长焦,配置相比上一代 90mm 略有缩水,但却是我最爱用的一颗镜头,在各种场景下都能稳定发挥,夜景表现也很优秀。

23mm 的主摄表现也让人满意,色彩还原相对真实,我也很推荐使用自带的「鲜明」和「质感」两种摄影风格,让成片颇具胶片质感,随手按下快门都能有不错的效果。

开启夜间模式后,荣耀 Magic V5 也能比较好地处理复杂的高光环境,但暗部的细节相对来说会差一些。

虽然影像能力不错,但代价就是这个非常不优雅的镜头模组,个人也感觉并没有比其他折叠屏手机的影像素质拉开明显差距。

硬件只是下限,软件有时候更能影响时间体验。先看看大折叠手机必备的多任务能力,Magic V5 这次主打「三分屏」,能够打开三个 20:9 的应用窗口,并能同时显示其中两个。

对比起 vivo 的「原子工作台」和 OPPO 的「全景虚拟屏」,荣耀的大折叠多任务方案还是稍显落后,并且使用过程中还出现过异常的卡顿,需要后续进一步优化。

但如果说到 AI 能力,那荣耀就是妥妥的第一梯队级别,内置的「YOYO 助手」已经具有一些 AI 智能体的能力。

其中比较惊艳我的流程是「打车」,只要跟 YOYO 确定好目的地,就能将手机放在一旁,等 YOYO 自己输入好地址信息然后叫车,用户也能手动接管选车型。

并且,在展开内屏之后,Magic V5 支持分屏显示 AI 助手和手头上的事情,比如看微信公众号时,就能同时看原文和 YOYO 的总结,是非常舒适的 AI 助手体验。

另一个我喜欢的功能是「YOYO 记忆」,能够将看到的内容进行转存,并通过 AI 生成摘要,简单来说就是一个跨所有平台的系统级 AI 收藏夹。

和其他家主要依靠截图再进行 AI 分析不同,YOYO 能够转存一整篇图文,方便日后离线翻看,就是排版不够美观,易读性还有提升空间,并且最新版本还出现了打开笔记闪退的问题,希望早日修复。

YOYO 记忆还能和第三方平台的「收藏」按钮联动,自动对用户进行收藏的内容进行 AI 记忆,就是目前支持的平台还比较少,我常用的图文平台和社交媒体只有小红书支持。

荣耀底层的智能场景化预判能力,也已经到了一种有点让我「毛骨悚然」地步:

当我快到地铁站时,YOYO 建议会自动提示快速微信地铁乘车码的快捷方式;我靠近家里的丰巢快递柜时,YOYO 也会及时送上相关的取件码信息。

除了 AI,「加入苹果生态」也是今年 Android 手机的一个主旋律,荣耀当然也不例外,不过目前主要只支持 iPhone 互传照片和文件,而  vivo 已经能连 Apple Watch。

只是苹替很多,但「鸿替」目前只有荣耀 Magic V5。只要打开荣耀分享和华为分享,荣耀 Magic V5 就能和 HarmonyOS 5 设备进行系统级互传,不需要提前装好额外的应用。

总体而言,我很愿意给 Magic OS 9 一个好评,但和这么顶级的硬件对比,又显得稍弱了。

堆料不能解决所有问题

从三星第一次向世人展示 Galaxy Fold 到现在,已经过去了六年的时间。

也就是说,折叠屏手机颇具未来感的「明日产品」,逐渐成为一种形态更成熟的大众消费品。

关于折叠屏手机,其实一直以来都有一个很尴尬的问题:展开后的大屏,其实只占消费者使用时间的 20%,但却要承受 50% 的溢价,并且还要牺牲手感、性能、影像这些属性。

不管是荣耀,还是 vivo 和 OPPO,今年发布的三款大折叠旗舰,机身也是相当极致的轻薄,几乎已经贴近到达 Type-C 接口,就是为了让折叠态的体验能够看齐直板手机。

当然,各家可以继续往零点几毫米压缩,继续攻克屏幕的平整度,抚平折痕,但很显然,这样迭代带来的收益,已经在逐渐递减,毕竟再薄,也得容下一个 USB-C 接口。

所以有的品牌选择在这个赛道上掉头,宁愿全面减配,但把价格打得更低,换取更多对折叠屏这种形态心痒痒的用户。

而荣耀 Magic V5 选择做「六边形战士」,进一步提升产品力,所有参数基本都给到最满,也薄到接近临界值,完全能称得上走到了折叠屏手机这个阶段下的终点。

只是有一个问题:售价 8999 元,并且来自荣耀。

本质上说,折叠屏手机是一种高品牌、高溢价、高技术的产品,三者缺一不可。

华为折叠屏手机的配置和形态不总是最顶尖的,但它依然是卖得最好的,而且要远远好于对手。

这也是为什么,苹果即将推出的折叠 iPhone 很有可能爆,并且还能拉起整个折叠屏品类的出货量,即使第一台折叠 iPhone 大概率落后行业两三代,并且还卖五位数。

折叠屏手机是一个工程能力先于产品定义的形态,是市场需求先于用户需求的产品。

堆料能解决问题,但堆料解决不了所有问题,荣耀做出了尝试,我也很期待市场会给出什么样的答案。

#欢迎关注爱范儿官方微信公众号:爱范儿(微信号:ifanr),更多精彩内容第一时间为您奉上。

爱范儿 | 原文链接 · 查看评论 · 新浪微博


❌