日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

我們一起聊聊如何通過流式渲染提升用戶體驗?

來源: 責編: 時間:2024-06-27 17:13:30 196觀看
導讀什么是流式渲染?流式渲染的核心理念是將 HTML 文檔分割成小塊(chunk),并逐步地發送給客戶端,而非等待整個頁面完整生成后再進行傳輸。這種方式能夠極大地提升用戶的初始加載體驗,特別是在網絡條件不佳或者頁面內容復雜的情

什么是流式渲染?

流式渲染的核心理念是將 HTML 文檔分割成小塊(chunk),并逐步地發送給客戶端,而非等待整個頁面完整生成后再進行傳輸。這種方式能夠極大地提升用戶的初始加載體驗,特別是在網絡條件不佳或者頁面內容復雜的情況下。MjB28資訊網——每日最新資訊28at.com

流式渲染并非新興技術,早在 90 年代,網頁瀏覽器就已開始運用這種模式來處理 HTML 文檔。不過,在 SPA(單頁應用)大行其道的時期,由于其核心在于客戶端動態渲染內容,流式渲染未能引起廣泛關注。然而,現今隨著服務端渲染技術的日臻成熟,流式渲染已成為顯著優化首屏加載性能的有力手段。MjB28資訊網——每日最新資訊28at.com

Node.js 實現簡單流式渲染

HTTP 是 Node.js 中的一等公民,其在設計時就充分考慮了流式傳輸和低延遲特性。這使得 Node.js 極為適合作為 Web 庫或框架的構建基礎。 ———— Node.js 官網MjB28資訊網——每日最新資訊28at.com

Node.js 從設計之初就將流式傳輸數據納入考量,以下是一個簡單的示例代碼:MjB28資訊網——每日最新資訊28at.com

const Koa = require('koa');const app = new Koa();// 假設數據需要 5 秒的時間來獲取renderAsyncString = async () => {  return new Promise((resolve, reject) => {    setTimeout(() => {      resolve('<h1>Hello World</h1>');    }, 5000);  })}app.use(async (ctx, next) => {  ctx.type = 'html';  ctx.body = await renderAsyncString();  await next();});app.listen(3000, () => {  console.log('App is listening on port 3000');});

這是一個簡化的業務場景,運行之后,會出現長達 5 秒的白屏,然后才顯示出"Hello World"這段文字。MjB28資訊網——每日最新資訊28at.com

毫無疑問,沒有用戶會愿意忍受一個長達 5 秒的白屏網頁!在 web.dev[1] 對于 TTFB(Time To First Byte,首字節時間)的介紹中提到,加載第一個字節的時間應當控制在 800ms 以內,才能稱得上是優質的 Web 網站服務。MjB28資訊網——每日最新資訊28at.com

為了改善這種情況,我們可以借助流式渲染技術。比如,先向用戶呈現一個加載中的提示或者骨架屏,以此來優化用戶體驗。下面是改進后的代碼:MjB28資訊網——每日最新資訊28at.com

const Koa = require('koa');const app = new Koa();const Stream = require('stream');// 假設數據需要 5 秒的時間來獲取renderAsyncString = async () => {  return new Promise((resolve, reject) => {    setTimeout(() => {      resolve('<h1>Hello World</h1>');    }, 5000);  })}app.use(async (ctx, next) => {  const rs = new Stream.Readable();  rs._read = () => {};  ctx.type = 'html';  rs.push('<h1>loading...</h1>');  ctx.body = rs;  renderAsyncString().then((string) => {    rs.push(`<script>      document.querySelector('h1').innerHTML = '${string}';    </script>`);  })});app.listen(3000, () => {  console.log('App is listening on port 3000');});

采用流式渲染后,頁面最初會顯示"loading...",然后在 5 秒后更新為"Hello World"。MjB28資訊網——每日最新資訊28at.com

需要特別注意的是,Safari 瀏覽器對于何時觸發流式傳輸可能存在一些限制(以下內容未找到官方說明,而是通過實踐總結得出):MjB28資訊網——每日最新資訊28at.com

  • 傳輸的 chunk 大小需大于 512 字節。若小于此值,可能無法有效觸發流式傳輸,影響用戶體驗。
  • 傳輸的內容必須能夠在屏幕上實際渲染。例如,傳輸<div style="display:none;">...</div>這樣隱藏的內容可能是無效的,無法實現流式渲染的預期效果。

聲明式 Shadow DOM,不依賴 javascript 實現

在上述的代碼中,我們運用了一定的 JavaScript 代碼。本質上,我們需要預先渲染一部分 HTML 標簽作為占位,隨后再用新的 HTML 標簽對其進行替換。使用 JavaScript 來實現這一過程相對容易,但如果禁用了 JavaScript 呢?MjB28資訊網——每日最新資訊28at.com

這就可能需要借助一些 Shadow DOM[2] 的技巧!眾多組件化設計的前端框架都包含了 slot(插槽)的概念,在 Shadow DOM 中也提供了 slot 標簽,其可用于創建可插入的 Web Components。在 Chrome 111 及以上版本中,我們能夠使用聲明式 Shadow DOM,無需依賴 JavaScript,在服務器端就能實現 shadow DOM 的功能。以下是一個聲明式 Shadow DOM 的示例:MjB28資訊網——每日最新資訊28at.com

<template shadowrootmode="open">      <header>Header</header>      <main>        <slot name="hole"></slot>      </main>      <footer>Footer</footer>    </template>      <div slot="hole">插入一段文字!</div>

從中可以清晰地看到,我們的文字成功插入到了 slot 標簽之中。利用聲明式 Shadow DOM,我們能夠對之前的示例進行改寫:MjB28資訊網——每日最新資訊28at.com

const Koa = require('koa');const app = new Koa();const Stream = require('stream');// 假設數據需要 5 秒的時間來獲取renderAsyncString = async () => {  return new Promise((resolve, reject) => {    setTimeout(() => {      resolve('<h1>Hello World</h1>');    }, 5000);  })}app.use(async (ctx, next) => {  const rs = new Stream.Readable();  rs._read = () => {};  ctx.type = 'html';  rs.push(`  <template shadowrootmode="open">    <slot name="hole"><h1>loading</h1></slot>  </template>  `);  ctx.body = rs;  renderAsyncString().then((string) => {    rs.push(`<h1 slot="hole">${string}</h1>`);    rs.push(null);  })});app.listen(3000, () => {  console.log('App is listening on port 3000');});

運行這段改寫后的代碼,其結果與之前完全相同。更為重要的是,即便我們禁用了瀏覽器的 JavaScript,代碼依然能夠正常運行!MjB28資訊網——每日最新資訊28at.com

聲明式 Shadow DOM 是一個相對較新的特性,您可以在這篇文檔[3]中獲取更多詳細信息。MjB28資訊網——每日最新資訊28at.com

react 實現流式渲染

現在讓我們轉換視角,來看看 React 框架中的流式渲染。自 React 18 版本之后,在框架層面上開始支持流式渲染。下面是使用 nextjs 對之前的示例進行改寫的代碼:MjB28資訊網——每日最新資訊28at.com

import { Suspense } from 'eact'const renderAsyncString = async () => {  return new Promise((resolve, reject) => {    setTimeout(() => {      resolve('Hello World!');    }, 5000);  })}async function Main() {  const string = await renderAsyncString();  return <h1>{string}</h1>}export default async function App() {  return (    <Suspense fallback={<h1>loading...</h1>} >      <Main />    </Suspense>  )}

運行這段代碼,其效果與之前的示例完全一致,并且同樣無需運行任何客戶端的 JavaScript 代碼。MjB28資訊網——每日最新資訊28at.com

關于 React 的流式渲染,您可以在官方的技術層面[4]解釋中獲取更深入的信息。在本文中,僅作為對流式渲染的概要介紹,不對其進行更為細致的講解。MjB28資訊網——每日最新資訊28at.com

總結

本文從理論層面深入探討了流式渲染的相關實現方案。理論上,流式渲染的概念和實現相對簡單。HTTP 標準和 Node.js 早在很久以前就對這一特性提供了支持。然而,在實際的工程應用中,流式渲染并非易事。以 React 為例,要實現流式渲染,不僅需要 React 自身作為用戶界面(UI)框架提供支持,還需要借助像 nextjs 這樣的元框架(meta framework)來賦予服務端相應的能力。MjB28資訊網——每日最新資訊28at.com

本文鏈接:http://m.www897cc.com/showinfo-26-96975-0.html我們一起聊聊如何通過流式渲染提升用戶體驗?

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 面試官:Transient關鍵字修飾的變量當真不可序列化?

下一篇: 純 CSS 檢測滾動的速度和方向

標簽:
  • 熱門焦點
Top 日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不
在线观看欧美| 欧美一区二区视频在线观看2020 | 欧美日韩1区2区3区| 欧美韩日一区二区| 欧美三级视频| 国产亚洲日本欧美韩国| 在线免费高清一区二区三区| 亚洲精品国产精品国产自| 一区二区三区精品国产| 欧美在线一区二区| 欧美黄污视频| 国产精品亚洲综合| 香蕉国产精品偷在线观看不卡| 激情欧美一区二区三区| 一区二区免费在线播放| 欧美精品免费播放| 91久久精品国产91久久性色| 久久精品国亚洲| 亚洲第一黄色网| 欧美久久久久免费| 伊人婷婷欧美激情| 欧美激情一区二区三区蜜桃视频 | 欧美网站在线| 欧美日韩午夜在线| 亚洲一区二区成人在线观看| 欧美激情五月| 在线视频你懂得一区| 欧美日韩中文字幕精品| 一区二区三区鲁丝不卡| 国产精品网站在线播放| 韩国一区二区三区在线观看 | 欧美日韩国产区| 亚洲激情在线播放| 亚洲欧美日韩精品久久奇米色影视| 欧美成人免费小视频| 亚洲日本中文| 国产欧美日韩视频一区二区三区 | 另类亚洲自拍| 亚洲香蕉在线观看| 麻豆91精品| 亚洲精品视频一区| 亚洲视频视频在线| 国产精品久久久久久久久搜平片| 久久国产综合精品| av成人免费在线观看| 亚洲福利视频一区二区| 亚洲国产成人高清精品| 国产亚洲视频在线| 欧美吻胸吃奶大尺度电影| 欧美日韩精品久久久| 精品动漫av| 羞羞色国产精品| 欧美日韩在线观看一区二区三区| 在线色欧美三级视频| 午夜免费电影一区在线观看| 欧美日韩在线亚洲一区蜜芽| 亚洲狠狠婷婷| 老鸭窝毛片一区二区三区| 国产精品亚洲网站| 亚洲五月婷婷| 欧美色精品天天在线观看视频| 91久久精品国产91久久性色| 久久天堂国产精品| 国内精品免费在线观看| 欧美一级片一区| 国产精品一区二区黑丝| 亚洲欧美日韩国产一区二区三区| 欧美视频在线观看免费网址| 日韩视频一区二区在线观看| 欧美激情亚洲综合一区| 亚洲欧洲在线免费| 欧美成人乱码一区二区三区| 亚洲观看高清完整版在线观看| 久久人人爽人人爽爽久久| 红桃视频欧美| 久久久水蜜桃| 激情亚洲网站| 久热精品视频在线| 亚洲国产视频一区| 欧美激情第六页| 99综合精品| 欧美日韩在线免费| 亚洲一区3d动漫同人无遮挡| 国产精品yjizz| 亚洲综合电影一区二区三区| 国产精品国产三级国产专播精品人| 中文一区字幕| 国产精品入口| 欧美在线视频免费观看| 国内精品亚洲| 免费成人av在线| 91久久精品日日躁夜夜躁欧美| 欧美成人精品在线| 国产精品久久久久久久久久妞妞| av成人毛片| 久久综合中文字幕| 在线不卡中文字幕| 农村妇女精品| 亚洲激情黄色| 欧美精品综合| 一区二区黄色| 国产精品免费一区二区三区观看| 亚洲综合精品| 国产亚洲激情视频在线| 久久久久高清| 亚洲国产日韩一级| 黑人巨大精品欧美一区二区| 久久九九99| 亚洲国产精品嫩草影院| 欧美精品三级在线观看| 亚洲午夜国产成人av电影男同| 国产精品久久久久久模特| 午夜精品久久久| 国产精品亚洲综合| 久久美女性网| 亚洲精品国产精品乱码不99| 欧美日韩免费| 亚洲欧洲av一区二区三区久久| 国产无遮挡一区二区三区毛片日本| 久久亚洲春色中文字幕| 亚洲麻豆av| 国产乱码精品一区二区三区五月婷 | 久久亚洲精选| 亚洲精品一二三区| 国产精品人成在线观看免费| 久久久久成人精品免费播放动漫| 亚洲国产天堂久久综合网| 国产精品s色| 久久久天天操| 妖精成人www高清在线观看| 国产九区一区在线| 欧美高清日韩| 午夜精品国产更新| 最新国产乱人伦偷精品免费网站| 国产精品日本| 欧美jizzhd精品欧美巨大免费| 亚洲深夜福利网站| 一区二区三区在线免费视频| 欧美色图首页| 久久综合九色综合欧美就去吻| 亚洲视屏在线播放| 亚洲第一色在线| 国产精品一区久久| 欧美精品一区在线| 久久精品一区蜜桃臀影院| 99视频日韩| 在线观看福利一区| 国产精品系列在线| 欧美人成免费网站| 久久久久久久久久久成人| 亚洲图片在区色| 亚洲高清不卡一区| 国产性色一区二区| 国产精品v欧美精品∨日韩| 麻豆精品在线视频| 欧美在线黄色| 一区二区三区成人精品| 亚洲第一福利社区| 国产人妖伪娘一区91| 欧美日韩亚洲视频一区| 鲁大师成人一区二区三区| 欧美一区亚洲一区| 亚洲午夜久久久久久尤物| 亚洲经典三级| 一区在线电影| 国产一区二区精品| 国产精品日韩在线| 欧美久久婷婷综合色| 老司机精品视频一区二区三区| 欧美一区二区三区男人的天堂 | 久久久久久久久蜜桃| 亚洲欧美日韩在线高清直播| 久久久久高清| 最新高清无码专区| 国产视频一区二区在线观看| 欧美日韩性视频在线| 美女网站久久| 久久久久国产一区二区三区| 亚洲欧美日韩国产中文在线| 99精品视频一区二区三区| 亚洲欧洲在线免费| 亚洲高清久久久| 黄色日韩在线| 国产一区二区日韩精品| 国产美女精品视频免费观看| 国产精品久久午夜| 欧美婷婷久久| 欧美日韩在线播放三区| 欧美激情在线观看| 欧美va天堂在线| 麻豆国产精品一区二区三区| 久久精品一二三区| 久久久久久色| 久久久久在线观看| 久久久精品日韩| 久久久国产视频91| 久久久久国产精品一区二区| 久久九九国产| 久久久久免费| 久久久久在线观看| 裸体女人亚洲精品一区| 快播亚洲色图| 麻豆成人综合网| 欧美.www|