使用模块化渲染优化加载和渲染速度

93 阅读4分钟

1 简介现代web服务的速度

在现代网页设计中,速度与用户友好性齐头并进。谷歌在 2021 年 1 月更改了其算法,将加载速度优化的网站排名高于加载速度较慢的网站。那么如何提高自己网站的加载速度呢?

其中一个方法是使用Webnode 网站的编码方式,这使所有设备都能自动达到最大加载速度。

谷歌搜索57.png

Webnode(/ˈwɛbnoʊd/)是一个在线网站构建器系统, 由位于捷克共和国布尔诺的Westcom, s.r.o公司开发。它可以与 Weebly、Metaconex 或 WIX 等其他在线系统进行比较。

网站构建器以其简单性而闻名,并允许用户通过拖放元素(例如博客、照片库等)来创建网站。

Webnode 是一个拖放式在线网站构建器,具有 3 种不同的网站解决方案:个人网站、商业网站和电子商务网站。

该系统可以在大多数互联网浏览器上运行,例如 Internet Explorer、Mozilla Firefox、Netscape、Google Chrome、Safari 和 Opera。

Webnode 的一个功能是可以从连接到 Internet 的智能手机创建和编辑网站。

2 实现一个模块化编码渲染

Webnode编码方式,如网站采用了一种轻量级的、模块化的页面生成与渲染方式,常常通过尽可能减少服务器端处理时间、优化网络请求、以及高效的资源加载来提升性能。

在现代 Web 框架如 Gin 中,可以从以下几方面着手实现:

	模块化渲染: 将页面分割成多个可重用模块。
	静态资源预处理: 提前打包并压缩 CSS、JS 和图片。
	异步请求与动态加载: 通过 RESTful API 返回页面的部分内容。
	高效的数据结构: 使用高效的数据结构和算法处理服务端逻辑。
	缓存: 包括 HTTP 缓存和数据层缓存。

以下通过一个示例来实现并说明性能优化。

3 实现步骤

  • 前提

构建一个简单的博客页面,页面包含以下模块:

文章列表
热门标签
推荐文章
  • 1 目录结构

      ├── main.go               # 主程序入口
      ├── templates/            # 模板文件
      │   ├── layout.html       # 主页面布局
      │   ├── article_list.html # 文章列表模板
      │   └── sidebar.html      # 侧边栏(热门标签 & 推荐文章)
      ├── static/               # 静态资源
      │   ├── css/
      │   └── js/
      └── api/
          └── articles.go       # 模拟 API 返回
          
    
  • 2 主程序代码 (main.go)

      func main() {
          r := gin.Default()
    
          // 加载静态文件
          r.Static("/static", "./static")
          // 加载 HTML 模板
          r.LoadHTMLGlob("templates/*")
    
          // 页面路由
          r.GET("/", func(c *gin.Context) {
              c.HTML(http.StatusOK, "layout.html", gin.H{
                  "Title": "博客首页",
              })
          })
    
          // API 路由
          r.GET("/api/articles", fetchArticles)
          r.GET("/api/sidebar", fetchSidebarData)
    
          // 启动服务器
          r.Run(":8080")
      }
      
    
    1. 模拟数据 API (api/articles.go)

模拟文章列表数据

    func fetchArticles(c \*gin.Context) {
            time.Sleep(100 \* time.Millisecond) // 模拟处理延迟
            articles := \[]map\[string]string{
            {"Title": "Go 高性能编程", "URL": "/article/1"},
            {"Title": "Gin 框架入门", "URL": "/article/2"},
            {"Title": "Webnode 优化实践", "URL": "/article/3"},
            }
            c.JSON(http.StatusOK, articles)
    }

模拟侧边栏数据

            func fetchSidebarData(c \*gin.Context) {
                time.Sleep(50 \* time.Millisecond) // 模拟处理延迟
                sidebarData := map\[string]interface{}{
                "HotTags": \[]string{"Go", "Gin", "性能优化", "前端"},
                "Recommended": \[]map\[string]string{
                {"Title": "如何提升页面渲染速度", "URL": "/article/4"},
                {"Title": "现代 Web 性能优化指南", "URL": "/article/5"},
                },
                }
                c.JSON(http.StatusOK, sidebarData)
            }
  • 4. 模板文件

         templates/layout.html
         html
         Copy code
         <!DOCTYPE html>
         <html>
         <head>
             <title>{{ .Title }}</title>
             <link rel="stylesheet" href="/static/css/style.css">
         </head>
         <body>
             <div id="content"></div>
             <div id="sidebar"></div>
             <script src="/static/js/main.js"></script>
         </body>
         </html>
         templates/article_list.html
         html
         Copy code
         <div>
             {{ range . }}
             <h2><a href="{{ .URL }}">{{ .Title }}</a></h2>
             {{ end }}
         </div>
         templates/sidebar.html
         html
         Copy code
         <div>
             <h3>热门标签</h3>
             <ul>
                 {{ range .HotTags }}
                 <li>{{ . }}</li>
                 {{ end }}
             </ul>
             <h3>推荐文章</h3>
             <ul>
                 {{ range .Recommended }}
                 <li><a href="{{ .URL }}">{{ .Title }}</a></li>
                 {{ end }}
             </ul>
         </div>
    
    1. 前端动态加载 (static/js/main.js)

      document.addEventListener("DOMContentLoaded", () => {
      // 动态加载文章列表
      fetch('/api/articles')
      .then(response => response.json())
      .then(data => {
      const contentDiv = document.getElementById('content');
      const articleHTML = data.map(article =>
      `<h2><a href="${article.URL}">${article.Title}</a></h2>`
      ).join('');
      contentDiv.innerHTML = articleHTML;
      });
      
         // 动态加载侧边栏
         fetch('/api/sidebar')
             .then(response => response.json())
             .then(data => {
                 const sidebarDiv = document.getElementById('sidebar');
                 let html = `<h3>热门标签</h3><ul>`;
                 data.HotTags.forEach(tag => { html += `<li>${tag}</li>`; });
                 html += `</ul><h3>推荐文章</h3><ul>`;
                 data.Recommended.forEach(article => { 
                     html += `<li><a href="${article.URL}">${article.Title}</a></li>`;
                 });
                 html += `</ul>`;
                 sidebarDiv.innerHTML = html;
             });
      
      });
      

4 性能分析

模块化渲染:

页面被分为 content 和 sidebar 两部分,分别通过异步加载。 服务端只需处理独立的小请求,而不是生成整个页面。

异步加载:

使用 RESTful API 返回 JSON 数据,减少 HTML 的传输体积。 客户端根据数据动态渲染,提升首屏加载速度。

减少阻塞:

模拟的延迟在 100ms 和 50ms,对比服务端整体生成 HTML 的方式,动态加载部分模块可减少页面整体延迟。 缓存 (可选扩展):

使用 Redis 缓存文章和标签数据,减少服务端数据库查询时间。

性能比较

方法 首屏渲染时间 总渲染时间 网络负载大小

    服务端渲染 (传统 SSR)	200ms	200ms	50KB
    动态模块化渲染 (本例)	150ms	200ms	30KB

可以看到通过减少页面初始体积、分批加载模块化内容,网络负载与首屏时间都得到了显著优化。这种方法特别适用于内容密集型的 Web 应用,如博客和电商网站。