好久没更了,发生了比较多的事。首先是换了份工作,觉得之前的工作没什么意思,就主动辞职了,顺便休息一段时间。结果在gap的这段时间内,ai coding发展的特别迅速,前端开发变了天。前端岗位少了很多,agent开发岗位多了很多。但是我说白了,很多公司招agent开发的面试官,他自己懂个屁的agent。然后传统前端岗也是,有些面试官我真的怀疑他的水平,他说我说的回答不对,我确信我是对的,但是没招。
这就是ai冲击下的前端开发现状。没什么人研究技术了,以后懂技术的人越来越少,但是面试的时候会有一群技术不怎么样的人来问你技术,哈哈
怎么说呢,ai确实厉害,你说它对于一些原理啊,提升水平什么之类的,帮助有限,但是实际开发提效太降维打击了。而实际上对原理的理解,对真实水平的提升,除了自己,无人在意。只要你需求完成得快,那ai就是对的。所以确实是有点没心气了,心情好就写一写记录一下,心情不好的话还是好好活着更重要。
css和页面渲染
说回正题,好久没写了,第一篇还是写的简单一点,就聊聊八股里面经常提到的,css会阻塞页面渲染。
八股里面经常说,浏览器要渲染页面,把html标签解析成dom树,把css解析成cssom树,然后把两棵树合并成render树。而解析css会阻塞渲染,因为不知道样式就无法渲染。
通常情况下,放在 head 中的css会阻塞首次绘制,浏览器会等待它加载并解析完成。
如果css在body里面?
通常来讲,css都是放到head里的,便于浏览器更早的发现css并下载。
但是如果css放到了body的里面,那么浏览器可能会先把当前已经解析结束的内容,先做一次渲染。然后等css下载并解析完成后,再重新渲染一次。
我们可以自己写个demo来试验一下,用express起个简单的node server,写个html文件,css文件,然后让node server收到请求的时候返回相应的html或css。只不过返回css的时候,加上几秒钟的延迟,便于我们观察效果。
相关代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <!-- public/index.html -->
<!doctype html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>观察 3 秒后的样式加载</title> </head> <body> <main> <h1>等待 3 秒的 CSS</h1> <p>样式表引用位于第一张和第二张卡片之间,服务器延迟 3 秒返回 CSS。</p>
<section class="cards" aria-label="样式观察区"> <article class="card"> <h2>颜色</h2> <p>CSS 生效后,这张卡片会变成浅紫色,页面背景变为深色。</p> </article>
<link rel="stylesheet" href="/styles.css">
<article class="card"> <h2>布局</h2> <p>宽屏上,三张卡片会横向排列;窄屏上则纵向排列。</p> </article> <article class="card"> <h2>细节</h2> <p>观察字体大小、留白、圆角和阴影在样式生效后的变化。</p> </article> </section> </main>
</body> </html>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
:root { color-scheme: dark; font-family: system-ui, -apple-system, "Segoe UI", "Microsoft YaHei", sans-serif; background: #11151e; color: #eef1f8; line-height: 1.7; }
* { box-sizing: border-box; } body { margin: 0; } main { max-width: 1080px; margin: 0 auto; padding: 64px 24px; } h1 { font-size: clamp(36px, 6vw, 64px); line-height: 1.18; letter-spacing: -0.04em; margin: 20px 0; } h2 { margin: 10px 0; font-size: 23px; } .cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; margin: 36px 0; } .card { padding: 28px; border-radius: 20px; color: #242138; background: #d9ccff; box-shadow: 0 18px 35px #0003; } .card:nth-of-type(2) { background: #bcebdc; } .card:nth-of-type(3) { background: #ffd6ae; } .card p { margin-bottom: 0; }
@media (max-width: 720px) { main { padding: 36px 18px; } .cards { grid-template-columns: 1fr; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
const express = require('express'); const path = require('node:path'); const { setTimeout: delay } = require('node:timers/promises');
const app = express(); const port = Number(process.env.PORT || 3000);
app.use(async (request, response, next) => { response.set('Cache-Control', 'no-store'); if (request.path.endsWith('.css')) { await delay(3000); } next(); });
app.use(express.static(path.join(__dirname, 'public'), { cacheControl: false, etag: false, lastModified: false, }));
app.listen(port, '127.0.0.1', () => { console.log(`Open http://localhost:${port}`); });
|
当我们执行node server.js命令启动服务器,然后访问localhost:3000的时候,我们最先看到的是这样

而过了几秒后,页面变成了这样

以上是在chrome155中试验的结果。浏览器遇到 body 内的样式表后,会暂停后续 HTML 的解析,但允许前面已经构建的 DOM 被绘制。因此,CSS 加载前只有第一张卡片出现;加载完成后,解析继续,后两张卡片才出现,同时样式应用到整个页面。
这说明浏览器如果遇到了body里面的css,并不会傻等这个css下载并解析完成,所以人们常背的八股里css阻塞渲染,并不是绝对的,没有一直不渲染等你的义务,可以先把当前准备好的内容先渲染出来,这也是浏览器的增量解析的机制。这就是FOUC(无样式内容闪烁)现象,体验很差,所以我们应该避免把css写到body里面。
死背八股,死路一条。很多人痛恨八股,觉得死记硬背没有意义。但实际上八股里面的内容恰恰都很有用,只不过需要结合实际去理解。背而不懂,没有意义。